67 using trie_type = _TrieType;
69 using _is_const = std::bool_constant<IsConst>;
75 using trie_node_type = mdds::detail::const_t<typename trie_type::trie_node, IsConst>;
77 typename std::remove_const<trie_node_type>::type::children_type, _is_const>::type;
79 using key_type =
typename trie_type::key_type;
85 using pointer = value_type*;
86 using reference = value_type&;
87 using difference_type = std::ptrdiff_t;
88 using iterator_category = std::bidirectional_iterator_tag;
91 node_stack_type m_node_stack;
93 key_type m_current_key;
94 trie_value_type* m_current_value_ptr;
97 static trie_node_type* push_child_node_to_stack(
98 node_stack_type& node_stack, key_type& buf, trie_node_child_pos_type& child_pos)
100 trie_node_type* node = &child_pos->second;
101 buf.push_back(child_pos->first);
102 node_stack.emplace_back(node, node->children.begin());
113 trie_node_type* cur_node =
nullptr;
120 auto& si = node_stack.back();
123 buf.push_back(si.child_pos->first);
124 cur_node = &si.child_pos->second;
125 node_stack.emplace_back(cur_node, cur_node->children.end());
126 }
while (!cur_node->children.empty());
131 iterator_base(empty_iterator_type) : m_current_value_ptr(nullptr), m_type(iterator_type::empty)
135 iterator_base() : m_current_value_ptr(nullptr), m_type(iterator_type::normal)
138 iterator_base(node_stack_type&& node_stack, key_type&& buf, iterator_type type)
139 : m_node_stack(std::move(node_stack)), m_buffer(std::move(buf)), m_current_key(m_buffer),
140 m_current_value_ptr(&m_node_stack.back().node->value), m_type(type)
143 bool operator==(
const iterator_base& other)
const
145 if (m_type != other.m_type)
148 if (m_type == iterator_type::empty)
151 return m_node_stack.back() == other.m_node_stack.back();
154 bool operator!=(
const iterator_base& other)
const
156 return !operator==(other);
159 value_type operator*()
161 return value_type(m_current_key, *m_current_value_ptr);
164 value_type operator->()
166 return value_type(m_current_key, *m_current_value_ptr);
169 iterator_base& operator++()
171 trie_node_type* cur_node = m_node_stack.back().node;
175 if (cur_node->children.empty())
182 if (m_node_stack.size() == 1)
184#ifdef MDDS_TRIE_MAP_DEBUG
185 if (m_type == iterator_type::end)
187 std::ostringstream os;
188 os <<
"iterator_base::operator++#" << __LINE__ <<
": moving past the end position!";
189 throw general_error(os.str());
193 m_type = iterator_type::end;
199 m_node_stack.pop_back();
200 auto& si = m_node_stack.back();
203 if (si.child_pos != si.node->children.end())
206 cur_node = push_child_node_to_stack(m_node_stack, m_buffer, si.child_pos);
214 auto child_pos = cur_node->children.begin();
215 cur_node = push_child_node_to_stack(m_node_stack, m_buffer, child_pos);
217 }
while (!cur_node->has_value);
219 m_current_key = m_buffer;
220 m_current_value_ptr = &cur_node->value;
224 iterator_base operator++(
int)
226 iterator_base tmp(*
this);
231 iterator_base& operator--()
233 trie_node_type* cur_node = m_node_stack.back().node;
235 if (m_type == iterator_type::end && cur_node->has_value)
237 assert(m_node_stack.size() == 1);
238 m_type = iterator_type::normal;
240 else if (m_node_stack.size() == 1)
244 auto& si = m_node_stack.back();
245 assert(si.child_pos == cur_node->children.end());
247 m_type = iterator_type::normal;
249 else if (cur_node->children.empty())
260 m_node_stack.pop_back();
261 auto& si = m_node_stack.back();
264 if (si.child_pos != cur_node->children.begin())
268 assert(cur_node->has_value);
270 }
while (!cur_node->has_value);
277 assert(cur_node->has_value);
278 assert(m_node_stack.back().child_pos == cur_node->children.begin());
284 m_node_stack.pop_back();
285 auto& si = m_node_stack.back();
288 if (m_node_stack.size() == 1)
292 assert(cur_node->has_value);
294 }
while (!cur_node->has_value);
297 assert(cur_node->has_value);
298 m_current_key = m_buffer;
299 m_current_value_ptr = &cur_node->value;
303 iterator_base operator--(
int)
305 iterator_base tmp(*
this);
407 using trie_type = _TrieType;
409 using node_stack_type =
typename trie_type::const_node_stack_type;
411 using trie_node =
typename trie_type::trie_node;
412 using key_type =
typename trie_type::key_type;
413 using key_unit_type =
typename key_type::value_type;
415 const trie_node* m_node;
417 node_stack_type m_node_stack;
419 search_results(
const trie_node* node, key_type&& buf) : m_node(node), m_buffer(buf)
423 using const_iterator =
typename trie_type::const_iterator;
425 const_iterator begin()
const
429 return const_iterator(empty_iterator);
432 key_type buf(m_buffer);
433 node_stack_type node_stack;
434 node_stack.emplace_back(m_node, m_node->children.begin());
436 while (!node_stack.back().node->has_value)
441 auto it = node_stack.back().child_pos;
442 const_iterator::push_child_node_to_stack(node_stack, buf, it);
445 return const_iterator(std::move(node_stack), std::move(buf), iterator_type::normal);
448 const_iterator end()
const
452 return const_iterator(empty_iterator);
454 node_stack_type node_stack;
455 node_stack.emplace_back(m_node, m_node->children.end());
456 return const_iterator(std::move(node_stack), key_type(m_buffer), iterator_type::end);
464class packed_iterator_base
466 using trie_type = TrieT;
470 using stack_item =
typename trie_type::stack_item;
471 using node_stack_type =
typename trie_type::node_stack_type;
473 using key_type =
typename trie_type::key_type;
474 using size_type =
typename trie_type::size_type;
475 using trie_value_type =
typename trie_type::value_type;
476 using value_store_type =
typename trie_type::value_store_type;
477 using pack_value_type =
typename trie_type::pack_value_type;
478 using key_unit_type =
typename key_type::value_type;
483 using pointer = value_type*;
484 using reference = value_type&;
485 using difference_type = std::ptrdiff_t;
486 using iterator_category = std::bidirectional_iterator_tag;
489 const value_store_type* m_value_store =
nullptr;
490 node_stack_type m_node_stack;
492 pack_value_type m_current_value = trie_type::null_value;
493 iterator_type m_type;
499 static void push_child_node_to_stack(
500 const value_store_type* value_store, node_stack_type& node_stack, key_type& buf,
501 const pack_value_type* child_pos)
504 const auto* node_pos = node_stack.back().node_pos;
506 key_unit_type c =
static_cast<key_unit_type
>(*child_pos);
509 auto offset =
static_cast<size_type
>(*child_pos);
511 const auto* p = node_pos;
513 size_type index_size = *p;
516 const auto* child_end = child_pos + index_size;
519 node_stack.emplace_back(value_store, node_pos, child_pos, child_end);
522 static void descend_to_previous_leaf_node(node_stack_type& node_stack, key_type& buf)
524 const pack_value_type* node_pos =
nullptr;
525 size_t index_size = 0;
532 stack_item* si = &node_stack.back();
533 node_pos = si->node_pos;
535 size_t offset = *si->child_pos;
537 key_unit_type c = *si->child_pos;
541 const auto* p = node_pos;
545 const auto* child_pos = p;
546 const auto* child_end = child_pos + index_size;
547 node_stack.emplace_back(node_stack.back().value_store, node_pos, child_end, child_end);
548 }
while (index_size);
551 packed_iterator_base(empty_iterator_type) : m_type(iterator_type::empty)
555 packed_iterator_base() : m_type(iterator_type::normal)
558 packed_iterator_base(
559 const value_store_type* value_store, node_stack_type&& node_stack, key_type&& buf, pack_value_type pos)
560 : m_value_store(value_store), m_node_stack(std::move(node_stack)), m_buffer(std::move(buf)),
561 m_current_value(pos), m_type(iterator_type::normal)
564 packed_iterator_base(
const value_store_type* value_store, node_stack_type&& node_stack, key_type&& buf)
565 : m_value_store(value_store), m_node_stack(std::move(node_stack)), m_buffer(std::move(buf)),
566 m_type(iterator_type::end)
569 bool operator==(
const packed_iterator_base& other)
const
571 if (m_type != other.m_type)
574 if (m_type == iterator_type::empty)
577 return m_node_stack.back() == other.m_node_stack.back();
580 bool operator!=(
const packed_iterator_base& other)
const
582 return !operator==(other);
585 value_type operator*()
587 assert(m_value_store);
588 assert(m_current_value != trie_type::null_value);
589 return value_type(m_buffer, (*m_value_store)[m_current_value]);
592 value_type operator->()
594 assert(m_value_store);
595 assert(m_current_value != trie_type::null_value);
596 return value_type(m_buffer, (*m_value_store)[m_current_value]);
599 packed_iterator_base& operator++()
601 stack_item* si = &m_node_stack.back();
602 pack_value_type v = trie_type::null_value;
603 size_t index_size = *(si->node_pos + 1);
614 if (m_node_stack.size() == 1)
616#ifdef MDDS_TRIE_MAP_DEBUG
617 if (m_type == iterator_type::end)
619 std::ostringstream os;
620 os <<
"packed_iterator_base::operator++#" << __LINE__ <<
": moving past the end position!";
625 m_type = iterator_type::end;
631 m_node_stack.pop_back();
632 si = &m_node_stack.back();
633 std::advance(si->child_pos, 2);
635 if (si->child_pos != si->child_end)
638 push_child_node_to_stack(m_value_store, m_node_stack, m_buffer, si->child_pos);
646 push_child_node_to_stack(m_value_store, m_node_stack, m_buffer, si->child_pos);
649 si = &m_node_stack.back();
651 index_size = *(si->node_pos + 1);
652 }
while (v == trie_type::null_value);
654 assert(v != trie_type::null_value);
660 packed_iterator_base operator++(
int)
662 packed_iterator_base tmp(*
this);
667 packed_iterator_base& operator--()
669 stack_item* si = &m_node_stack.back();
670 pack_value_type v = *si->node_pos;
671 size_t index_size = *(si->node_pos + 1);
673 if (m_type == iterator_type::end && v != trie_type::null_value)
675 assert(m_node_stack.size() == 1);
676 m_type = iterator_type::normal;
678 else if (m_node_stack.size() == 1)
682 assert(si->child_pos == si->child_end);
683 descend_to_previous_leaf_node(m_node_stack, m_buffer);
684 si = &m_node_stack.back();
686 m_type = iterator_type::normal;
688 else if (!index_size)
699 m_node_stack.pop_back();
700 si = &m_node_stack.back();
701 const auto* p = si->node_pos;
706 const auto* first_child = p;
708 if (si->child_pos != first_child)
711 descend_to_previous_leaf_node(m_node_stack, m_buffer);
712 si = &m_node_stack.back();
715 assert(v != trie_type::null_value);
717 }
while (v == trie_type::null_value);
724 assert(*si->node_pos);
725 assert(si->child_pos == (si->node_pos + 2));
731 m_node_stack.pop_back();
732 si = &m_node_stack.back();
735 if (m_node_stack.size() == 1)
738 descend_to_previous_leaf_node(m_node_stack, m_buffer);
739 si = &m_node_stack.back();
741 assert(v != trie_type::null_value);
743 }
while (v == trie_type::null_value);
746 assert(v != trie_type::null_value);
752 packed_iterator_base operator--(
int)
754 packed_iterator_base tmp(*
this);
761class packed_search_results
763 using trie_type = _TrieType;
765 using node_stack_type =
typename trie_type::node_stack_type;
766 using value_store_type =
typename trie_type::value_store_type;
767 using pack_value_type =
typename trie_type::pack_value_type;
769 using key_type =
typename trie_type::key_type;
770 using key_unit_type =
typename key_type::value_type;
772 const value_store_type* m_value_store =
nullptr;
773 const pack_value_type* m_node =
nullptr;
776 packed_search_results(
const value_store_type* value_store,
const pack_value_type* node, key_type&& buf)
777 : m_value_store(value_store), m_node(node), m_buffer(std::move(buf))
779 assert(m_value_store);
782 node_stack_type get_root_node()
const
784 const auto* p = m_node;
786 size_t index_size = *p;
788 const auto* child_pos = p;
789 const auto* child_end = child_pos + index_size;
792 node_stack_type node_stack;
793 node_stack.emplace_back(m_value_store, m_node, child_pos, child_end);
797 void swap(packed_search_results& other)
799 std::swap(m_node, other.m_node);
800 std::swap(m_buffer, other.m_buffer);
806 packed_search_results() : m_node(
nullptr)
809 packed_search_results(
const packed_search_results& other) : m_node(other.m_node), m_buffer(other.m_buffer)
812 packed_search_results(packed_search_results&& other) : m_node(other.m_node), m_buffer(std::move(other.m_buffer))
814 other.m_node =
nullptr;
817 packed_search_results& operator=(packed_search_results other)
819 packed_search_results tmp(std::move(other));
824 const_iterator begin()
const
828 return const_iterator(empty_iterator);
831 key_type buf(m_buffer);
832 node_stack_type node_stack = get_root_node();
834 while (!node_stack.back().has_value())
839 const_iterator::push_child_node_to_stack(m_value_store, node_stack, buf, node_stack.back().child_pos);
842 return const_iterator(m_value_store, std::move(node_stack), std::move(buf), node_stack.back().get_value_pos());
845 const_iterator end()
const
849 return const_iterator(empty_iterator);
851 node_stack_type node_stack = get_root_node();
852 auto& si = node_stack.back();
853 si.child_pos = si.child_end;
854 return const_iterator(m_value_store, std::move(node_stack), key_type(m_buffer));