annotate DEPENDENCIES/generic/include/boost/property_tree/detail/ptree_implementation.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // ----------------------------------------------------------------------------
Chris@16 2 // Copyright (C) 2002-2006 Marcin Kalicinski
Chris@16 3 // Copyright (C) 2009 Sebastian Redl
Chris@16 4 //
Chris@16 5 // Distributed under the Boost Software License, Version 1.0.
Chris@16 6 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 //
Chris@16 9 // For more information, see www.boost.org
Chris@16 10 // ----------------------------------------------------------------------------
Chris@16 11 #ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
Chris@16 12 #define BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
Chris@16 13
Chris@16 14 #include <boost/iterator/iterator_adaptor.hpp>
Chris@16 15 #include <boost/iterator/reverse_iterator.hpp>
Chris@16 16 #include <boost/assert.hpp>
Chris@16 17 #include <boost/utility/swap.hpp>
Chris@16 18 #include <memory>
Chris@16 19
Chris@16 20 #if (defined(BOOST_MSVC) && \
Chris@16 21 (_MSC_FULL_VER >= 160000000 && _MSC_FULL_VER < 170000000)) || \
Chris@16 22 (defined(BOOST_INTEL_WIN) && \
Chris@16 23 defined(BOOST_DINKUMWARE_STDLIB))
Chris@16 24 #define BOOST_PROPERTY_TREE_PAIR_BUG
Chris@16 25 #endif
Chris@16 26
Chris@16 27 namespace boost { namespace property_tree
Chris@16 28 {
Chris@16 29 template <class K, class D, class C>
Chris@16 30 struct basic_ptree<K, D, C>::subs
Chris@16 31 {
Chris@16 32 struct by_name {};
Chris@16 33 // The actual child container.
Chris@16 34 #if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
Chris@16 35 // MSVC 10 has moved std::pair's members to a base
Chris@16 36 // class. Unfortunately this does break the interface.
Chris@16 37 BOOST_STATIC_CONSTANT(unsigned,
Chris@16 38 first_offset = offsetof(value_type, first));
Chris@16 39 #endif
Chris@16 40 typedef multi_index_container<value_type,
Chris@16 41 multi_index::indexed_by<
Chris@16 42 multi_index::sequenced<>,
Chris@16 43 multi_index::ordered_non_unique<multi_index::tag<by_name>,
Chris@16 44 #if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
Chris@16 45 multi_index::member_offset<value_type, const key_type,
Chris@16 46 first_offset>,
Chris@16 47 #else
Chris@16 48 multi_index::member<value_type, const key_type,
Chris@16 49 &value_type::first>,
Chris@16 50 #endif
Chris@16 51 key_compare
Chris@16 52 >
Chris@16 53 >
Chris@16 54 > base_container;
Chris@16 55
Chris@16 56 // The by-name lookup index.
Chris@16 57 typedef typename base_container::template index<by_name>::type
Chris@16 58 by_name_index;
Chris@16 59
Chris@16 60 // Access functions for getting to the children of a tree.
Chris@16 61 static base_container& ch(self_type *s) {
Chris@16 62 return *static_cast<base_container*>(s->m_children);
Chris@16 63 }
Chris@16 64 static const base_container& ch(const self_type *s) {
Chris@16 65 return *static_cast<const base_container*>(s->m_children);
Chris@16 66 }
Chris@16 67 static by_name_index& assoc(self_type *s) {
Chris@16 68 return ch(s).BOOST_NESTED_TEMPLATE get<by_name>();
Chris@16 69 }
Chris@16 70 static const by_name_index& assoc(const self_type *s) {
Chris@16 71 return ch(s).BOOST_NESTED_TEMPLATE get<by_name>();
Chris@16 72 }
Chris@16 73 };
Chris@16 74 template <class K, class D, class C>
Chris@16 75 class basic_ptree<K, D, C>::iterator : public boost::iterator_adaptor<
Chris@16 76 iterator, typename subs::base_container::iterator, value_type>
Chris@16 77 {
Chris@16 78 friend class boost::iterator_core_access;
Chris@16 79 typedef boost::iterator_adaptor<
Chris@16 80 iterator, typename subs::base_container::iterator, value_type>
Chris@16 81 baset;
Chris@16 82 public:
Chris@16 83 typedef typename baset::reference reference;
Chris@16 84 iterator() {}
Chris@16 85 explicit iterator(typename iterator::base_type b)
Chris@16 86 : iterator::iterator_adaptor_(b)
Chris@16 87 {}
Chris@16 88 reference dereference() const
Chris@16 89 {
Chris@16 90 // multi_index doesn't allow modification of its values, because
Chris@16 91 // indexes could sort by anything, and modification screws that up.
Chris@16 92 // However, we only sort by the key, and it's protected against
Chris@16 93 // modification in the value_type, so this const_cast is safe.
Chris@16 94 return const_cast<reference>(*this->base_reference());
Chris@16 95 }
Chris@16 96 };
Chris@16 97 template <class K, class D, class C>
Chris@16 98 class basic_ptree<K, D, C>::const_iterator : public boost::iterator_adaptor<
Chris@16 99 const_iterator, typename subs::base_container::const_iterator>
Chris@16 100 {
Chris@16 101 public:
Chris@16 102 const_iterator() {}
Chris@16 103 explicit const_iterator(typename const_iterator::base_type b)
Chris@16 104 : const_iterator::iterator_adaptor_(b)
Chris@16 105 {}
Chris@16 106 const_iterator(iterator b)
Chris@16 107 : const_iterator::iterator_adaptor_(b.base())
Chris@16 108 {}
Chris@16 109 };
Chris@16 110 template <class K, class D, class C>
Chris@16 111 class basic_ptree<K, D, C>::reverse_iterator
Chris@16 112 : public boost::reverse_iterator<iterator>
Chris@16 113 {
Chris@16 114 public:
Chris@16 115 reverse_iterator() {}
Chris@16 116 explicit reverse_iterator(iterator b)
Chris@16 117 : boost::reverse_iterator<iterator>(b)
Chris@16 118 {}
Chris@16 119 };
Chris@16 120 template <class K, class D, class C>
Chris@16 121 class basic_ptree<K, D, C>::const_reverse_iterator
Chris@16 122 : public boost::reverse_iterator<const_iterator>
Chris@16 123 {
Chris@16 124 public:
Chris@16 125 const_reverse_iterator() {}
Chris@16 126 explicit const_reverse_iterator(const_iterator b)
Chris@16 127 : boost::reverse_iterator<const_iterator>(b)
Chris@16 128 {}
Chris@16 129 const_reverse_iterator(
Chris@16 130 typename basic_ptree<K, D, C>::reverse_iterator b)
Chris@16 131 : boost::reverse_iterator<const_iterator>(b)
Chris@16 132 {}
Chris@16 133 };
Chris@16 134 template <class K, class D, class C>
Chris@16 135 class basic_ptree<K, D, C>::assoc_iterator
Chris@16 136 : public boost::iterator_adaptor<assoc_iterator,
Chris@16 137 typename subs::by_name_index::iterator,
Chris@16 138 value_type>
Chris@16 139 {
Chris@16 140 friend class boost::iterator_core_access;
Chris@16 141 typedef boost::iterator_adaptor<assoc_iterator,
Chris@16 142 typename subs::by_name_index::iterator,
Chris@16 143 value_type>
Chris@16 144 baset;
Chris@16 145 public:
Chris@16 146 typedef typename baset::reference reference;
Chris@16 147 assoc_iterator() {}
Chris@16 148 explicit assoc_iterator(typename assoc_iterator::base_type b)
Chris@16 149 : assoc_iterator::iterator_adaptor_(b)
Chris@16 150 {}
Chris@16 151 reference dereference() const
Chris@16 152 {
Chris@16 153 return const_cast<reference>(*this->base_reference());
Chris@16 154 }
Chris@16 155 };
Chris@16 156 template <class K, class D, class C>
Chris@16 157 class basic_ptree<K, D, C>::const_assoc_iterator
Chris@16 158 : public boost::iterator_adaptor<const_assoc_iterator,
Chris@16 159 typename subs::by_name_index::const_iterator>
Chris@16 160 {
Chris@16 161 public:
Chris@16 162 const_assoc_iterator() {}
Chris@16 163 explicit const_assoc_iterator(
Chris@16 164 typename const_assoc_iterator::base_type b)
Chris@16 165 : const_assoc_iterator::iterator_adaptor_(b)
Chris@16 166 {}
Chris@16 167 const_assoc_iterator(assoc_iterator b)
Chris@16 168 : const_assoc_iterator::iterator_adaptor_(b.base())
Chris@16 169 {}
Chris@16 170 };
Chris@16 171
Chris@16 172
Chris@16 173 // Big five
Chris@16 174
Chris@16 175 // Perhaps the children collection could be created on-demand only, to
Chris@16 176 // reduce heap traffic. But that's a lot more work to implement.
Chris@16 177
Chris@16 178 template<class K, class D, class C> inline
Chris@16 179 basic_ptree<K, D, C>::basic_ptree()
Chris@16 180 : m_children(new typename subs::base_container)
Chris@16 181 {
Chris@16 182 }
Chris@16 183
Chris@16 184 template<class K, class D, class C> inline
Chris@16 185 basic_ptree<K, D, C>::basic_ptree(const data_type &d)
Chris@16 186 : m_data(d), m_children(new typename subs::base_container)
Chris@16 187 {
Chris@16 188 }
Chris@16 189
Chris@16 190 template<class K, class D, class C> inline
Chris@16 191 basic_ptree<K, D, C>::basic_ptree(const basic_ptree<K, D, C> &rhs)
Chris@16 192 : m_data(rhs.m_data),
Chris@16 193 m_children(new typename subs::base_container(subs::ch(&rhs)))
Chris@16 194 {
Chris@16 195 }
Chris@16 196
Chris@16 197 template<class K, class D, class C>
Chris@16 198 basic_ptree<K, D, C> &
Chris@16 199 basic_ptree<K, D, C>::operator =(const basic_ptree<K, D, C> &rhs)
Chris@16 200 {
Chris@16 201 self_type(rhs).swap(*this);
Chris@16 202 return *this;
Chris@16 203 }
Chris@16 204
Chris@16 205 template<class K, class D, class C>
Chris@16 206 basic_ptree<K, D, C>::~basic_ptree()
Chris@16 207 {
Chris@16 208 delete &subs::ch(this);
Chris@16 209 }
Chris@16 210
Chris@16 211 template<class K, class D, class C> inline
Chris@16 212 void basic_ptree<K, D, C>::swap(basic_ptree<K, D, C> &rhs)
Chris@16 213 {
Chris@16 214 boost::swap(m_data, rhs.m_data);
Chris@16 215 // Void pointers, no ADL necessary
Chris@16 216 std::swap(m_children, rhs.m_children);
Chris@16 217 }
Chris@16 218
Chris@16 219 // Container view
Chris@16 220
Chris@16 221 template<class K, class D, class C> inline
Chris@16 222 typename basic_ptree<K, D, C>::size_type
Chris@16 223 basic_ptree<K, D, C>::size() const
Chris@16 224 {
Chris@16 225 return subs::ch(this).size();
Chris@16 226 }
Chris@16 227
Chris@16 228 template<class K, class D, class C> inline
Chris@16 229 typename basic_ptree<K, D, C>::size_type
Chris@16 230 basic_ptree<K, D, C>::max_size() const
Chris@16 231 {
Chris@16 232 return subs::ch(this).max_size();
Chris@16 233 }
Chris@16 234
Chris@16 235 template<class K, class D, class C> inline
Chris@16 236 bool basic_ptree<K, D, C>::empty() const
Chris@16 237 {
Chris@16 238 return subs::ch(this).empty();
Chris@16 239 }
Chris@16 240
Chris@16 241 template<class K, class D, class C> inline
Chris@16 242 typename basic_ptree<K, D, C>::iterator
Chris@16 243 basic_ptree<K, D, C>::begin()
Chris@16 244 {
Chris@16 245 return iterator(subs::ch(this).begin());
Chris@16 246 }
Chris@16 247
Chris@16 248 template<class K, class D, class C> inline
Chris@16 249 typename basic_ptree<K, D, C>::const_iterator
Chris@16 250 basic_ptree<K, D, C>::begin() const
Chris@16 251 {
Chris@16 252 return const_iterator(subs::ch(this).begin());
Chris@16 253 }
Chris@16 254
Chris@16 255 template<class K, class D, class C> inline
Chris@16 256 typename basic_ptree<K, D, C>::iterator
Chris@16 257 basic_ptree<K, D, C>::end()
Chris@16 258 {
Chris@16 259 return iterator(subs::ch(this).end());
Chris@16 260 }
Chris@16 261
Chris@16 262 template<class K, class D, class C> inline
Chris@16 263 typename basic_ptree<K, D, C>::const_iterator
Chris@16 264 basic_ptree<K, D, C>::end() const
Chris@16 265 {
Chris@16 266 return const_iterator(subs::ch(this).end());
Chris@16 267 }
Chris@16 268
Chris@16 269 template<class K, class D, class C> inline
Chris@16 270 typename basic_ptree<K, D, C>::reverse_iterator
Chris@16 271 basic_ptree<K, D, C>::rbegin()
Chris@16 272 {
Chris@16 273 return reverse_iterator(this->end());
Chris@16 274 }
Chris@16 275
Chris@16 276 template<class K, class D, class C> inline
Chris@16 277 typename basic_ptree<K, D, C>::const_reverse_iterator
Chris@16 278 basic_ptree<K, D, C>::rbegin() const
Chris@16 279 {
Chris@16 280 return const_reverse_iterator(this->end());
Chris@16 281 }
Chris@16 282
Chris@16 283 template<class K, class D, class C> inline
Chris@16 284 typename basic_ptree<K, D, C>::reverse_iterator
Chris@16 285 basic_ptree<K, D, C>::rend()
Chris@16 286 {
Chris@16 287 return reverse_iterator(this->begin());
Chris@16 288 }
Chris@16 289
Chris@16 290 template<class K, class D, class C> inline
Chris@16 291 typename basic_ptree<K, D, C>::const_reverse_iterator
Chris@16 292 basic_ptree<K, D, C>::rend() const
Chris@16 293 {
Chris@16 294 return const_reverse_iterator(this->begin());
Chris@16 295 }
Chris@16 296
Chris@16 297 template<class K, class D, class C> inline
Chris@16 298 typename basic_ptree<K, D, C>::value_type &
Chris@16 299 basic_ptree<K, D, C>::front()
Chris@16 300 {
Chris@16 301 return const_cast<value_type&>(subs::ch(this).front());
Chris@16 302 }
Chris@16 303
Chris@16 304 template<class K, class D, class C> inline
Chris@16 305 const typename basic_ptree<K, D, C>::value_type &
Chris@16 306 basic_ptree<K, D, C>::front() const
Chris@16 307 {
Chris@16 308 return subs::ch(this).front();
Chris@16 309 }
Chris@16 310
Chris@16 311 template<class K, class D, class C> inline
Chris@16 312 typename basic_ptree<K, D, C>::value_type &
Chris@16 313 basic_ptree<K, D, C>::back()
Chris@16 314 {
Chris@16 315 return const_cast<value_type&>(subs::ch(this).back());
Chris@16 316 }
Chris@16 317
Chris@16 318 template<class K, class D, class C> inline
Chris@16 319 const typename basic_ptree<K, D, C>::value_type &
Chris@16 320 basic_ptree<K, D, C>::back() const
Chris@16 321 {
Chris@16 322 return subs::ch(this).back();
Chris@16 323 }
Chris@16 324
Chris@16 325 template<class K, class D, class C> inline
Chris@16 326 typename basic_ptree<K, D, C>::iterator
Chris@16 327 basic_ptree<K, D, C>::insert(iterator where, const value_type &value)
Chris@16 328 {
Chris@16 329 return iterator(subs::ch(this).insert(where.base(), value).first);
Chris@16 330 }
Chris@16 331
Chris@16 332 template<class K, class D, class C>
Chris@16 333 template<class It> inline
Chris@16 334 void basic_ptree<K, D, C>::insert(iterator where, It first, It last)
Chris@16 335 {
Chris@16 336 subs::ch(this).insert(where.base(), first, last);
Chris@16 337 }
Chris@16 338
Chris@16 339 template<class K, class D, class C> inline
Chris@16 340 typename basic_ptree<K, D, C>::iterator
Chris@16 341 basic_ptree<K, D, C>::erase(iterator where)
Chris@16 342 {
Chris@16 343 return iterator(subs::ch(this).erase(where.base()));
Chris@16 344 }
Chris@16 345
Chris@16 346 template<class K, class D, class C> inline
Chris@16 347 typename basic_ptree<K, D, C>::iterator
Chris@16 348 basic_ptree<K, D, C>::erase(iterator first, iterator last)
Chris@16 349 {
Chris@16 350 return iterator(subs::ch(this).erase(first.base(), last.base()));
Chris@16 351 }
Chris@16 352
Chris@16 353 template<class K, class D, class C> inline
Chris@16 354 typename basic_ptree<K, D, C>::iterator
Chris@16 355 basic_ptree<K, D, C>::push_front(const value_type &value)
Chris@16 356 {
Chris@16 357 return iterator(subs::ch(this).push_front(value).first);
Chris@16 358 }
Chris@16 359
Chris@16 360 template<class K, class D, class C> inline
Chris@16 361 typename basic_ptree<K, D, C>::iterator
Chris@16 362 basic_ptree<K, D, C>::push_back(const value_type &value)
Chris@16 363 {
Chris@16 364 return iterator(subs::ch(this).push_back(value).first);
Chris@16 365 }
Chris@16 366
Chris@16 367 template<class K, class D, class C> inline
Chris@16 368 void basic_ptree<K, D, C>::pop_front()
Chris@16 369 {
Chris@16 370 subs::ch(this).pop_front();
Chris@16 371 }
Chris@16 372
Chris@16 373 template<class K, class D, class C> inline
Chris@16 374 void basic_ptree<K, D, C>::pop_back()
Chris@16 375 {
Chris@16 376 subs::ch(this).pop_back();
Chris@16 377 }
Chris@16 378
Chris@16 379 template<class K, class D, class C> inline
Chris@16 380 void basic_ptree<K, D, C>::reverse()
Chris@16 381 {
Chris@16 382 subs::ch(this).reverse();
Chris@16 383 }
Chris@16 384
Chris@16 385 namespace impl
Chris@16 386 {
Chris@16 387 struct by_first
Chris@16 388 {
Chris@16 389 template <typename P>
Chris@16 390 bool operator ()(const P& lhs, const P& rhs) const {
Chris@16 391 return lhs.first < rhs.first;
Chris@16 392 }
Chris@16 393 };
Chris@101 394
Chris@101 395 template <typename C>
Chris@101 396 struct equal_pred
Chris@101 397 {
Chris@101 398 template <typename P>
Chris@101 399 bool operator ()(const P& lhs, const P& rhs) const {
Chris@101 400 C c;
Chris@101 401 return !c(lhs.first, rhs.first) &&
Chris@101 402 !c(rhs.first, lhs.first) &&
Chris@101 403 lhs.second == rhs.second;
Chris@101 404 }
Chris@101 405 };
Chris@101 406
Chris@101 407 template <typename C, typename MI>
Chris@101 408 bool equal_children(const MI& ch1, const MI& ch2) {
Chris@101 409 // Assumes ch1.size() == ch2.size()
Chris@101 410 return std::equal(ch1.begin(), ch1.end(),
Chris@101 411 ch2.begin(), equal_pred<C>());
Chris@101 412 }
Chris@16 413 }
Chris@16 414
Chris@16 415 template<class K, class D, class C> inline
Chris@16 416 void basic_ptree<K, D, C>::sort()
Chris@16 417 {
Chris@16 418 sort(impl::by_first());
Chris@16 419 }
Chris@16 420
Chris@16 421 template<class K, class D, class C>
Chris@16 422 template<class Compare> inline
Chris@16 423 void basic_ptree<K, D, C>::sort(Compare comp)
Chris@16 424 {
Chris@16 425 subs::ch(this).sort(comp);
Chris@16 426 }
Chris@16 427
Chris@16 428 // Equality
Chris@16 429
Chris@16 430 template<class K, class D, class C> inline
Chris@16 431 bool basic_ptree<K, D, C>::operator ==(
Chris@16 432 const basic_ptree<K, D, C> &rhs) const
Chris@16 433 {
Chris@16 434 // The size test is cheap, so add it as an optimization
Chris@16 435 return size() == rhs.size() && data() == rhs.data() &&
Chris@101 436 impl::equal_children<C>(subs::ch(this), subs::ch(&rhs));
Chris@16 437 }
Chris@16 438
Chris@16 439 template<class K, class D, class C> inline
Chris@16 440 bool basic_ptree<K, D, C>::operator !=(
Chris@16 441 const basic_ptree<K, D, C> &rhs) const
Chris@16 442 {
Chris@16 443 return !(*this == rhs);
Chris@16 444 }
Chris@16 445
Chris@16 446 // Associative view
Chris@16 447
Chris@16 448 template<class K, class D, class C> inline
Chris@16 449 typename basic_ptree<K, D, C>::assoc_iterator
Chris@16 450 basic_ptree<K, D, C>::ordered_begin()
Chris@16 451 {
Chris@16 452 return assoc_iterator(subs::assoc(this).begin());
Chris@16 453 }
Chris@16 454
Chris@16 455 template<class K, class D, class C> inline
Chris@16 456 typename basic_ptree<K, D, C>::const_assoc_iterator
Chris@16 457 basic_ptree<K, D, C>::ordered_begin() const
Chris@16 458 {
Chris@16 459 return const_assoc_iterator(subs::assoc(this).begin());
Chris@16 460 }
Chris@16 461
Chris@16 462 template<class K, class D, class C> inline
Chris@16 463 typename basic_ptree<K, D, C>::assoc_iterator
Chris@16 464 basic_ptree<K, D, C>::not_found()
Chris@16 465 {
Chris@16 466 return assoc_iterator(subs::assoc(this).end());
Chris@16 467 }
Chris@16 468
Chris@16 469 template<class K, class D, class C> inline
Chris@16 470 typename basic_ptree<K, D, C>::const_assoc_iterator
Chris@16 471 basic_ptree<K, D, C>::not_found() const
Chris@16 472 {
Chris@16 473 return const_assoc_iterator(subs::assoc(this).end());
Chris@16 474 }
Chris@16 475
Chris@16 476 template<class K, class D, class C> inline
Chris@16 477 typename basic_ptree<K, D, C>::assoc_iterator
Chris@16 478 basic_ptree<K, D, C>::find(const key_type &key)
Chris@16 479 {
Chris@16 480 return assoc_iterator(subs::assoc(this).find(key));
Chris@16 481 }
Chris@16 482
Chris@16 483 template<class K, class D, class C> inline
Chris@16 484 typename basic_ptree<K, D, C>::const_assoc_iterator
Chris@16 485 basic_ptree<K, D, C>::find(const key_type &key) const
Chris@16 486 {
Chris@16 487 return const_assoc_iterator(subs::assoc(this).find(key));
Chris@16 488 }
Chris@16 489
Chris@16 490 template<class K, class D, class C> inline
Chris@16 491 std::pair<
Chris@16 492 typename basic_ptree<K, D, C>::assoc_iterator,
Chris@16 493 typename basic_ptree<K, D, C>::assoc_iterator
Chris@16 494 > basic_ptree<K, D, C>::equal_range(const key_type &key)
Chris@16 495 {
Chris@16 496 std::pair<typename subs::by_name_index::iterator,
Chris@16 497 typename subs::by_name_index::iterator> r(
Chris@16 498 subs::assoc(this).equal_range(key));
Chris@16 499 return std::pair<assoc_iterator, assoc_iterator>(
Chris@16 500 assoc_iterator(r.first), assoc_iterator(r.second));
Chris@16 501 }
Chris@16 502
Chris@16 503 template<class K, class D, class C> inline
Chris@16 504 std::pair<
Chris@16 505 typename basic_ptree<K, D, C>::const_assoc_iterator,
Chris@16 506 typename basic_ptree<K, D, C>::const_assoc_iterator
Chris@16 507 > basic_ptree<K, D, C>::equal_range(const key_type &key) const
Chris@16 508 {
Chris@16 509 std::pair<typename subs::by_name_index::const_iterator,
Chris@16 510 typename subs::by_name_index::const_iterator> r(
Chris@16 511 subs::assoc(this).equal_range(key));
Chris@16 512 return std::pair<const_assoc_iterator, const_assoc_iterator>(
Chris@16 513 const_assoc_iterator(r.first), const_assoc_iterator(r.second));
Chris@16 514 }
Chris@16 515
Chris@16 516 template<class K, class D, class C> inline
Chris@16 517 typename basic_ptree<K, D, C>::size_type
Chris@16 518 basic_ptree<K, D, C>::count(const key_type &key) const
Chris@16 519 {
Chris@16 520 return subs::assoc(this).count(key);
Chris@16 521 }
Chris@16 522
Chris@16 523 template<class K, class D, class C> inline
Chris@16 524 typename basic_ptree<K, D, C>::size_type
Chris@16 525 basic_ptree<K, D, C>::erase(const key_type &key)
Chris@16 526 {
Chris@16 527 return subs::assoc(this).erase(key);
Chris@16 528 }
Chris@16 529
Chris@16 530 template<class K, class D, class C> inline
Chris@16 531 typename basic_ptree<K, D, C>::iterator
Chris@16 532 basic_ptree<K, D, C>::to_iterator(assoc_iterator ai)
Chris@16 533 {
Chris@16 534 return iterator(subs::ch(this).
Chris@16 535 BOOST_NESTED_TEMPLATE project<0>(ai.base()));
Chris@16 536 }
Chris@16 537
Chris@16 538 template<class K, class D, class C> inline
Chris@16 539 typename basic_ptree<K, D, C>::const_iterator
Chris@16 540 basic_ptree<K, D, C>::to_iterator(const_assoc_iterator ai) const
Chris@16 541 {
Chris@16 542 return const_iterator(subs::ch(this).
Chris@16 543 BOOST_NESTED_TEMPLATE project<0>(ai.base()));
Chris@16 544 }
Chris@16 545
Chris@16 546 // Property tree view
Chris@16 547
Chris@16 548 template<class K, class D, class C> inline
Chris@16 549 typename basic_ptree<K, D, C>::data_type &
Chris@16 550 basic_ptree<K, D, C>::data()
Chris@16 551 {
Chris@16 552 return m_data;
Chris@16 553 }
Chris@16 554
Chris@16 555 template<class K, class D, class C> inline
Chris@16 556 const typename basic_ptree<K, D, C>::data_type &
Chris@16 557 basic_ptree<K, D, C>::data() const
Chris@16 558 {
Chris@16 559 return m_data;
Chris@16 560 }
Chris@16 561
Chris@16 562 template<class K, class D, class C> inline
Chris@16 563 void basic_ptree<K, D, C>::clear()
Chris@16 564 {
Chris@16 565 m_data = data_type();
Chris@16 566 subs::ch(this).clear();
Chris@16 567 }
Chris@16 568
Chris@16 569 template<class K, class D, class C>
Chris@16 570 basic_ptree<K, D, C> &
Chris@16 571 basic_ptree<K, D, C>::get_child(const path_type &path)
Chris@16 572 {
Chris@16 573 path_type p(path);
Chris@16 574 self_type *n = walk_path(p);
Chris@16 575 if (!n) {
Chris@16 576 BOOST_PROPERTY_TREE_THROW(ptree_bad_path("No such node", path));
Chris@16 577 }
Chris@16 578 return *n;
Chris@16 579 }
Chris@16 580
Chris@16 581 template<class K, class D, class C> inline
Chris@16 582 const basic_ptree<K, D, C> &
Chris@16 583 basic_ptree<K, D, C>::get_child(const path_type &path) const
Chris@16 584 {
Chris@16 585 return const_cast<self_type*>(this)->get_child(path);
Chris@16 586 }
Chris@16 587
Chris@16 588 template<class K, class D, class C> inline
Chris@16 589 basic_ptree<K, D, C> &
Chris@16 590 basic_ptree<K, D, C>::get_child(const path_type &path,
Chris@16 591 self_type &default_value)
Chris@16 592 {
Chris@16 593 path_type p(path);
Chris@16 594 self_type *n = walk_path(p);
Chris@16 595 return n ? *n : default_value;
Chris@16 596 }
Chris@16 597
Chris@16 598 template<class K, class D, class C> inline
Chris@16 599 const basic_ptree<K, D, C> &
Chris@16 600 basic_ptree<K, D, C>::get_child(const path_type &path,
Chris@16 601 const self_type &default_value) const
Chris@16 602 {
Chris@16 603 return const_cast<self_type*>(this)->get_child(path,
Chris@16 604 const_cast<self_type&>(default_value));
Chris@16 605 }
Chris@16 606
Chris@16 607
Chris@16 608 template<class K, class D, class C>
Chris@16 609 optional<basic_ptree<K, D, C> &>
Chris@16 610 basic_ptree<K, D, C>::get_child_optional(const path_type &path)
Chris@16 611 {
Chris@16 612 path_type p(path);
Chris@16 613 self_type *n = walk_path(p);
Chris@16 614 if (!n) {
Chris@16 615 return optional<self_type&>();
Chris@16 616 }
Chris@16 617 return *n;
Chris@16 618 }
Chris@16 619
Chris@16 620 template<class K, class D, class C>
Chris@16 621 optional<const basic_ptree<K, D, C> &>
Chris@16 622 basic_ptree<K, D, C>::get_child_optional(const path_type &path) const
Chris@16 623 {
Chris@16 624 path_type p(path);
Chris@16 625 self_type *n = walk_path(p);
Chris@16 626 if (!n) {
Chris@16 627 return optional<const self_type&>();
Chris@16 628 }
Chris@16 629 return *n;
Chris@16 630 }
Chris@16 631
Chris@16 632 template<class K, class D, class C>
Chris@16 633 basic_ptree<K, D, C> &
Chris@16 634 basic_ptree<K, D, C>::put_child(const path_type &path,
Chris@16 635 const self_type &value)
Chris@16 636 {
Chris@16 637 path_type p(path);
Chris@16 638 self_type &parent = force_path(p);
Chris@16 639 // Got the parent. Now get the correct child.
Chris@16 640 key_type fragment = p.reduce();
Chris@16 641 assoc_iterator el = parent.find(fragment);
Chris@16 642 // If the new child exists, replace it.
Chris@16 643 if(el != parent.not_found()) {
Chris@16 644 return el->second = value;
Chris@16 645 } else {
Chris@16 646 return parent.push_back(value_type(fragment, value))->second;
Chris@16 647 }
Chris@16 648 }
Chris@16 649
Chris@16 650 template<class K, class D, class C>
Chris@16 651 basic_ptree<K, D, C> &
Chris@16 652 basic_ptree<K, D, C>::add_child(const path_type &path,
Chris@16 653 const self_type &value)
Chris@16 654 {
Chris@16 655 path_type p(path);
Chris@16 656 self_type &parent = force_path(p);
Chris@16 657 // Got the parent.
Chris@16 658 key_type fragment = p.reduce();
Chris@16 659 return parent.push_back(value_type(fragment, value))->second;
Chris@16 660 }
Chris@16 661
Chris@16 662 template<class K, class D, class C>
Chris@16 663 template<class Type, class Translator>
Chris@16 664 typename boost::enable_if<detail::is_translator<Translator>, Type>::type
Chris@16 665 basic_ptree<K, D, C>::get_value(Translator tr) const
Chris@16 666 {
Chris@16 667 if(boost::optional<Type> o = get_value_optional<Type>(tr)) {
Chris@16 668 return *o;
Chris@16 669 }
Chris@16 670 BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
Chris@16 671 std::string("conversion of data to type \"") +
Chris@16 672 typeid(Type).name() + "\" failed", data()));
Chris@16 673 }
Chris@16 674
Chris@16 675 template<class K, class D, class C>
Chris@16 676 template<class Type> inline
Chris@16 677 Type basic_ptree<K, D, C>::get_value() const
Chris@16 678 {
Chris@16 679 return get_value<Type>(
Chris@16 680 typename translator_between<data_type, Type>::type());
Chris@16 681 }
Chris@16 682
Chris@16 683 template<class K, class D, class C>
Chris@16 684 template<class Type, class Translator> inline
Chris@16 685 Type basic_ptree<K, D, C>::get_value(const Type &default_value,
Chris@16 686 Translator tr) const
Chris@16 687 {
Chris@16 688 return get_value_optional<Type>(tr).get_value_or(default_value);
Chris@16 689 }
Chris@16 690
Chris@16 691 template<class K, class D, class C>
Chris@16 692 template <class Ch, class Translator>
Chris@16 693 typename boost::enable_if<
Chris@16 694 detail::is_character<Ch>,
Chris@16 695 std::basic_string<Ch>
Chris@16 696 >::type
Chris@16 697 basic_ptree<K, D, C>::get_value(const Ch *default_value, Translator tr)const
Chris@16 698 {
Chris@16 699 return get_value<std::basic_string<Ch>, Translator>(default_value, tr);
Chris@16 700 }
Chris@16 701
Chris@16 702 template<class K, class D, class C>
Chris@16 703 template<class Type> inline
Chris@16 704 typename boost::disable_if<detail::is_translator<Type>, Type>::type
Chris@16 705 basic_ptree<K, D, C>::get_value(const Type &default_value) const
Chris@16 706 {
Chris@16 707 return get_value(default_value,
Chris@16 708 typename translator_between<data_type, Type>::type());
Chris@16 709 }
Chris@16 710
Chris@16 711 template<class K, class D, class C>
Chris@16 712 template <class Ch>
Chris@16 713 typename boost::enable_if<
Chris@16 714 detail::is_character<Ch>,
Chris@16 715 std::basic_string<Ch>
Chris@16 716 >::type
Chris@16 717 basic_ptree<K, D, C>::get_value(const Ch *default_value) const
Chris@16 718 {
Chris@16 719 return get_value< std::basic_string<Ch> >(default_value);
Chris@16 720 }
Chris@16 721
Chris@16 722 template<class K, class D, class C>
Chris@16 723 template<class Type, class Translator> inline
Chris@16 724 optional<Type> basic_ptree<K, D, C>::get_value_optional(
Chris@16 725 Translator tr) const
Chris@16 726 {
Chris@16 727 return tr.get_value(data());
Chris@16 728 }
Chris@16 729
Chris@16 730 template<class K, class D, class C>
Chris@16 731 template<class Type> inline
Chris@16 732 optional<Type> basic_ptree<K, D, C>::get_value_optional() const
Chris@16 733 {
Chris@16 734 return get_value_optional<Type>(
Chris@16 735 typename translator_between<data_type, Type>::type());
Chris@16 736 }
Chris@16 737
Chris@16 738 template<class K, class D, class C>
Chris@16 739 template<class Type, class Translator> inline
Chris@16 740 typename boost::enable_if<detail::is_translator<Translator>, Type>::type
Chris@16 741 basic_ptree<K, D, C>::get(const path_type &path,
Chris@16 742 Translator tr) const
Chris@16 743 {
Chris@16 744 return get_child(path).BOOST_NESTED_TEMPLATE get_value<Type>(tr);
Chris@16 745 }
Chris@16 746
Chris@16 747 template<class K, class D, class C>
Chris@16 748 template<class Type> inline
Chris@16 749 Type basic_ptree<K, D, C>::get(const path_type &path) const
Chris@16 750 {
Chris@16 751 return get_child(path).BOOST_NESTED_TEMPLATE get_value<Type>();
Chris@16 752 }
Chris@16 753
Chris@16 754 template<class K, class D, class C>
Chris@16 755 template<class Type, class Translator> inline
Chris@16 756 Type basic_ptree<K, D, C>::get(const path_type &path,
Chris@16 757 const Type &default_value,
Chris@16 758 Translator tr) const
Chris@16 759 {
Chris@16 760 return get_optional<Type>(path, tr).get_value_or(default_value);
Chris@16 761 }
Chris@16 762
Chris@16 763 template<class K, class D, class C>
Chris@16 764 template <class Ch, class Translator>
Chris@16 765 typename boost::enable_if<
Chris@16 766 detail::is_character<Ch>,
Chris@16 767 std::basic_string<Ch>
Chris@16 768 >::type
Chris@16 769 basic_ptree<K, D, C>::get(
Chris@16 770 const path_type &path, const Ch *default_value, Translator tr) const
Chris@16 771 {
Chris@16 772 return get<std::basic_string<Ch>, Translator>(path, default_value, tr);
Chris@16 773 }
Chris@16 774
Chris@16 775 template<class K, class D, class C>
Chris@16 776 template<class Type> inline
Chris@16 777 typename boost::disable_if<detail::is_translator<Type>, Type>::type
Chris@16 778 basic_ptree<K, D, C>::get(const path_type &path,
Chris@16 779 const Type &default_value) const
Chris@16 780 {
Chris@16 781 return get_optional<Type>(path).get_value_or(default_value);
Chris@16 782 }
Chris@16 783
Chris@16 784 template<class K, class D, class C>
Chris@16 785 template <class Ch>
Chris@16 786 typename boost::enable_if<
Chris@16 787 detail::is_character<Ch>,
Chris@16 788 std::basic_string<Ch>
Chris@16 789 >::type
Chris@16 790 basic_ptree<K, D, C>::get(
Chris@16 791 const path_type &path, const Ch *default_value) const
Chris@16 792 {
Chris@16 793 return get< std::basic_string<Ch> >(path, default_value);
Chris@16 794 }
Chris@16 795
Chris@16 796 template<class K, class D, class C>
Chris@16 797 template<class Type, class Translator>
Chris@16 798 optional<Type> basic_ptree<K, D, C>::get_optional(const path_type &path,
Chris@16 799 Translator tr) const
Chris@16 800 {
Chris@16 801 if (optional<const self_type&> child = get_child_optional(path))
Chris@16 802 return child.get().
Chris@16 803 BOOST_NESTED_TEMPLATE get_value_optional<Type>(tr);
Chris@16 804 else
Chris@16 805 return optional<Type>();
Chris@16 806 }
Chris@16 807
Chris@16 808 template<class K, class D, class C>
Chris@16 809 template<class Type>
Chris@16 810 optional<Type> basic_ptree<K, D, C>::get_optional(
Chris@16 811 const path_type &path) const
Chris@16 812 {
Chris@16 813 if (optional<const self_type&> child = get_child_optional(path))
Chris@16 814 return child.get().BOOST_NESTED_TEMPLATE get_value_optional<Type>();
Chris@16 815 else
Chris@16 816 return optional<Type>();
Chris@16 817 }
Chris@16 818
Chris@16 819 template<class K, class D, class C>
Chris@16 820 template<class Type, class Translator>
Chris@16 821 void basic_ptree<K, D, C>::put_value(const Type &value, Translator tr)
Chris@16 822 {
Chris@16 823 if(optional<data_type> o = tr.put_value(value)) {
Chris@16 824 data() = *o;
Chris@16 825 } else {
Chris@16 826 BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
Chris@16 827 std::string("conversion of type \"") + typeid(Type).name() +
Chris@16 828 "\" to data failed", boost::any()));
Chris@16 829 }
Chris@16 830 }
Chris@16 831
Chris@16 832 template<class K, class D, class C>
Chris@16 833 template<class Type> inline
Chris@16 834 void basic_ptree<K, D, C>::put_value(const Type &value)
Chris@16 835 {
Chris@16 836 put_value(value, typename translator_between<data_type, Type>::type());
Chris@16 837 }
Chris@16 838
Chris@16 839 template<class K, class D, class C>
Chris@16 840 template<class Type, typename Translator>
Chris@16 841 basic_ptree<K, D, C> & basic_ptree<K, D, C>::put(
Chris@16 842 const path_type &path, const Type &value, Translator tr)
Chris@16 843 {
Chris@16 844 if(optional<self_type &> child = get_child_optional(path)) {
Chris@16 845 child.get().put_value(value, tr);
Chris@16 846 return *child;
Chris@16 847 } else {
Chris@16 848 self_type &child2 = put_child(path, self_type());
Chris@16 849 child2.put_value(value, tr);
Chris@16 850 return child2;
Chris@16 851 }
Chris@16 852 }
Chris@16 853
Chris@16 854 template<class K, class D, class C>
Chris@16 855 template<class Type> inline
Chris@16 856 basic_ptree<K, D, C> & basic_ptree<K, D, C>::put(
Chris@16 857 const path_type &path, const Type &value)
Chris@16 858 {
Chris@16 859 return put(path, value,
Chris@16 860 typename translator_between<data_type, Type>::type());
Chris@16 861 }
Chris@16 862
Chris@16 863 template<class K, class D, class C>
Chris@16 864 template<class Type, typename Translator> inline
Chris@16 865 basic_ptree<K, D, C> & basic_ptree<K, D, C>::add(
Chris@16 866 const path_type &path, const Type &value, Translator tr)
Chris@16 867 {
Chris@16 868 self_type &child = add_child(path, self_type());
Chris@16 869 child.put_value(value, tr);
Chris@16 870 return child;
Chris@16 871 }
Chris@16 872
Chris@16 873 template<class K, class D, class C>
Chris@16 874 template<class Type> inline
Chris@16 875 basic_ptree<K, D, C> & basic_ptree<K, D, C>::add(
Chris@16 876 const path_type &path, const Type &value)
Chris@16 877 {
Chris@16 878 return add(path, value,
Chris@16 879 typename translator_between<data_type, Type>::type());
Chris@16 880 }
Chris@16 881
Chris@16 882
Chris@16 883 template<class K, class D, class C>
Chris@16 884 basic_ptree<K, D, C> *
Chris@16 885 basic_ptree<K, D, C>::walk_path(path_type &p) const
Chris@16 886 {
Chris@16 887 if(p.empty()) {
Chris@16 888 // I'm the child we're looking for.
Chris@16 889 return const_cast<basic_ptree*>(this);
Chris@16 890 }
Chris@16 891 // Recurse down the tree to find the path.
Chris@16 892 key_type fragment = p.reduce();
Chris@16 893 const_assoc_iterator el = find(fragment);
Chris@16 894 if(el == not_found()) {
Chris@16 895 // No such child.
Chris@16 896 return 0;
Chris@16 897 }
Chris@16 898 // Not done yet, recurse.
Chris@16 899 return el->second.walk_path(p);
Chris@16 900 }
Chris@16 901
Chris@16 902 template<class K, class D, class C>
Chris@16 903 basic_ptree<K, D, C> & basic_ptree<K, D, C>::force_path(path_type &p)
Chris@16 904 {
Chris@16 905 BOOST_ASSERT(!p.empty() && "Empty path not allowed for put_child.");
Chris@16 906 if(p.single()) {
Chris@16 907 // I'm the parent we're looking for.
Chris@16 908 return *this;
Chris@16 909 }
Chris@16 910 key_type fragment = p.reduce();
Chris@16 911 assoc_iterator el = find(fragment);
Chris@16 912 // If we've found an existing child, go down that path. Else
Chris@16 913 // create a new one.
Chris@16 914 self_type& child = el == not_found() ?
Chris@16 915 push_back(value_type(fragment, self_type()))->second : el->second;
Chris@16 916 return child.force_path(p);
Chris@16 917 }
Chris@16 918
Chris@16 919 // Free functions
Chris@16 920
Chris@16 921 template<class K, class D, class C>
Chris@16 922 inline void swap(basic_ptree<K, D, C> &pt1, basic_ptree<K, D, C> &pt2)
Chris@16 923 {
Chris@16 924 pt1.swap(pt2);
Chris@16 925 }
Chris@16 926
Chris@16 927 } }
Chris@16 928
Chris@16 929 #if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
Chris@16 930 #undef BOOST_PROPERTY_TREE_PAIR_BUG
Chris@16 931 #endif
Chris@16 932
Chris@16 933 #endif