Warning, file /include/boost/parser/detail/text/trie_map.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006 #ifndef BOOST_PARSER_DETAIL_TEXT_TRIE_MAP_HPP
0007 #define BOOST_PARSER_DETAIL_TEXT_TRIE_MAP_HPP
0008
0009 #include <boost/parser/detail/text/trie.hpp>
0010
0011 #include <boost/parser/detail/stl_interfaces/reverse_iterator.hpp>
0012
0013
0014 namespace boost::parser::detail { namespace text {
0015
0016 template<typename Key, typename Value>
0017 struct trie_map_iterator;
0018
0019 template<typename Key, typename Value>
0020 struct const_trie_map_iterator;
0021
0022 template<typename Key, typename Value>
0023 using reverse_trie_map_iterator =
0024 stl_interfaces::reverse_iterator<trie_map_iterator<Key, Value>>;
0025
0026 template<typename Key, typename Value>
0027 using const_reverse_trie_map_iterator =
0028 stl_interfaces::reverse_iterator<const_trie_map_iterator<Key, Value>>;
0029
0030
0031
0032 template<typename Iter>
0033 struct trie_range
0034 {
0035 using iterator = Iter;
0036
0037 iterator first;
0038 iterator last;
0039
0040 iterator begin() const { return first; }
0041 iterator end() const { return last; }
0042
0043 friend bool operator==(trie_range const & lhs, trie_range const & rhs)
0044 {
0045 return lhs.first == rhs.first && lhs.last == rhs.last;
0046 }
0047 friend bool operator!=(trie_range const & lhs, trie_range const & rhs)
0048 {
0049 return !(lhs == rhs);
0050 }
0051 };
0052
0053
0054
0055 template<typename Iter>
0056 struct const_trie_range
0057 {
0058 using const_iterator = Iter;
0059
0060 const_iterator first;
0061 const_iterator last;
0062
0063 const_iterator begin() const { return first; }
0064 const_iterator end() const { return last; }
0065
0066 friend bool
0067 operator==(const_trie_range const & lhs, const_trie_range const & rhs)
0068 {
0069 return lhs.first == rhs.first && lhs.last == rhs.last;
0070 }
0071 friend bool
0072 operator!=(const_trie_range const & lhs, const_trie_range const & rhs)
0073 {
0074 return !(lhs == rhs);
0075 }
0076 };
0077
0078
0079 template<typename Iter>
0080 struct trie_insert_result
0081 {
0082 using iterator = Iter;
0083
0084 trie_insert_result() : iter(), inserted(false) {}
0085 trie_insert_result(iterator it, bool ins) : iter(it), inserted(ins) {}
0086
0087 iterator iter;
0088 bool inserted;
0089
0090 friend bool operator==(
0091 trie_insert_result const & lhs, trie_insert_result const & rhs)
0092 {
0093 return lhs.iter == rhs.iter && lhs.inserted == rhs.inserted;
0094 }
0095 friend bool operator!=(
0096 trie_insert_result const & lhs, trie_insert_result const & rhs)
0097 {
0098 return !(lhs == rhs);
0099 }
0100 };
0101
0102 namespace detail {
0103
0104 struct index_within_parent_t
0105 {
0106 index_within_parent_t() : value_(-1) {}
0107
0108 std::size_t value() const { return value_; }
0109
0110 template<
0111 typename Key,
0112 typename Value,
0113 typename Iter,
0114 std::size_t KeySize>
0115 void insert_at(
0116 std::unique_ptr<trie_node_t<
0117 index_within_parent_t,
0118 Key,
0119 Value,
0120 KeySize>> const & child,
0121 std::ptrdiff_t offset,
0122 Iter it,
0123 Iter end)
0124 {
0125 child->index_within_parent_.value_ = offset;
0126 for (; it != end; ++it) {
0127 ++(*it)->index_within_parent_.value_;
0128 }
0129 }
0130
0131 template<typename Key, typename Value, std::size_t KeySize>
0132 void insert_ptr(std::unique_ptr<trie_node_t<
0133 index_within_parent_t,
0134 Key,
0135 Value,
0136 KeySize>> const & child)
0137 {
0138 child->index_within_parent_.value_ = 0;
0139 }
0140
0141 template<typename Iter>
0142 void erase(Iter it, Iter end)
0143 {
0144 for (; it != end; ++it) {
0145 --(*it)->index_within_parent_.value_;
0146 }
0147 }
0148
0149 private:
0150 std::size_t value_;
0151 };
0152
0153 template<typename Key, typename Value, std::size_t KeySize = 0>
0154 struct trie_iterator_state_t
0155 {
0156 trie_node_t<index_within_parent_t, Key, Value, KeySize> const *
0157 parent_;
0158 std::size_t index_;
0159 };
0160
0161 template<typename Key, typename Value, std::size_t KeySize>
0162 trie_iterator_state_t<Key, Value, KeySize>
0163 parent_state(trie_iterator_state_t<Key, Value, KeySize> state)
0164 {
0165 return {state.parent_->parent(),
0166 state.parent_->index_within_parent()};
0167 }
0168
0169 template<typename Key, typename Value, std::size_t KeySize>
0170 Key reconstruct_key(trie_iterator_state_t<Key, Value, KeySize> state)
0171 {
0172 Key retval;
0173 while (state.parent_->parent()) {
0174 retval.insert(retval.end(), state.parent_->key(state.index_));
0175 state = parent_state(state);
0176 }
0177 std::reverse(retval.begin(), retval.end());
0178 return retval;
0179 }
0180
0181 template<typename Key, typename Value, std::size_t KeySize>
0182 trie_node_t<index_within_parent_t, Key, Value, KeySize> const *
0183 to_node(trie_iterator_state_t<Key, Value, KeySize> state)
0184 {
0185 if (state.index_ < state.parent_->size())
0186 return state.parent_->child(state.index_);
0187 return nullptr;
0188 }
0189 }
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209 template<typename Key, typename Value, typename Compare>
0210 struct trie_map
0211 {
0212 private:
0213 using node_t =
0214 detail::trie_node_t<detail::index_within_parent_t, Key, Value>;
0215 using iter_state_t = detail::trie_iterator_state_t<Key, Value>;
0216
0217 public:
0218 using key_type = Key;
0219 using mapped_type = Value;
0220 using value_type = trie_element<Key, Value>;
0221 using key_compare = Compare;
0222 using key_element_type = typename Key::value_type;
0223
0224 using reference = value_type &;
0225 using const_reference = value_type const &;
0226 using iterator = trie_map_iterator<key_type, mapped_type>;
0227 using const_iterator = const_trie_map_iterator<key_type, mapped_type>;
0228 using reverse_iterator =
0229 reverse_trie_map_iterator<key_type, mapped_type>;
0230 using const_reverse_iterator =
0231 const_reverse_trie_map_iterator<key_type, mapped_type>;
0232 using size_type = std::ptrdiff_t;
0233 using difference_type = std::ptrdiff_t;
0234
0235 using range = trie_range<iterator>;
0236 using const_range = const_trie_range<const_iterator>;
0237 using insert_result = trie_insert_result<iterator>;
0238 using match_result = trie_match_result;
0239
0240 trie_map() : size_(0) {}
0241
0242 trie_map(Compare const & comp) : size_(0), comp_(comp) {}
0243
0244 template<typename Iter, typename Sentinel>
0245 trie_map(Iter first, Sentinel last, Compare const & comp = Compare()) :
0246 size_(0),
0247 comp_(comp)
0248 {
0249 insert(first, last);
0250 }
0251 template<typename Range>
0252 explicit trie_map(Range r, Compare const & comp = Compare()) :
0253 size_(0),
0254 comp_(comp)
0255 {
0256 insert(detail::begin(r), detail::end(r));
0257 }
0258 template<std::size_t KeySize>
0259 explicit trie_map(
0260 parser::detail::text::trie<Key, Value, Compare, KeySize> const &
0261 trie) :
0262 size_(0)
0263 {
0264 Key key;
0265 from_trie_impl(trie.header_, key);
0266 }
0267 trie_map(std::initializer_list<value_type> il) : size_(0)
0268 {
0269 insert(il);
0270 }
0271
0272 trie_map & operator=(std::initializer_list<value_type> il)
0273 {
0274 clear();
0275 for (auto const & x : il) {
0276 insert(x);
0277 }
0278 return *this;
0279 }
0280
0281 bool empty() const { return size_ == 0; }
0282 size_type size() const { return size_; }
0283 size_type max_size() const { return PTRDIFF_MAX; }
0284
0285 const_iterator begin() const
0286 {
0287 iter_state_t state{&header_, 0};
0288 if (size_) {
0289 while (!state.parent_->min_value()) {
0290 state.parent_ = state.parent_->min_child();
0291 }
0292 }
0293 return const_iterator(state);
0294 }
0295 const_iterator end() const
0296 {
0297 iter_state_t state{&header_, 0};
0298 if (size_) {
0299 node_t const * node = nullptr;
0300 while ((node = to_node(state))) {
0301 state.parent_ = node;
0302 state.index_ = state.parent_->size() - 1;
0303 }
0304 state.parent_ = state.parent_->parent();
0305 state.index_ = state.parent_->size();
0306 }
0307 return const_iterator(state);
0308 }
0309 const_iterator cbegin() const { return begin(); }
0310 const_iterator cend() const { return end(); }
0311
0312 const_reverse_iterator rbegin() const
0313 {
0314 return const_reverse_iterator{end()};
0315 }
0316 const_reverse_iterator rend() const
0317 {
0318 return const_reverse_iterator{begin()};
0319 }
0320 const_reverse_iterator crbegin() const { return rbegin(); }
0321 const_reverse_iterator crend() const { return rend(); }
0322
0323 #ifndef BOOST_PARSER_DOXYGEN
0324
0325 #define BOOST_TRIE_MAP_C_STR_OVERLOAD(rtype, func) \
0326 template<typename Char, std::size_t N> \
0327 rtype func(Char const(&chars)[N]) \
0328 { \
0329 static_assert( \
0330 std::is_same<Char, key_element_type>::value, \
0331 "Only well-formed when Char is Key::value_type."); \
0332 return func(detail::char_range<Char const>{chars, chars + N - 1}); \
0333 }
0334
0335 #define BOOST_TRIE_MAP_C_STR_OVERLOAD_QUALS(rtype, func, quals) \
0336 template<typename Char, std::size_t N> \
0337 rtype func(Char const(&chars)[N]) quals \
0338 { \
0339 static_assert( \
0340 std::is_same<Char, key_element_type>::value, \
0341 "Only well-formed when Char is Key::value_type."); \
0342 return func(detail::char_range<Char const>{chars, chars + N - 1}); \
0343 }
0344
0345 #endif
0346
0347
0348 template<typename KeyRange>
0349 bool contains(KeyRange const & key) const
0350 {
0351 return find(key) != end();
0352 }
0353
0354 #ifndef BOOST_PARSER_DOXYGEN
0355 BOOST_TRIE_MAP_C_STR_OVERLOAD_QUALS(bool, contains, const)
0356 #endif
0357
0358
0359
0360
0361 template<typename KeyRange>
0362 const_iterator find(KeyRange const & key) const
0363 {
0364 auto first = detail::begin(key);
0365 auto const last = detail::end(key);
0366 auto match = longest_match_impl(first, last);
0367 if (first == last && match.match) {
0368 return const_iterator(iter_state_t{
0369 to_node_ptr(match.node)->parent(),
0370 to_node_ptr(match.node)->index_within_parent()});
0371 }
0372 return this->end();
0373 }
0374
0375 #ifndef BOOST_PARSER_DOXYGEN
0376 BOOST_TRIE_MAP_C_STR_OVERLOAD_QUALS(const_iterator, find, const)
0377 #endif
0378
0379
0380
0381
0382 template<typename KeyRange>
0383 const_iterator lower_bound(KeyRange const & key) const
0384 {
0385 return bound_impl<true>(key);
0386 }
0387
0388 #ifndef BOOST_PARSER_DOXYGEN
0389 BOOST_TRIE_MAP_C_STR_OVERLOAD_QUALS(const_iterator, lower_bound, const)
0390 #endif
0391
0392
0393
0394
0395 template<typename KeyRange>
0396 const_iterator upper_bound(KeyRange const & key) const
0397 {
0398 return bound_impl<false>(key);
0399 }
0400
0401 #ifndef BOOST_PARSER_DOXYGEN
0402 BOOST_TRIE_MAP_C_STR_OVERLOAD_QUALS(const_iterator, upper_bound, const)
0403 #endif
0404
0405
0406 template<typename KeyRange>
0407 const_range equal_range(KeyRange const & key) const
0408 {
0409 return {lower_bound(key), upper_bound(key)};
0410 }
0411
0412 #ifndef BOOST_PARSER_DOXYGEN
0413 BOOST_TRIE_MAP_C_STR_OVERLOAD_QUALS(const_range, equal_range, const)
0414 #endif
0415
0416
0417
0418 template<typename KeyIter, typename Sentinel>
0419 match_result longest_subsequence(KeyIter first, Sentinel last) const
0420
0421 {
0422 return longest_match_impl(first, last);
0423 }
0424
0425
0426
0427 template<typename KeyRange>
0428 match_result longest_subsequence(KeyRange const & key) const
0429 {
0430 return longest_subsequence(detail::begin(key), detail::end(key));
0431 }
0432
0433 #ifndef BOOST_PARSER_DOXYGEN
0434 BOOST_TRIE_MAP_C_STR_OVERLOAD_QUALS(
0435 match_result, longest_subsequence, const)
0436 #endif
0437
0438
0439
0440 template<typename KeyIter, typename Sentinel>
0441 match_result longest_match(KeyIter first, Sentinel last) const
0442 {
0443 auto const retval = longest_match_impl(first, last);
0444 return back_up_to_match(retval);
0445 }
0446
0447
0448
0449 template<typename KeyRange>
0450 match_result longest_match(KeyRange const & key) const
0451 {
0452 return longest_match(detail::begin(key), detail::end(key));
0453 }
0454
0455 #ifndef BOOST_PARSER_DOXYGEN
0456 BOOST_TRIE_MAP_C_STR_OVERLOAD_QUALS(match_result, longest_match, const)
0457 #endif
0458
0459
0460 template<typename KeyElementT>
0461 match_result extend_subsequence(match_result prev, KeyElementT e) const
0462 {
0463 auto e_ptr = &e;
0464 return extend_subsequence_impl(prev, e_ptr, e_ptr + 1);
0465 }
0466
0467
0468
0469 template<typename KeyIter, typename Sentinel>
0470 match_result extend_subsequence(
0471 match_result prev, KeyIter first, Sentinel last) const
0472 {
0473 return extend_subsequence_impl(prev, first, last);
0474 }
0475
0476
0477
0478
0479 template<typename KeyElementT>
0480 match_result extend_match(match_result prev, KeyElementT e) const
0481 {
0482 BOOST_PARSER_ASSERT(prev.match);
0483 auto e_ptr = &e;
0484 auto const retval = extend_subsequence_impl(prev, e_ptr, e_ptr + 1);
0485 return back_up_to_match(retval);
0486 }
0487
0488
0489
0490
0491 template<typename KeyIter, typename Sentinel>
0492 match_result
0493 extend_match(match_result prev, KeyIter first, Sentinel last) const
0494 {
0495 BOOST_PARSER_ASSERT(prev.match);
0496 auto const retval = extend_subsequence_impl(prev, first, last);
0497 return back_up_to_match(retval);
0498 }
0499
0500
0501
0502
0503 template<typename OutIter>
0504 OutIter copy_next_key_elements(match_result prev, OutIter out) const
0505 {
0506 auto node = to_node_ptr(prev.node);
0507 return std::copy(node->key_begin(), node->key_end(), out);
0508 }
0509
0510
0511
0512 template<typename KeyRange>
0513 optional_ref<mapped_type const> operator[](KeyRange const & key) const
0514 {
0515 auto it = find(key);
0516 if (it == end())
0517 return {};
0518 return it->value;
0519 }
0520
0521 #ifndef BOOST_PARSER_DOXYGEN
0522 BOOST_TRIE_MAP_C_STR_OVERLOAD_QUALS(
0523 optional_ref<mapped_type const>, operator[], const)
0524 #endif
0525
0526
0527
0528 optional_ref<mapped_type const> operator[](match_result match) const
0529 {
0530 if (!match.match)
0531 return {};
0532 return *to_node_ptr(match.node)->value();
0533 }
0534
0535 iterator begin() { return iterator(const_this()->begin()); }
0536 iterator end() { return iterator(const_this()->end()); }
0537
0538 reverse_iterator rbegin() { return reverse_iterator{end()}; }
0539 reverse_iterator rend() { return reverse_iterator{begin()}; }
0540
0541 void clear()
0542 {
0543 header_ = node_t();
0544 size_ = 0;
0545 }
0546
0547
0548
0549
0550 template<typename KeyRange>
0551 iterator find(KeyRange const & key)
0552 {
0553 return iterator(const_this()->find(key));
0554 }
0555
0556 #ifndef BOOST_PARSER_DOXYGEN
0557 BOOST_TRIE_MAP_C_STR_OVERLOAD(iterator, find)
0558 #endif
0559
0560
0561
0562
0563 template<typename KeyRange>
0564 iterator lower_bound(KeyRange const & key)
0565 {
0566 return iterator(const_this()->lower_bound(key));
0567 }
0568
0569 #ifndef BOOST_PARSER_DOXYGEN
0570 BOOST_TRIE_MAP_C_STR_OVERLOAD(iterator, lower_bound)
0571 #endif
0572
0573
0574
0575
0576 template<typename KeyRange>
0577 iterator upper_bound(KeyRange const & key)
0578 {
0579 return iterator(const_this()->upper_bound(key));
0580 }
0581
0582 #ifndef BOOST_PARSER_DOXYGEN
0583 BOOST_TRIE_MAP_C_STR_OVERLOAD(iterator, upper_bound)
0584 #endif
0585
0586
0587 template<typename KeyRange>
0588 range equal_range(KeyRange const & key)
0589 {
0590 return {lower_bound(key), upper_bound(key)};
0591 }
0592
0593 #ifndef BOOST_PARSER_DOXYGEN
0594 BOOST_TRIE_MAP_C_STR_OVERLOAD(range, equal_range)
0595 #endif
0596
0597
0598
0599 template<typename KeyRange>
0600 optional_ref<mapped_type> operator[](KeyRange const & key)
0601 {
0602 auto it = find(key);
0603 if (it == end())
0604 return {};
0605 return it->value;
0606 }
0607
0608 #ifndef BOOST_PARSER_DOXYGEN
0609 BOOST_TRIE_MAP_C_STR_OVERLOAD(
0610 optional_ref<mapped_type>, operator[])
0611 #endif
0612
0613
0614
0615 optional_ref<mapped_type> operator[](match_result match)
0616 {
0617 if (!match.match)
0618 return {};
0619 return *const_cast<node_t *>(to_node_ptr(match.node))->value();
0620 }
0621
0622
0623
0624
0625 template<typename KeyIter, typename Sentinel>
0626 insert_result insert(KeyIter first, Sentinel last, Value value)
0627 {
0628 if (empty()) {
0629 std::unique_ptr<node_t> new_node(new node_t(&header_));
0630 header_.insert(std::move(new_node));
0631 }
0632
0633 auto match = longest_match_impl(first, last);
0634 if (first == last && match.match) {
0635 return {iterator(iter_state_t{
0636 to_node_ptr(match.node)->parent(),
0637 to_node_ptr(match.node)->index_within_parent()}),
0638 false};
0639 }
0640 auto node = create_children(
0641 const_cast<node_t *>(to_node_ptr(match.node)), first, last);
0642 node->value() = std::move(value);
0643 ++size_;
0644 return {iterator(iter_state_t{node->parent(), 0}), true};
0645 }
0646
0647
0648
0649
0650 template<typename KeyRange>
0651 insert_result insert(KeyRange const & key, Value value)
0652 {
0653 return insert(detail::begin(key), detail::end(key), std::move(value));
0654 }
0655
0656 template<typename Char, std::size_t N>
0657 insert_result insert(Char const (&chars)[N], Value value)
0658 {
0659 static_assert(
0660 std::is_same<Char, key_element_type>::value,
0661 "Only well-formed when Char is Key::value_type.");
0662 return insert(
0663 detail::char_range<Char const>{chars, chars + N - 1},
0664 std::move(value));
0665 }
0666
0667
0668
0669
0670 insert_result insert(value_type e)
0671 {
0672 return insert(
0673 detail::begin(e.key), detail::end(e.key), std::move(e.value));
0674 }
0675
0676
0677
0678
0679 template<typename Iter, typename Sentinel>
0680 void insert(Iter first, Sentinel last)
0681 {
0682 for (; first != last; ++first) {
0683 insert(first->key, first->value);
0684 }
0685 }
0686
0687
0688
0689
0690 template<typename Range>
0691 insert_result insert(Range const & r)
0692 {
0693 return insert(detail::begin(r), detail::end(r));
0694 }
0695
0696
0697
0698
0699 void insert(std::initializer_list<value_type> il)
0700 {
0701 for (auto const & x : il) {
0702 insert(x);
0703 }
0704 }
0705
0706
0707
0708
0709
0710
0711 template<typename KeyIter, typename Sentinel>
0712 insert_result
0713 insert_or_assign(KeyIter first, Sentinel last, Value value)
0714 {
0715 auto it = first;
0716 auto match = longest_match_impl(it, last);
0717 if (it == last && match.match) {
0718 const_cast<Value &>(*to_node_ptr(match.node)->value()) =
0719 std::move(value);
0720 return insert_result{
0721 iterator(iter_state_t{
0722 to_node_ptr(match.node)->parent(),
0723 to_node_ptr(match.node)->index_within_parent()}),
0724 false};
0725 }
0726 return insert(first, last, std::move(value));
0727 }
0728
0729
0730
0731
0732
0733
0734 template<typename KeyRange>
0735 insert_result insert_or_assign(KeyRange const & key, Value value)
0736 {
0737 return insert_or_assign(
0738 detail::begin(key), detail::end(key), std::move(value));
0739 }
0740
0741 template<typename Char, std::size_t N>
0742 insert_result insert_or_assign(Char const (&chars)[N], Value value)
0743 {
0744 static_assert(
0745 std::is_same<Char, key_element_type>::value,
0746 "Only well-formed when Char is Key::value_type.");
0747 return insert_or_assign(
0748 detail::char_range<Char const>{chars, chars + N - 1},
0749 std::move(value));
0750 }
0751
0752
0753
0754
0755 template<typename KeyRange>
0756 bool erase(KeyRange const & key)
0757 {
0758 auto it = find(key);
0759 if (it == end())
0760 return false;
0761 erase(it);
0762 return true;
0763 }
0764
0765 #ifndef BOOST_PARSER_DOXYGEN
0766 BOOST_TRIE_MAP_C_STR_OVERLOAD(bool, erase)
0767 #endif
0768
0769
0770
0771 iterator erase(iterator it)
0772 {
0773 auto state = it.it_.state_;
0774
0775 --size_;
0776
0777 auto node =
0778 const_cast<node_t *>(state.parent_->child(state.index_));
0779 if (!node->empty()) {
0780
0781
0782 ++it;
0783 node->value() = std::optional<Value>();
0784 return it;
0785 }
0786
0787
0788
0789 const_cast<node_t *>(state.parent_)->erase(state.index_);
0790 while (state.parent_->parent() && state.parent_->empty() &&
0791 !state.parent_->value()) {
0792 state = parent_state(state);
0793 const_cast<node_t *>(state.parent_)->erase(state.index_);
0794 }
0795
0796 if (state.parent_->parent())
0797 state = parent_state(state);
0798 auto retval = iterator(state);
0799 if (!empty())
0800 ++retval;
0801
0802 return retval;
0803 }
0804
0805
0806
0807
0808 iterator erase(iterator first, iterator last)
0809 {
0810 auto retval = last;
0811 if (first == last)
0812 return retval;
0813 --last;
0814 while (last != first) {
0815 erase(last--);
0816 }
0817 erase(last);
0818 return retval;
0819 }
0820
0821 void swap(trie_map & other)
0822 {
0823 header_.swap(other.header_);
0824 std::swap(size_, other.size_);
0825 std::swap(comp_, other.comp_);
0826 }
0827
0828 friend bool operator==(trie_map const & lhs, trie_map const & rhs)
0829 {
0830 return lhs.size() == rhs.size() &&
0831 std::equal(lhs.begin(), lhs.end(), rhs.begin());
0832 }
0833 friend bool operator!=(trie_map const & lhs, trie_map const & rhs)
0834 {
0835 return !(lhs == rhs);
0836 }
0837
0838 #ifndef BOOST_PARSER_DOXYGEN
0839
0840 private:
0841 trie_map const * const_this()
0842 {
0843 return const_cast<trie_map const *>(this);
0844 }
0845 static node_t const * to_node_ptr(void const * ptr)
0846 {
0847 return static_cast<node_t const *>(ptr);
0848 }
0849
0850 template<std::size_t KeySize>
0851 void from_trie_impl(
0852 detail::trie_node_t<
0853 detail::no_index_within_parent_t,
0854 Key,
0855 Value,
0856 KeySize> const & node,
0857 Key & key,
0858 bool root = true)
0859 {
0860
0861
0862 if (!!node.value()) {
0863 insert(key, *node.value());
0864 }
0865
0866 std::vector<key_element_type> next_elements;
0867 node.copy_next_key_elements(std::back_inserter(next_elements));
0868 for (auto const & e : next_elements) {
0869 auto const * n = node.child(e, comp_);
0870 if (!root)
0871 key.insert(key.end(), e);
0872 from_trie_impl(*n, key, false);
0873 if (!root)
0874 key.erase(std::prev(key.end()));
0875 }
0876 }
0877
0878 template<typename KeyIter, typename Sentinel>
0879 match_result longest_match_impl(KeyIter & first, Sentinel last) const
0880 {
0881 return extend_subsequence_impl(
0882 match_result{&header_, 0, false, true}, first, last);
0883 }
0884
0885 template<typename KeyIter, typename Sentinel>
0886 match_result extend_subsequence_impl(
0887 match_result prev, KeyIter & first, Sentinel last) const
0888 {
0889 if (to_node_ptr(prev.node) == &header_) {
0890 if (header_.empty())
0891 return prev;
0892 prev.node = header_.child(0);
0893 }
0894
0895 if (first == last) {
0896 prev.match = !!to_node_ptr(prev.node)->value();
0897 prev.leaf = to_node_ptr(prev.node)->empty();
0898 return prev;
0899 }
0900
0901 node_t const * node = to_node_ptr(prev.node);
0902 size_type size = prev.size;
0903 while (first != last) {
0904 auto const it = node->find(*first, comp_);
0905 if (it == node->end())
0906 break;
0907 ++first;
0908 ++size;
0909 node = it->get();
0910 }
0911
0912 return match_result{node, size, !!node->value(), node->empty()};
0913 }
0914
0915 static match_result back_up_to_match(match_result retval)
0916 {
0917 auto node = to_node_ptr(retval.node);
0918 while (node->parent() && !node->value()) {
0919 retval.node = node = node->parent();
0920 --retval.size;
0921 }
0922 if (!!node->value())
0923 retval.match = true;
0924 return retval;
0925 }
0926
0927 template<typename KeyIter, typename Sentinel>
0928 node_t * create_children(node_t * node, KeyIter first, Sentinel last)
0929 {
0930 auto retval = node;
0931 for (; first != last; ++first) {
0932 std::unique_ptr<node_t> new_node(new node_t(retval));
0933 retval =
0934 retval->insert(*first, comp_, std::move(new_node))->get();
0935 }
0936 return retval;
0937 }
0938
0939 template<bool LowerBound, typename KeyRange>
0940 const_iterator bound_impl(KeyRange const & key) const
0941 {
0942 auto first = detail::begin(key);
0943 auto const last = detail::end(key);
0944 auto match = longest_match_impl(first, last);
0945 if (first == last && match.match) {
0946 auto retval = const_iterator(iter_state_t{
0947 to_node_ptr(match.node)->parent(),
0948 to_node_ptr(match.node)->index_within_parent()});
0949 if (!LowerBound)
0950 ++retval;
0951 return retval;
0952 }
0953
0954 auto node = to_node_ptr(match.node);
0955 if (node->before_child_subtree(*first)) {
0956
0957
0958
0959
0960 return ++const_iterator(
0961 iter_state_t{node->parent(), node->index_within_parent()});
0962 }
0963
0964 auto const it = node->lower_bound(*first, comp_);
0965 if (it == node->end()) {
0966
0967 do {
0968 node = to_node_ptr(node->max_child());
0969 } while (!node->value());
0970 return ++const_iterator(
0971 iter_state_t{node->parent(), node->parent()->size() - 1});
0972 }
0973
0974
0975 std::size_t parent_index = it - node->begin();
0976 node = to_node_ptr(it->get());
0977 while (!node->value()) {
0978 node = to_node_ptr(node->min_child());
0979 parent_index = 0;
0980 }
0981 return const_iterator(iter_state_t{node->parent(), parent_index});
0982 }
0983
0984 node_t header_;
0985 size_type size_;
0986 key_compare comp_;
0987
0988 #endif
0989 };
0990
0991 template<typename Key, typename Compare>
0992 struct trie_set;
0993
0994 template<typename Key>
0995 struct const_trie_set_iterator;
0996
0997 template<typename Key, typename Value>
0998 struct const_trie_map_iterator : stl_interfaces::iterator_interface<
0999 const_trie_map_iterator<Key, Value>,
1000 std::bidirectional_iterator_tag,
1001 trie_element<Key, Value>,
1002 trie_element<Key, Value const &>>
1003 {
1004 private:
1005 using state_t = detail::trie_iterator_state_t<Key, Value>;
1006 state_t state_;
1007 using ref_type = trie_element<Key, Value const &>;
1008 using ptr_type = stl_interfaces::proxy_arrow_result<ref_type>;
1009
1010 public:
1011 const_trie_map_iterator() : state_{nullptr, 0} {}
1012
1013 const_trie_map_iterator(trie_match_result match_result)
1014 {
1015 BOOST_PARSER_ASSERT(match_result.node);
1016 BOOST_PARSER_ASSERT(match_result.match);
1017 auto node = static_cast<detail::trie_node_t<
1018 detail::index_within_parent_t,
1019 Key,
1020 Value> const *>(match_result.node);
1021 state_.parent_ = node->parent();
1022 state_.index_ = node->index_within_parent();
1023 }
1024
1025 ref_type operator*() const
1026 {
1027 return ref_type{detail::reconstruct_key(state_),
1028 state_.parent_->child_value(state_.index_)};
1029 }
1030 ptr_type operator->() const
1031 {
1032 ref_type && deref_result = **this;
1033 return ptr_type(
1034 ref_type{std::move(deref_result.key), deref_result.value});
1035 }
1036
1037 const_trie_map_iterator & operator++()
1038 {
1039 auto node = to_node(state_);
1040 if (node && !node->empty()) {
1041 state_.parent_ = node;
1042 state_.index_ = 0;
1043 } else {
1044
1045 ++state_.index_;
1046 auto const first_state = state_;
1047 while (state_.parent_->parent() &&
1048 state_.parent_->parent()->parent() &&
1049 state_.parent_->size() <= state_.index_) {
1050 state_ = parent_state(state_);
1051 ++state_.index_;
1052 }
1053
1054
1055
1056
1057 if ((!state_.parent_->parent() ||
1058 !state_.parent_->parent()->parent()) &&
1059 state_.parent_->size() <= state_.index_) {
1060 state_ = first_state;
1061 return *this;
1062 }
1063 }
1064
1065 node = state_.parent_->child(state_.index_);
1066 while (!node->value()) {
1067 auto i = 0u;
1068 node = node->child(i);
1069 state_ = state_t{node->parent(), i};
1070 }
1071
1072 return *this;
1073 }
1074 const_trie_map_iterator & operator--()
1075 {
1076
1077 if (state_.index_ == state_.parent_->size()) {
1078 --state_.index_;
1079 return *this;
1080 }
1081
1082
1083
1084 while (state_.parent_->parent() && state_.index_ == 0) {
1085 state_ = parent_state(state_);
1086 if (state_.parent_->child(state_.index_)->value())
1087 return *this;
1088 }
1089
1090
1091
1092 if (state_.index_)
1093 --state_.index_;
1094 auto node = state_.parent_->child(state_.index_);
1095 while (!node->empty()) {
1096 auto i = node->size() - 1;
1097 node = node->child(i);
1098 state_ = state_t{node->parent(), i};
1099 }
1100
1101 return *this;
1102 }
1103
1104 friend bool operator==(
1105 const_trie_map_iterator lhs, const_trie_map_iterator rhs)
1106 {
1107 return lhs.state_.parent_ == rhs.state_.parent_ &&
1108 lhs.state_.index_ == rhs.state_.index_;
1109 }
1110
1111 using base_type = stl_interfaces::iterator_interface<
1112 const_trie_map_iterator<Key, Value>,
1113 std::bidirectional_iterator_tag,
1114 trie_element<Key, Value>,
1115 trie_element<Key, Value const &>>;
1116 using base_type::operator++;
1117 using base_type::operator--;
1118
1119 #ifndef BOOST_PARSER_DOXYGEN
1120
1121 private:
1122 explicit const_trie_map_iterator(state_t state) : state_(state) {}
1123
1124 template<typename KeyT, typename ValueT, typename Compare>
1125 friend struct trie_map;
1126 template<typename KeyT, typename Compare>
1127 friend struct trie_set;
1128 template<typename KeyT, typename ValueT>
1129 friend struct trie_map_iterator;
1130 template<typename KeyT>
1131 friend struct const_trie_set_iterator;
1132
1133 #endif
1134 };
1135
1136 template<typename Key, typename Value>
1137 struct trie_map_iterator : stl_interfaces::iterator_interface<
1138 trie_map_iterator<Key, Value>,
1139 std::bidirectional_iterator_tag,
1140 trie_element<Key, Value>,
1141 trie_element<Key, Value &>>
1142 {
1143 private:
1144 const_trie_map_iterator<Key, Value> it_;
1145 using ref_type = trie_element<Key, Value &>;
1146 using ptr_type = stl_interfaces::proxy_arrow_result<ref_type>;
1147
1148 public:
1149 trie_map_iterator() {}
1150
1151 trie_map_iterator(trie_match_result match_result) :
1152 trie_map_iterator(const_trie_map_iterator<Key, Value>(match_result))
1153 {}
1154
1155 ref_type operator*() const
1156 {
1157 return ref_type{detail::reconstruct_key(it_.state_),
1158 it_.state_.parent_->child_value(it_.state_.index_)};
1159 };
1160
1161 ptr_type operator->() const
1162 {
1163 ref_type && deref_result = **this;
1164 return ptr_type(
1165 ref_type{std::move(deref_result.key), deref_result.value});
1166 }
1167
1168 trie_map_iterator & operator++()
1169 {
1170 ++it_;
1171 return *this;
1172 }
1173 trie_map_iterator & operator--()
1174 {
1175 --it_;
1176 return *this;
1177 }
1178
1179 friend bool
1180 operator==(trie_map_iterator lhs, trie_map_iterator rhs)
1181 {
1182 return lhs.it_ == rhs.it_;
1183 }
1184
1185 using base_type = stl_interfaces::iterator_interface<
1186 trie_map_iterator<Key, Value>,
1187 std::bidirectional_iterator_tag,
1188 trie_element<Key, Value>,
1189 trie_element<Key, Value &>>;
1190 using base_type::operator++;
1191 using base_type::operator--;
1192
1193 #ifndef BOOST_PARSER_DOXYGEN
1194
1195 private:
1196 explicit trie_map_iterator(
1197 detail::trie_iterator_state_t<Key, Value> state) :
1198 it_(state)
1199 {}
1200 explicit trie_map_iterator(const_trie_map_iterator<Key, Value> it) :
1201 it_(it)
1202 {}
1203
1204 template<typename KeyT, typename ValueT, typename Compare>
1205 friend struct trie_map;
1206 template<typename KeyT, typename Compare>
1207 friend struct trie_set;
1208
1209 #endif
1210 };
1211
1212 }}
1213
1214 #if BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS
1215
1216 namespace std::ranges {
1217 template<typename Iter>
1218 inline constexpr bool
1219 enable_borrowed_range<boost::parser::detail::text::trie_range<Iter>> =
1220 true;
1221 template<typename Iter>
1222 inline constexpr bool enable_borrowed_range<
1223 boost::parser::detail::text::const_trie_range<Iter>> = true;
1224 }
1225
1226 #endif
1227
1228 #endif