3 #include <wordring/serialize/serialize_iterator.hpp>
4 #include <wordring/trie/stable_trie_base.hpp>
5 #include <wordring/trie/trie_base.hpp>
6 #include <wordring/trie/trie_iterator.hpp>
10 #include <type_traits>
129 template <
typename Label,
typename Base>
132 template <
typename Label1,
typename Base1>
135 template <
typename Label1,
typename Base1>
139 using base_type = Base;
141 using typename base_type::container;
142 using typename base_type::label_vector;
143 using typename base_type::index_type;
144 using typename base_type::node_type;
146 using base_type::null_value;
149 using label_type = Label;
150 using value_type = std::uint32_t;
151 using size_type =
typename container::size_type;
152 using allocator_type =
typename base_type::allocator_type;
158 using typename base_type::serialize_iterator;
160 using base_type::get_allocator;
161 using base_type::ibegin;
162 using base_type::iend;
163 using base_type::clear;
166 using base_type::is_tail;
168 using base_type::m_c;
170 static std::uint32_t constexpr coefficient =
sizeof(label_type) /
sizeof(
typename base_type::label_type);
172 static_assert(std::is_integral_v<label_type>);
173 static_assert(1 <= coefficient);
226 template <typename InputIterator, typename std::enable_if_t<std::is_integral_v<typename std::iterator_traits<InputIterator>::value_type>, std::nullptr_t> =
nullptr>
227 basic_trie(InputIterator first, InputIterator last, allocator_type
const& alloc = allocator_type())
253 template <typename ForwardIterator, typename std::enable_if_t<std::negation_v<std::is_integral<typename std::iterator_traits<ForwardIterator>::value_type>>, std::nullptr_t> =
nullptr>
254 basic_trie(ForwardIterator first, ForwardIterator last, allocator_type
const& alloc = allocator_type())
275 basic_trie(std::initializer_list<detail::trie_node> il, allocator_type
const& alloc = allocator_type())
276 : base_type(il, alloc)
305 template <typename InputIterator, typename std::enable_if_t<std::is_integral_v<typename std::iterator_traits<InputIterator>::value_type>, std::nullptr_t> =
nullptr>
306 void assign(InputIterator first, InputIterator last)
308 base_type::assign(first, last);
331 template <typename ForwardIterator, typename std::enable_if_t<std::negation_v<std::is_integral<typename std::iterator_traits<ForwardIterator>::value_type>>, std::nullptr_t> =
nullptr>
332 void assign(ForwardIterator first, ForwardIterator last)
334 assert(coefficient ==
sizeof(
typename std::iterator_traits<ForwardIterator>::value_type::value_type));
336 if constexpr (coefficient == 1) base_type::assign(first, last);
339 while (first != last)
365 return base_type::at(
static_cast<typename base_type::const_iterator
>(pos), idx);
399 return base_type::at(
static_cast<typename base_type::const_iterator
>(pos));
444 template <
typename InputIterator>
447 assert(coefficient ==
sizeof(
typename std::iterator_traits<InputIterator>::value_type));
451 if constexpr (coefficient == 1) result = base_type::at(first, last);
457 result = base_type::at(it1, it2);
472 template <
typename InputIterator>
473 const_reference
at(InputIterator first, InputIterator last)
const
505 template <
typename Key>
508 return at(std::begin(key), std::end(key));
521 template <
typename Key>
522 const_reference
const at(Key
const& key)
const
524 return at(std::begin(key), std::end(key));
550 template <
typename Key>
601 size_type
size() const noexcept
603 return base_type::size();
612 return base_type::max_size() / coefficient;
643 template <
typename InputIterator>
646 assert(coefficient ==
sizeof(
typename std::iterator_traits<InputIterator>::value_type));
650 if constexpr (coefficient == 1) result = base_type::insert(first, last, value);
656 result = base_type::insert(it1, it2, value);
686 template <
typename Key>
689 return insert(std::begin(key), std::end(key), value);
714 base_type::erase(
static_cast<typename base_type::const_iterator
>(pos));
738 template <
typename InputIterator>
739 void erase(InputIterator first, InputIterator last)
741 assert(coefficient ==
sizeof(
typename std::iterator_traits<InputIterator>::value_type));
765 template <
typename Key>
768 erase(std::begin(key), std::end(key));
773 base_type::swap(other);
803 template <
typename InputIterator>
804 auto lookup(InputIterator first, InputIterator last)
const
806 assert(coefficient ==
sizeof(
typename std::iterator_traits<InputIterator>::value_type));
808 std::pair<const_iterator, InputIterator> result;
810 if constexpr (coefficient == 1)
812 auto ret = base_type::lookup(first, last);
813 result.first = ret.first;
814 result.second = ret.second;
822 auto ret = base_type::lookup(it1, it2, i);
825 if (i != 0)
for (; i != 0; --i) ret.first = ret.first.parent();
827 result.first = ret.first;
828 result.second = ret.second.base();
842 template <
typename InputIterator>
845 assert(coefficient ==
sizeof(
typename std::iterator_traits<InputIterator>::value_type));
847 auto pair =
lookup(first, last);
849 return (pair.second == last)
877 template <
typename Key>
880 return search(std::begin(key), std::end(key));
892 template <
typename InputIterator>
895 assert(coefficient ==
sizeof(
typename std::iterator_traits<InputIterator>::value_type));
897 auto pair =
lookup(first, last);
899 auto it = pair.second;
900 index_type idx = pair.first.m_index;
902 return (it == last && is_tail(idx))
930 template <
typename Key>
933 return find(std::begin(key), std::end(key));
943 template <
typename InputIterator>
944 bool contains(InputIterator first, InputIterator last)
const
946 assert(coefficient ==
sizeof(
typename std::iterator_traits<InputIterator>::value_type));
948 auto pair =
lookup(first, last);
950 auto it = pair.second;
951 index_type idx = pair.first.m_index;
953 return !(it != last || !is_tail(idx));
974 template <
typename Key>
977 return contains(std::begin(key), std::end(key));
1003 template <
typename Label1,
typename Base1>
1006 typename basic_trie<Label1, Base1>::base_type
const& base =
trie;
1014 template <
typename Label1,
typename Base1>
1017 typename basic_trie<Label1, Base1>::base_type& base =
trie;
1025 template <
typename Label,
typename Allocator = std::allocator<detail::trie_node>>
1033 template <
typename Label,
typename Allocator = std::allocator<detail::trie_node>>