49 using size_type = std::size_t;
58 static constexpr bool is_nothrow_less_v =
noexcept(std::declval<key_type>() < std::declval<key_type>()) &&
59 noexcept(std::declval<value_type>() < std::declval<value_type>());
61 static constexpr bool is_nothrow_equal_v =
noexcept(std::declval<key_type>() == std::declval<key_type>()) &&
62 noexcept(std::declval<value_type>() == std::declval<value_type>());
64 segment_type() =
default;
66 segment_type(
const segment_type&) =
default;
67 segment_type(segment_type&&) =
default;
69 segment_type& operator=(
const segment_type& r) =
default;
70 segment_type& operator=(segment_type&& r) =
default;
71 bool operator<(
const segment_type& r)
const noexcept(is_nothrow_less_v && is_nothrow_equal_v);
72 bool operator==(
const segment_type& r)
const noexcept(is_nothrow_equal_v);
73 bool operator!=(
const segment_type& r)
const noexcept(is_nothrow_equal_v);
76 using segment_store_type = std::deque<segment_type>;
77 using value_pos_type =
typename segment_store_type::size_type;
78 using value_chain_type = std::vector<value_pos_type>;
80 using node_chain_type = std::vector<st::detail::node_base*>;
81 using value_to_nodes_type = std::map<value_pos_type, node_chain_type>;
83 struct nonleaf_value_type
85 std::unique_ptr<value_chain_type> data_chain;
89 nonleaf_value_type(
const nonleaf_value_type& r)
92 data_chain = std::make_unique<value_chain_type>(*r.data_chain);
95 bool operator==(
const nonleaf_value_type& r)
const
97 return data_chain == r.data_chain;
100 ~nonleaf_value_type()
104 struct leaf_value_type
106 std::unique_ptr<value_chain_type> data_chain;
110 leaf_value_type(
const leaf_value_type& r)
113 data_chain = std::make_unique<value_chain_type>(*r.data_chain);
116 bool operator==(
const leaf_value_type& r)
const
118 return data_chain == r.data_chain;
126 using node = st::detail::node<key_type, leaf_value_type>;
127 using node_ptr =
typename node::node_ptr;
128 using nonleaf_node =
typename st::detail::nonleaf_node<key_type, nonleaf_value_type>;
131 class search_result_inserter;
137 class search_results_base
139 friend class search_result_inserter;
142 typedef std::vector<value_chain_type*> res_chains_type;
143 typedef std::shared_ptr<res_chains_type> res_chains_ptr;
146 search_results_base(
const segment_store_type& segment_store) : m_segment_store(&segment_store)
149 search_results_base(
const search_results_base& r)
150 : m_segment_store(r.m_segment_store), mp_res_chains(r.mp_res_chains)
155 size_type
size()
const;
157 void push_back_chain(value_chain_type* chain);
159 const segment_store_type* get_segment_store()
const
161 return m_segment_store;
164 const res_chains_ptr& get_res_chains()
const
166 return mp_res_chains;
170 const segment_store_type* m_segment_store =
nullptr;
171 res_chains_ptr mp_res_chains;
174 class const_iterator_base
176 friend class segment_tree;
179 typedef typename search_results_base::res_chains_type res_chains_type;
180 typedef typename search_results_base::res_chains_ptr res_chains_ptr;
182 const_iterator_base(
const segment_store_type* segment_store,
const res_chains_ptr& p)
183 : m_segment_store(segment_store), mp_res_chains(p), m_end_pos(true)
187 using iterator_category = std::bidirectional_iterator_tag;
188 using value_type =
const segment_tree::segment_type;
189 using pointer = value_type*;
190 using reference = value_type&;
191 using difference_type = std::ptrdiff_t;
193 const_iterator_base() =
default;
194 const_iterator_base(
const const_iterator_base& r) =
default;
195 const_iterator_base& operator=(
const const_iterator_base& r) =
default;
197 value_type* operator++();
198 value_type* operator--();
200 bool operator==(
const const_iterator_base& r)
const;
201 bool operator!=(
const const_iterator_base& r)
const;
203 value_type& operator*()
208 const value_type* operator->()
214 void move_to_front();
218 value_type& cur_value()
220 auto pos = *m_cur_pos_in_chain;
221 return (*m_segment_store)[pos];
224 size_type cur_pos()
const
226 return *m_cur_pos_in_chain;
229 const segment_store_type* m_segment_store =
nullptr;
230 res_chains_ptr mp_res_chains;
231 typename res_chains_type::const_iterator m_cur_chain;
232 typename value_chain_type::const_iterator m_cur_pos_in_chain;
233 bool m_end_pos =
true;
236 class search_result_inserter
239 search_result_inserter(search_results_base& results) : m_results(results)
241 void operator()(value_chain_type* node_data)
246 m_results.push_back_chain(node_data);
250 search_results_base& m_results;
253 static constexpr bool nothrow_default_constructible_v =
254 std::is_nothrow_default_constructible_v<std::vector<nonleaf_node>> &&
255 std::is_nothrow_default_constructible_v<segment_store_type> &&
256 std::is_nothrow_default_constructible_v<value_to_nodes_type> &&
257 std::is_nothrow_default_constructible_v<node_ptr>;
259 static constexpr bool nothrow_move_constructible_v =
260 std::is_nothrow_move_constructible_v<std::vector<nonleaf_node>> &&
261 std::is_nothrow_move_constructible_v<segment_store_type> &&
262 std::is_nothrow_move_constructible_v<value_to_nodes_type> && std::is_nothrow_move_constructible_v<node_ptr>;
264 static constexpr bool nothrow_swappable_v =
265 std::is_nothrow_swappable_v<std::vector<nonleaf_node>> && std::is_nothrow_swappable_v<segment_store_type> &&
266 std::is_nothrow_swappable_v<value_to_nodes_type> && std::is_nothrow_swappable_v<node_ptr>;
268 static constexpr bool nothrow_move_assignable_v = nothrow_move_constructible_v && nothrow_swappable_v;
271 class search_results :
public search_results_base
273 friend class segment_tree;
275 typedef typename search_results_base::res_chains_type res_chains_type;
276 typedef typename search_results_base::res_chains_ptr res_chains_ptr;
278 search_results(
const segment_store_type& segment_tree) : search_results_base(segment_tree)
282 class const_iterator :
public const_iterator_base
284 friend class segment_tree<KeyT, ValueT>::search_results;
287 const_iterator(const segment_store_type* segment_store, const res_chains_ptr& p)
288 : const_iterator_base(segment_store, p)
292 const_iterator() : const_iterator_base()
295 const_iterator(
const const_iterator& r) : const_iterator_base(r)
298 const_iterator& operator=(
const const_iterator& r)
300 const_iterator_base::operator=(r);
312 return search_results_base::empty();
322 return search_results_base::size();
328 search_results_base::get_segment_store(), search_results_base::get_res_chains());
333 typename search_results::const_iterator end()
const
335 typename search_results::const_iterator it(
336 search_results_base::get_segment_store(), search_results_base::get_res_chains());
342 segment_tree() noexcept(nothrow_default_constructible_v);
343 segment_tree(const segment_tree& r);
344 segment_tree(segment_tree&& r) = default;
347 segment_tree& operator=(const segment_tree& r);
348 segment_tree& operator=(segment_tree&& r) noexcept(nothrow_move_assignable_v);
357 bool operator==(const segment_tree& r) const;
359 bool operator!=(const segment_tree& r) const;
438 template<
typename Pred>
446 void swap(segment_tree& r)
noexcept(nothrow_swappable_v);
469 noexcept(noexcept(st::detail::count_leaf_nodes<size_type>(m_left_leaf.get(), m_right_leaf.get())))
471 return st::detail::count_leaf_nodes<size_type>(m_left_leaf.get(), m_right_leaf.get());
494 std::vector<value_type> value_chain;
497 std::vector<leaf_node> leaf_nodes;
503 static void create_leaf_node_instances(std::vector<key_type> keys, node_ptr& left, node_ptr& right);
510 void descend_tree_and_mark(
512 node_chain_type& nodelist);
514 void build_leaf_nodes();
520 void remove_data_from_nodes(node_chain_type& nodelist, value_pos_type value);
521 void remove_data_from_chain(value_chain_type& chain, value_pos_type value);
522 void remove_value_pos(size_type pos);
524 void clear_all_nodes();
527 struct tree_dumper_traits
529 using leaf_type = node;
530 using nonleaf_type = nonleaf_node;
531 using tree_type = segment_tree;
535 const tree_type& tree;
538 std::string operator()(
const leaf_type& leaf)
const;
539 std::string operator()(
const nonleaf_type& nonleaf)
const;
543 std::vector<nonleaf_node> m_nonleaf_node_pool;
550 segment_store_type m_segment_store;
557 value_to_nodes_type m_tagged_nodes_map;
559 nonleaf_node* m_root_node;
560 node_ptr m_left_leaf;
561 node_ptr m_right_leaf;