libstdc++
GNU C++ library
Loading...
Searching...
No Matches
pat_trie_.hpp
Go to the documentation of this file.
1// -*- C++ -*-
2
3// Copyright (C) 2005-2026 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the terms
7// of the GNU General Public License as published by the Free Software
8// Foundation; either version 3, or (at your option) any later
9// version.
10
11// This library is distributed in the hope that it will be useful, but
12// WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
26
27// Permission to use, copy, modify, sell, and distribute this software
28// is hereby granted without fee, provided that the above copyright
29// notice appears in all copies, and that both that copyright notice
30// and this permission notice appear in supporting documentation. None
31// of the above authors, nor IBM Haifa Research Laboratories, make any
32// representation about the suitability of this software for any
33// purpose. It is provided "as is" without express or implied
34// warranty.
35
36/**
37 * @file pat_trie_/pat_trie_.hpp
38 * Contains an implementation class for a patricia tree.
39 */
40
41#include <iterator>
42#include <utility>
43#include <algorithm>
44#include <functional>
45#include <assert.h>
46#include <list>
56#ifdef _GLIBCXX_DEBUG
58#endif
59#include <debug/debug.h>
60
61namespace __gnu_pbds
62{
63 namespace detail
64 {
65#ifdef PB_DS_DATA_TRUE_INDICATOR
66#define PB_DS_PAT_TRIE_NAME pat_trie_map
67#endif
68
69#ifdef PB_DS_DATA_FALSE_INDICATOR
70#define PB_DS_PAT_TRIE_NAME pat_trie_set
71#endif
72
73#define PB_DS_CLASS_T_DEC \
74 template<typename Key, typename Mapped, typename Node_And_It_Traits, \
75 typename _Alloc>
76
77#define PB_DS_CLASS_C_DEC \
78 PB_DS_PAT_TRIE_NAME<Key, Mapped, Node_And_It_Traits, _Alloc>
79
80#define PB_DS_PAT_TRIE_TRAITS_BASE \
81 types_traits<Key, Mapped, _Alloc, false>
82
83#ifdef _GLIBCXX_DEBUG
84#define PB_DS_DEBUG_MAP_BASE_C_DEC \
85 debug_map_base<Key, eq_by_less<Key, std::less<Key> >, \
86 typename rebind_traits<_Alloc, Key>::const_reference>
87#endif
88
89
90 /**
91 * @brief PATRICIA trie.
92 * @ingroup branch-detail
93 *
94 * This implementation loosely borrows ideas from:
95 * 1) Fast Mergeable Integer Maps, Okasaki, Gill 1998
96 * 2) Ptset: Sets of integers implemented as Patricia trees,
97 * Jean-Christophe Filliatr, 2000
98 */
99 template<typename Key, typename Mapped, typename Node_And_It_Traits,
100 typename _Alloc>
102#ifdef _GLIBCXX_DEBUG
103 public PB_DS_DEBUG_MAP_BASE_C_DEC,
104#endif
105 public Node_And_It_Traits::synth_access_traits,
106 public Node_And_It_Traits::node_update,
109 {
110 private:
113 typedef Node_And_It_Traits traits_type;
115 typedef typename traits_type::synth_access_traits synth_access_traits;
117
118 typedef typename traits_type::node node;
120 typedef typename __rebind_n::const_pointer node_const_pointer;
121 typedef typename __rebind_n::pointer node_pointer;
122
123 typedef typename traits_type::head head;
125 typedef typename __rebind_h::allocator_type head_allocator;
126 typedef typename __rebind_h::pointer head_pointer;
128 typedef typename traits_type::leaf leaf;
130 typedef typename __rebind_l::allocator_type leaf_allocator;
131 typedef typename __rebind_l::pointer leaf_pointer;
132 typedef typename __rebind_l::const_pointer leaf_const_pointer;
133
134 typedef typename traits_type::inode inode;
135 typedef typename inode::iterator inode_iterator;
137 typedef typename __rebind_in::allocator_type inode_allocator;
138 typedef typename __rebind_in::pointer inode_pointer;
139 typedef typename __rebind_in::const_pointer inode_const_pointer;
141
142 /// Conditional deallocator.
144 {
145 protected:
149
150 public:
152 : m_p_nd(p_nd), m_no_action_dtor(false), m_call_destructor(false)
153 { }
155 void
159 void
161 { m_call_destructor = true; }
164 {
166 return;
168 if (m_call_destructor)
169 m_p_nd->~leaf();
171 s_leaf_allocator.deallocate(m_p_nd, 1);
172 }
173 };
174
175
176 /// Branch bag, for split-join.
178 {
179 private:
183
184#ifdef _GLIBCXX_DEBUG
185 typedef std::_GLIBCXX_STD_C::list<__inp, __rebind_inp> bag_type;
186#else
188#endif
191 public:
192 void
195 inode_pointer p_nd = s_inode_allocator.allocate(1);
196 __try
198 m_bag.push_back(p_nd);
199 }
200 __catch(...)
202 s_inode_allocator.deallocate(p_nd, 1);
204 }
205 }
206
209 {
211 inode_pointer p_nd = *m_bag.begin();
212 m_bag.pop_front();
213 return p_nd;
214 }
215
217 {
218 while (!m_bag.empty())
219 {
220 inode_pointer p_nd = *m_bag.begin();
221 s_inode_allocator.deallocate(p_nd, 1);
222 m_bag.pop_front();
224 }
225
227 empty() const
228 { return m_bag.empty(); }
229 };
230
231#ifdef _GLIBCXX_DEBUG
232 typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base;
233#endif
234
235 typedef typename traits_type::null_node_update_pointer null_node_update_pointer;
236
237 public:
239 typedef _Alloc allocator_type;
240 typedef typename _Alloc::size_type size_type;
241 typedef typename _Alloc::difference_type difference_type;
242
258
259 typedef typename traits_type::access_traits access_traits;
260 typedef typename traits_type::const_iterator point_const_iterator;
261 typedef typename traits_type::iterator point_iterator;
265 typedef typename traits_type::reverse_iterator reverse_iterator;
266 typedef typename traits_type::const_reverse_iterator const_reverse_iterator;
267 typedef typename traits_type::node_const_iterator node_const_iterator;
268 typedef typename traits_type::node_iterator node_iterator;
269 typedef typename traits_type::node_update node_update;
270
272
274
276
277 void
279
282 _GLIBCXX_NODISCARD inline bool
283 empty() const;
284
285 inline size_type
286 size() const;
287
288 inline size_type
289 max_size() const;
290
293
296
299
300 const node_update&
302
305
306 inline mapped_reference
308 {
309#ifdef PB_DS_DATA_TRUE_INDICATOR
310 return insert(std::make_pair(r_key, mapped_type())).first->second;
311#else
312 insert(r_key);
313 return traits_base::s_null_type;
314#endif
315 }
316
317 inline point_iterator
322
323 inline point_iterator
325
328
329 inline point_iterator
331
334
335 void
337
338 inline bool
340
341 inline const_iterator
343
344#ifdef PB_DS_DATA_TRUE_INDICATOR
345 inline iterator
347#endif
348
351
352#ifdef PB_DS_DATA_TRUE_INDICATOR
353 inline reverse_iterator
355#endif
356
357 template<typename Pred>
358 inline size_type
360
361 void
363
364 void
366
367 inline iterator
369
370 inline const_iterator
371 begin() const;
372
373 inline iterator
375
376 inline const_iterator
377 end() const;
378
379 inline reverse_iterator
381
383 rbegin() const;
385 inline reverse_iterator
387
389 rend() const;
390
391 /// Returns a const node_iterator corresponding to the node at the
392 /// root of the tree.
394 node_begin() const;
395
396 /// Returns a node_iterator corresponding to the node at the
397 /// root of the tree.
398 inline node_iterator
400
401 /// Returns a const node_iterator corresponding to a node just
402 /// after a leaf of the tree.
404 node_end() const;
405
406 /// Returns a node_iterator corresponding to a node just
407 /// after a leaf of the tree.
408 inline node_iterator
410
411#ifdef PB_DS_PAT_TRIE_TRACE_
412 void
413 trace() const;
414#endif
415
416 protected:
417 template<typename It>
418 void
420
421 void
423
426
427 private:
428 void
430
431 inline void
433
434 template<typename Node_Update_>
435 inline void
436 apply_update(node_pointer, Node_Update_*);
437
438 bool
440
461
467
470
472 keys_diff_ind(typename access_traits::const_iterator,
473 typename access_traits::const_iterator,
474 typename access_traits::const_iterator,
475 typename access_traits::const_iterator);
476
479
480 void
482
483 void
485
486 inline void
488
489 void
491
492 void
494
495 void
497
498 static inline a_const_iterator
500
501 static inline a_const_iterator
503
504 inline node_pointer
506
507 inline node_pointer
509
510 inline node_pointer
512
513 inline static leaf_const_pointer
515
516 inline static leaf_pointer
518
519 inline static leaf_const_pointer
521
522 inline static leaf_pointer
524
525#ifdef _GLIBCXX_DEBUG
526 void
527 assert_valid(const char*, int) const;
528
529 void
530 assert_iterators(const char*, int) const;
531
532 void
533 assert_reverse_iterators(const char*, int) const;
534
535 static size_type
536 recursive_count_leafs(node_const_pointer, const char*, int);
537#endif
538
539#ifdef PB_DS_PAT_TRIE_TRACE_
540 static void
541 trace_node(node_const_pointer, size_type);
542
543 template<typename Metadata_>
544 static void
545 trace_node_metadata(node_const_pointer, type_to_type<Metadata_>);
546
547 static void
548 trace_node_metadata(node_const_pointer, type_to_type<null_type>);
549#endif
550
553
556 PB_DS_CLASS_C_DEC&, branch_bag&);
557
558 void
560 size_type, branch_bag&);
561
565
568 };
569
570#define PB_DS_ASSERT_NODE_VALID(X) \
571 _GLIBCXX_DEBUG_ONLY(X->assert_valid(this, __FILE__, __LINE__);)
572
573#define PB_DS_RECURSIVE_COUNT_LEAFS(X) \
574 recursive_count_leafs(X, __FILE__, __LINE__)
575
587
588#undef PB_DS_RECURSIVE_COUNT_LEAFS
589#undef PB_DS_ASSERT_NODE_VALID
590#undef PB_DS_CLASS_C_DEC
591#undef PB_DS_CLASS_T_DEC
592#undef PB_DS_PAT_TRIE_NAME
593#undef PB_DS_PAT_TRIE_TRAITS_BASE
594#undef PB_DS_DEBUG_MAP_BASE_C_DEC
595 } // namespace detail
596} // namespace __gnu_pbds
#define __try
#define __throw_exception_again
#define __catch(X)
#define _GLIBCXX_NODISCARD
#define PB_DS_CLASS_C_DEC
#define PB_DS_PAT_TRIE_NAME
Definition pat_trie_.hpp:66
#define PB_DS_PAT_TRIE_TRAITS_BASE
Definition pat_trie_.hpp:80
#define _GLIBCXX_DEBUG_ASSERT(_Condition)
Definition assertions.h:65
constexpr pair< typename __decay_and_strip< _T1 >::__type, typename __decay_and_strip< _T2 >::__type > make_pair(_T1 &&__x, _T2 &&__y)
A convenience wrapper for creating a pair from two objects.
Definition stl_pair.h:1166
GNU extensions for policy-based data structures for public use.
Struct holding two objects of arbitrary type.
Definition stl_pair.h:304
void push_back(const value_type &__x)
Add data to the end of the list.
Definition stl_list.h:1803
iterator begin() noexcept
Definition stl_list.h:1457
void pop_front() noexcept
Removes first element.
Definition stl_list.h:1786
A standard container with linear time access to elements, and fixed time insertion/deletion at any po...
Definition stl_list.h:1026
const_iterator begin() const
Definition pat_trie_.hpp:53
void rec_join_prep(leaf_const_pointer, inode_const_pointer, branch_bag &)
node_pointer rec_split(node_pointer, a_const_iterator, a_const_iterator, pat_trie_map< Key, Mapped, Node_And_It_Traits, _Alloc > &, branch_bag &)
void apply_update(node_pointer, null_node_update_pointer)
Definition pat_trie_.hpp:47
void erase_fixup(inode_pointer)
Definition pat_trie_.hpp:72
point_const_iterator upper_bound(key_const_reference) const
node_pointer recursive_copy_node(node_const_pointer)
traits_type::const_reverse_iterator const_reverse_iterator
bool erase(key_const_reference)
Definition pat_trie_.hpp:47
static a_const_iterator pref_begin(node_const_pointer)
static inode_allocator s_inode_allocator
void rec_join_prep(inode_const_pointer, leaf_const_pointer, branch_bag &)
node_pointer upper_bound_imp(key_const_reference)
node_pointer rec_join(inode_pointer, leaf_pointer, size_type, branch_bag &)
const_iterator end() const
Definition pat_trie_.hpp:65
const_iterator erase(const_iterator)
node_pointer find_imp(key_const_reference)
Definition pat_trie_.hpp:96
static leaf_pointer leftmost_descendant(node_pointer)
static a_const_iterator pref_end(node_const_pointer)
node_pointer lower_bound_imp(key_const_reference)
node_pointer rec_join(inode_pointer, inode_pointer, branch_bag &)
const node_update & get_node_update() const
Definition pat_trie_.hpp:65
static leaf_const_pointer rightmost_descendant(node_const_pointer)
std::pair< point_iterator, bool > insert(const_reference)
traits_type::null_node_update_pointer null_node_update_pointer
access_traits & get_access_traits()
Definition pat_trie_.hpp:47
inode_pointer insert_branch(node_pointer, node_pointer, branch_bag &)
void rec_join_prep(inode_const_pointer, inode_const_pointer, branch_bag &)
size_type keys_diff_ind(typename access_traits::const_iterator, typename access_traits::const_iterator, typename access_traits::const_iterator, typename access_traits::const_iterator)
void update_min_max_for_inserted_leaf(leaf_pointer)
const access_traits & get_access_traits() const
Definition pat_trie_.hpp:53
const_reverse_iterator rbegin() const
Definition pat_trie_.hpp:71
leaf_pointer split_prep(key_const_reference, pat_trie_map< Key, Mapped, Node_And_It_Traits, _Alloc > &, branch_bag &)
Definition pat_trie_.hpp:84
void actual_erase_leaf(leaf_pointer)
types_traits< Key, Mapped, _Alloc, false > traits_base
point_const_iterator find(key_const_reference) const
Definition pat_trie_.hpp:71
__rebind_l::allocator_type leaf_allocator
void rec_join_prep(leaf_const_pointer, leaf_const_pointer, branch_bag &)
point_const_iterator lower_bound(key_const_reference) const
node_pointer rec_join(node_pointer, node_pointer, size_type, branch_bag &)
node_const_iterator node_begin() const
Returns a const node_iterator corresponding to the node at the root of the tree.
const_reverse_iterator rend() const
Definition pat_trie_.hpp:97
node_pointer rec_join(leaf_pointer, leaf_pointer, branch_bag &)
const_reverse_iterator erase(const_reverse_iterator)
static leaf_const_pointer leftmost_descendant(node_const_pointer)
void swap(pat_trie_map< Key, Mapped, Node_And_It_Traits, _Alloc > &)
void update_min_max_for_erased_leaf(leaf_pointer)
point_iterator upper_bound(key_const_reference)
reverse_iterator erase(reverse_iterator)
void apply_update(node_pointer, Node_Update_ *)
Definition pat_trie_.hpp:54
traits_base::key_reference key_reference
traits_base::mapped_const_reference mapped_const_reference
mapped_reference operator[](key_const_reference r_key)
node_const_iterator node_end() const
Returns a const node_iterator corresponding to a node just after a leaf of the tree.
node_iterator node_begin()
Returns a node_iterator corresponding to the node at the root of the tree.
bool join_prep(pat_trie_map< Key, Mapped, Node_And_It_Traits, _Alloc > &, branch_bag &)
Definition pat_trie_.hpp:74
void value_swap(pat_trie_map< Key, Mapped, Node_And_It_Traits, _Alloc > &)
void join(pat_trie_map< Key, Mapped, Node_And_It_Traits, _Alloc > &)
Definition pat_trie_.hpp:47
node_iterator node_end()
Returns a node_iterator corresponding to a node just after a leaf of the tree.
point_iterator find(key_const_reference)
Definition pat_trie_.hpp:47
void rec_join_prep(node_const_pointer, node_const_pointer, branch_bag &)
void split_insert_branch(size_type, a_const_iterator, inode_iterator, size_type, branch_bag &)
node_pointer rec_join(leaf_pointer, inode_pointer, size_type, branch_bag &)
static leaf_pointer rightmost_descendant(node_pointer)
void split(key_const_reference, pat_trie_map< Key, Mapped, Node_And_It_Traits, _Alloc > &)
Definition pat_trie_.hpp:47
point_iterator lower_bound(key_const_reference)
static leaf_allocator s_leaf_allocator
std::list< __inp, __rebind_inp > bag_type
rebind_traits< _Alloc, __inp >::allocator_type __rebind_inp
Base type for PATRICIA trees.
Consistent API for accessing allocator-related types.