Coverage Report

Created: 2026-05-30 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/sentencepiece/third_party/absl/container/btree_set.h
Line
Count
Source
1
// Copyright 2018 The Abseil Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
//
15
// -----------------------------------------------------------------------------
16
// File: btree_set.h
17
// -----------------------------------------------------------------------------
18
//
19
// This header file defines B-tree sets: sorted associative containers of
20
// values.
21
//
22
//     * `absl::btree_set<>`
23
//     * `absl::btree_multiset<>`
24
//
25
// These B-tree types are similar to the corresponding types in the STL
26
// (`std::set` and `std::multiset`) and generally conform to the STL interfaces
27
// of those types. However, because they are implemented using B-trees, they
28
// are more efficient in most situations.
29
//
30
// Unlike `std::set` and `std::multiset`, which are commonly implemented using
31
// red-black tree nodes, B-tree sets use more generic B-tree nodes able to hold
32
// multiple values per node. Holding multiple values per node often makes
33
// B-tree sets perform better than their `std::set` counterparts, because
34
// multiple entries can be checked within the same cache hit.
35
//
36
// However, these types should not be considered drop-in replacements for
37
// `std::set` and `std::multiset` as there are some API differences, which are
38
// noted in this header file. The most consequential differences with respect to
39
// migrating to b-tree from the STL types are listed in the next paragraph.
40
// Other API differences are minor.
41
//
42
// Importantly, insertions and deletions may invalidate outstanding iterators,
43
// pointers, and references to elements. Such invalidations are typically only
44
// an issue if insertion and deletion operations are interleaved with the use of
45
// more than one iterator, pointer, or reference simultaneously. For this
46
// reason, `insert()`, `erase()`, and `extract_and_get_next()` return a valid
47
// iterator at the current position.
48
//
49
// There are other API differences: first, btree iterators can be subtracted,
50
// and this is faster than using `std::distance`. Additionally, btree
51
// iterators can be advanced via `operator+=` and `operator-=`, which is faster
52
// than using `std::advance`.
53
//
54
// B-tree sets are not exception-safe.
55
56
#ifndef ABSL_CONTAINER_BTREE_SET_H_
57
#define ABSL_CONTAINER_BTREE_SET_H_
58
59
#include <functional>
60
#include <memory>
61
#include <type_traits>
62
#include <utility>
63
64
#include "absl/base/attributes.h"
65
#include "absl/container/internal/btree.h"  // IWYU pragma: export
66
#include "absl/container/internal/btree_container.h"  // IWYU pragma: export
67
#include "absl/container/internal/common.h"
68
69
namespace absl {
70
ABSL_NAMESPACE_BEGIN
71
72
namespace container_internal {
73
74
template <typename Key>
75
struct set_slot_policy;
76
77
template <typename Key, typename...Params>
78
struct set_params_impl;
79
80
template <typename Key>
81
struct btree_set_defaults {
82
  using Compare = std::less<Key>;
83
  using Alloc = std::allocator<Key>;
84
  using TargetNodeSize = std::integral_constant<int, 256>;
85
  using IsMulti = std::false_type;
86
};
87
88
template <typename Key, typename Compare, typename Alloc, int TargetNodeSize,
89
          bool IsMulti>
90
using set_params = typename ApplyWithoutDefaultSuffix<
91
    set_params_impl,
92
    TypeList<void, typename btree_set_defaults<Key>::Compare,
93
             typename btree_set_defaults<Key>::Alloc,
94
             typename btree_set_defaults<Key>::TargetNodeSize,
95
             typename btree_set_defaults<Key>::IsMulti>,
96
    TypeList<Key, Compare, Alloc, std::integral_constant<int, TargetNodeSize>,
97
             std::integral_constant<bool, IsMulti>>>::type;
98
99
}  // namespace container_internal
100
101
// absl::btree_set<>
102
//
103
// An `absl::btree_set<K>` is an ordered associative container of unique key
104
// values designed to be a more efficient replacement for `std::set` (in most
105
// cases).
106
//
107
// Keys are sorted using an (optional) comparison function, which defaults to
108
// `std::less<K>`.
109
//
110
// An `absl::btree_set<K>` uses a default allocator of `std::allocator<K>` to
111
// allocate (and deallocate) nodes, and construct and destruct values within
112
// those nodes. You may instead specify a custom allocator `A` (which in turn
113
// requires specifying a custom comparator `C`) as in
114
// `absl::btree_set<K, C, A>`.
115
//
116
template <typename Key, typename Compare = std::less<Key>,
117
          typename Alloc = std::allocator<Key>>
118
class ABSL_ATTRIBUTE_OWNER btree_set
119
    : public container_internal::btree_set_container<
120
          container_internal::btree<container_internal::set_params<
121
              Key, Compare, Alloc, /*TargetNodeSize=*/256,
122
              /*IsMulti=*/false>>> {
123
  using Base = typename btree_set::btree_set_container;
124
125
 public:
126
  // Constructors and Assignment Operators
127
  //
128
  // A `btree_set` supports the same overload set as `std::set`
129
  // for construction and assignment:
130
  //
131
  // * Default constructor
132
  //
133
  //   absl::btree_set<std::string> set1;
134
  //
135
  // * Initializer List constructor
136
  //
137
  //   absl::btree_set<std::string> set2 =
138
  //       {{"huey"}, {"dewey"}, {"louie"},};
139
  //
140
  // * Copy constructor
141
  //
142
  //   absl::btree_set<std::string> set3(set2);
143
  //
144
  // * Copy assignment operator
145
  //
146
  //   absl::btree_set<std::string> set4;
147
  //   set4 = set3;
148
  //
149
  // * Move constructor
150
  //
151
  //   // Move is guaranteed efficient
152
  //   absl::btree_set<std::string> set5(std::move(set4));
153
  //
154
  // * Move assignment operator
155
  //
156
  //   // May be efficient if allocators are compatible
157
  //   absl::btree_set<std::string> set6;
158
  //   set6 = std::move(set5);
159
  //
160
  // * Range constructor
161
  //
162
  //   std::vector<std::string> v = {"a", "b"};
163
  //   absl::btree_set<std::string> set7(v.begin(), v.end());
164
361k
  btree_set() {}
absl::lts_20260107::btree_set<sentencepiece::bpe::Trainer::Symbol*, std::__1::less<sentencepiece::bpe::Trainer::Symbol*>, std::__1::allocator<sentencepiece::bpe::Trainer::Symbol*> >::btree_set()
Line
Count
Source
164
1.81k
  btree_set() {}
absl::lts_20260107::btree_set<unsigned long, std::__1::less<unsigned long>, std::__1::allocator<unsigned long> >::btree_set()
Line
Count
Source
164
359k
  btree_set() {}
165
  using Base::Base;
166
167
  // btree_set::begin()
168
  //
169
  // Returns an iterator to the beginning of the `btree_set`.
170
  using Base::begin;
171
172
  // btree_set::cbegin()
173
  //
174
  // Returns a const iterator to the beginning of the `btree_set`.
175
  using Base::cbegin;
176
177
  // btree_set::end()
178
  //
179
  // Returns an iterator to the end of the `btree_set`.
180
  using Base::end;
181
182
  // btree_set::cend()
183
  //
184
  // Returns a const iterator to the end of the `btree_set`.
185
  using Base::cend;
186
187
  // btree_set::empty()
188
  //
189
  // Returns whether or not the `btree_set` is empty.
190
  using Base::empty;
191
192
  // btree_set::max_size()
193
  //
194
  // Returns the largest theoretical possible number of elements within a
195
  // `btree_set` under current memory constraints. This value can be thought
196
  // of as the largest value of `std::distance(begin(), end())` for a
197
  // `btree_set<Key>`.
198
  using Base::max_size;
199
200
  // btree_set::size()
201
  //
202
  // Returns the number of elements currently within the `btree_set`.
203
  using Base::size;
204
205
  // btree_set::clear()
206
  //
207
  // Removes all elements from the `btree_set`. Invalidates any references,
208
  // pointers, or iterators referring to contained elements.
209
  using Base::clear;
210
211
  // btree_set::erase()
212
  //
213
  // Erases elements within the `btree_set`. Overloads are listed below.
214
  //
215
  // iterator erase(iterator position):
216
  // iterator erase(const_iterator position):
217
  //
218
  //   Erases the element at `position` of the `btree_set`, returning
219
  //   the iterator pointing to the element after the one that was erased
220
  //   (or end() if none exists).
221
  //
222
  // iterator erase(const_iterator first, const_iterator last):
223
  //
224
  //   Erases the elements in the open interval [`first`, `last`), returning
225
  //   the iterator pointing to the element after the interval that was erased
226
  //   (or end() if none exists).
227
  //
228
  // template <typename K> size_type erase(const K& key):
229
  //
230
  //   Erases the element with the matching key, if it exists, returning the
231
  //   number of elements erased (0 or 1).
232
  using Base::erase;
233
234
  // btree_set::insert()
235
  //
236
  // Inserts an element of the specified value into the `btree_set`,
237
  // returning an iterator pointing to the newly inserted element, provided that
238
  // an element with the given key does not already exist. If an insertion
239
  // occurs, any references, pointers, or iterators are invalidated.
240
  // Overloads are listed below.
241
  //
242
  // std::pair<iterator,bool> insert(const value_type& value):
243
  //
244
  //   Inserts a value into the `btree_set`. Returns a pair consisting of an
245
  //   iterator to the inserted element (or to the element that prevented the
246
  //   insertion) and a bool denoting whether the insertion took place.
247
  //
248
  // std::pair<iterator,bool> insert(value_type&& value):
249
  //
250
  //   Inserts a moveable value into the `btree_set`. Returns a pair
251
  //   consisting of an iterator to the inserted element (or to the element that
252
  //   prevented the insertion) and a bool denoting whether the insertion took
253
  //   place.
254
  //
255
  // iterator insert(const_iterator hint, const value_type& value):
256
  // iterator insert(const_iterator hint, value_type&& value):
257
  //
258
  //   Inserts a value, using the position of `hint` as a non-binding suggestion
259
  //   for where to begin the insertion search. Returns an iterator to the
260
  //   inserted element, or to the existing element that prevented the
261
  //   insertion.
262
  //
263
  // void insert(InputIterator first, InputIterator last):
264
  //
265
  //   Inserts a range of values [`first`, `last`).
266
  //
267
  // void insert(std::initializer_list<init_type> ilist):
268
  //
269
  //   Inserts the elements within the initializer list `ilist`.
270
  using Base::insert;
271
272
  // btree_set::emplace()
273
  //
274
  // Inserts an element of the specified value by constructing it in-place
275
  // within the `btree_set`, provided that no element with the given key
276
  // already exists.
277
  //
278
  // The element may be constructed even if there already is an element with the
279
  // key in the container, in which case the newly constructed element will be
280
  // destroyed immediately.
281
  //
282
  // If an insertion occurs, any references, pointers, or iterators are
283
  // invalidated.
284
  using Base::emplace;
285
286
  // btree_set::emplace_hint()
287
  //
288
  // Inserts an element of the specified value by constructing it in-place
289
  // within the `btree_set`, using the position of `hint` as a non-binding
290
  // suggestion for where to begin the insertion search, and only inserts
291
  // provided that no element with the given key already exists.
292
  //
293
  // The element may be constructed even if there already is an element with the
294
  // key in the container, in which case the newly constructed element will be
295
  // destroyed immediately.
296
  //
297
  // If an insertion occurs, any references, pointers, or iterators are
298
  // invalidated.
299
  using Base::emplace_hint;
300
301
  // btree_set::extract()
302
  //
303
  // Extracts the indicated element, erasing it in the process, and returns it
304
  // as a C++17-compatible node handle. Any references, pointers, or iterators
305
  // are invalidated. Overloads are listed below.
306
  //
307
  // node_type extract(const_iterator position):
308
  //
309
  //   Extracts the element at the indicated position and returns a node handle
310
  //   owning that extracted data.
311
  //
312
  // template <typename K> node_type extract(const K& k):
313
  //
314
  //   Extracts the element with the key matching the passed key value and
315
  //   returns a node handle owning that extracted data. If the `btree_set`
316
  //   does not contain an element with a matching key, this function returns an
317
  //   empty node handle.
318
  //
319
  // NOTE: In this context, `node_type` refers to the C++17 concept of a
320
  // move-only type that owns and provides access to the elements in associative
321
  // containers (https://en.cppreference.com/w/cpp/container/node_handle).
322
  // It does NOT refer to the data layout of the underlying btree.
323
  using Base::extract;
324
325
  // btree_set::extract_and_get_next()
326
  //
327
  // Extracts the indicated element, erasing it in the process, and returns it
328
  // as a C++17-compatible node handle along with an iterator to the next
329
  // element.
330
  //
331
  // extract_and_get_next_return_type extract_and_get_next(
332
  //     const_iterator position):
333
  //
334
  //   Extracts the element at the indicated position, returns a struct
335
  //   containing a member named `node`: a node handle owning that extracted
336
  //   data and a member named `next`: an iterator pointing to the next element
337
  //   in the btree.
338
  using Base::extract_and_get_next;
339
340
  // btree_set::merge()
341
  //
342
  // Extracts elements from a given `source` btree_set into this
343
  // `btree_set`. If the destination `btree_set` already contains an
344
  // element with an equivalent key, that element is not extracted.
345
  using Base::merge;
346
347
  // btree_set::swap(btree_set& other)
348
  //
349
  // Exchanges the contents of this `btree_set` with those of the `other`
350
  // btree_set, avoiding invocation of any move, copy, or swap operations on
351
  // individual elements.
352
  //
353
  // All iterators and references on the `btree_set` remain valid, excepting
354
  // for the past-the-end iterator, which is invalidated.
355
  using Base::swap;
356
357
  // btree_set::contains()
358
  //
359
  // template <typename K> bool contains(const K& key) const:
360
  //
361
  // Determines whether an element comparing equal to the given `key` exists
362
  // within the `btree_set`, returning `true` if so or `false` otherwise.
363
  //
364
  // Supports heterogeneous lookup, provided that the set has a compatible
365
  // heterogeneous comparator.
366
  using Base::contains;
367
368
  // btree_set::count()
369
  //
370
  // template <typename K> size_type count(const K& key) const:
371
  //
372
  // Returns the number of elements comparing equal to the given `key` within
373
  // the `btree_set`. Note that this function will return either `1` or `0`
374
  // since duplicate elements are not allowed within a `btree_set`.
375
  //
376
  // Supports heterogeneous lookup, provided that the set has a compatible
377
  // heterogeneous comparator.
378
  using Base::count;
379
380
  // btree_set::equal_range()
381
  //
382
  // Returns a closed range [first, last], defined by a `std::pair` of two
383
  // iterators, containing all elements with the passed key in the
384
  // `btree_set`.
385
  using Base::equal_range;
386
387
  // btree_set::find()
388
  //
389
  // template <typename K> iterator find(const K& key):
390
  // template <typename K> const_iterator find(const K& key) const:
391
  //
392
  // Finds an element with the passed `key` within the `btree_set`.
393
  //
394
  // Supports heterogeneous lookup, provided that the set has a compatible
395
  // heterogeneous comparator.
396
  using Base::find;
397
398
  // btree_set::lower_bound()
399
  //
400
  // template <typename K> iterator lower_bound(const K& key):
401
  // template <typename K> const_iterator lower_bound(const K& key) const:
402
  //
403
  // Finds the first element that is not less than `key` within the `btree_set`.
404
  //
405
  // Supports heterogeneous lookup, provided that the set has a compatible
406
  // heterogeneous comparator.
407
  using Base::lower_bound;
408
409
  // btree_set::upper_bound()
410
  //
411
  // template <typename K> iterator upper_bound(const K& key):
412
  // template <typename K> const_iterator upper_bound(const K& key) const:
413
  //
414
  // Finds the first element that is greater than `key` within the `btree_set`.
415
  //
416
  // Supports heterogeneous lookup, provided that the set has a compatible
417
  // heterogeneous comparator.
418
  using Base::upper_bound;
419
420
  // btree_set::get_allocator()
421
  //
422
  // Returns the allocator function associated with this `btree_set`.
423
  using Base::get_allocator;
424
425
  // btree_set::key_comp();
426
  //
427
  // Returns the key comparator associated with this `btree_set`.
428
  using Base::key_comp;
429
430
  // btree_set::value_comp();
431
  //
432
  // Returns the value comparator associated with this `btree_set`. The keys to
433
  // sort the elements are the values themselves, therefore `value_comp` and its
434
  // sibling member function `key_comp` are equivalent.
435
  using Base::value_comp;
436
};
437
438
// absl::swap(absl::btree_set<>, absl::btree_set<>)
439
//
440
// Swaps the contents of two `absl::btree_set` containers.
441
template <typename K, typename C, typename A>
442
void swap(btree_set<K, C, A> &x, btree_set<K, C, A> &y) {
443
  return x.swap(y);
444
}
445
446
// absl::erase_if(absl::btree_set<>, Pred)
447
//
448
// Erases all elements that satisfy the predicate pred from the container.
449
// Returns the number of erased elements.
450
template <typename K, typename C, typename A, typename Pred>
451
typename btree_set<K, C, A>::size_type erase_if(btree_set<K, C, A> &set,
452
                                                Pred pred) {
453
  return container_internal::btree_access::erase_if(set, std::move(pred));
454
}
455
456
// absl::btree_multiset<>
457
//
458
// An `absl::btree_multiset<K>` is an ordered associative container of
459
// keys and associated values designed to be a more efficient replacement
460
// for `std::multiset` (in most cases). Unlike `absl::btree_set`, a B-tree
461
// multiset allows equivalent elements.
462
//
463
// Keys are sorted using an (optional) comparison function, which defaults to
464
// `std::less<K>`.
465
//
466
// An `absl::btree_multiset<K>` uses a default allocator of `std::allocator<K>`
467
// to allocate (and deallocate) nodes, and construct and destruct values within
468
// those nodes. You may instead specify a custom allocator `A` (which in turn
469
// requires specifying a custom comparator `C`) as in
470
// `absl::btree_multiset<K, C, A>`.
471
//
472
template <typename Key, typename Compare = std::less<Key>,
473
          typename Alloc = std::allocator<Key>>
474
class ABSL_ATTRIBUTE_OWNER btree_multiset
475
    : public container_internal::btree_multiset_container<
476
          container_internal::btree<container_internal::set_params<
477
              Key, Compare, Alloc, /*TargetNodeSize=*/256,
478
              /*IsMulti=*/true>>> {
479
  using Base = typename btree_multiset::btree_multiset_container;
480
481
 public:
482
  // Constructors and Assignment Operators
483
  //
484
  // A `btree_multiset` supports the same overload set as `std::set`
485
  // for construction and assignment:
486
  //
487
  // * Default constructor
488
  //
489
  //   absl::btree_multiset<std::string> set1;
490
  //
491
  // * Initializer List constructor
492
  //
493
  //   absl::btree_multiset<std::string> set2 =
494
  //       {{"huey"}, {"dewey"}, {"louie"},};
495
  //
496
  // * Copy constructor
497
  //
498
  //   absl::btree_multiset<std::string> set3(set2);
499
  //
500
  // * Copy assignment operator
501
  //
502
  //   absl::btree_multiset<std::string> set4;
503
  //   set4 = set3;
504
  //
505
  // * Move constructor
506
  //
507
  //   // Move is guaranteed efficient
508
  //   absl::btree_multiset<std::string> set5(std::move(set4));
509
  //
510
  // * Move assignment operator
511
  //
512
  //   // May be efficient if allocators are compatible
513
  //   absl::btree_multiset<std::string> set6;
514
  //   set6 = std::move(set5);
515
  //
516
  // * Range constructor
517
  //
518
  //   std::vector<std::string> v = {"a", "b"};
519
  //   absl::btree_multiset<std::string> set7(v.begin(), v.end());
520
  btree_multiset() {}
521
  using Base::Base;
522
523
  // btree_multiset::begin()
524
  //
525
  // Returns an iterator to the beginning of the `btree_multiset`.
526
  using Base::begin;
527
528
  // btree_multiset::cbegin()
529
  //
530
  // Returns a const iterator to the beginning of the `btree_multiset`.
531
  using Base::cbegin;
532
533
  // btree_multiset::end()
534
  //
535
  // Returns an iterator to the end of the `btree_multiset`.
536
  using Base::end;
537
538
  // btree_multiset::cend()
539
  //
540
  // Returns a const iterator to the end of the `btree_multiset`.
541
  using Base::cend;
542
543
  // btree_multiset::empty()
544
  //
545
  // Returns whether or not the `btree_multiset` is empty.
546
  using Base::empty;
547
548
  // btree_multiset::max_size()
549
  //
550
  // Returns the largest theoretical possible number of elements within a
551
  // `btree_multiset` under current memory constraints. This value can be
552
  // thought of as the largest value of `std::distance(begin(), end())` for a
553
  // `btree_multiset<Key>`.
554
  using Base::max_size;
555
556
  // btree_multiset::size()
557
  //
558
  // Returns the number of elements currently within the `btree_multiset`.
559
  using Base::size;
560
561
  // btree_multiset::clear()
562
  //
563
  // Removes all elements from the `btree_multiset`. Invalidates any references,
564
  // pointers, or iterators referring to contained elements.
565
  using Base::clear;
566
567
  // btree_multiset::erase()
568
  //
569
  // Erases elements within the `btree_multiset`. Overloads are listed below.
570
  //
571
  // iterator erase(iterator position):
572
  // iterator erase(const_iterator position):
573
  //
574
  //   Erases the element at `position` of the `btree_multiset`, returning
575
  //   the iterator pointing to the element after the one that was erased
576
  //   (or end() if none exists).
577
  //
578
  // iterator erase(const_iterator first, const_iterator last):
579
  //
580
  //   Erases the elements in the open interval [`first`, `last`), returning
581
  //   the iterator pointing to the element after the interval that was erased
582
  //   (or end() if none exists).
583
  //
584
  // template <typename K> size_type erase(const K& key):
585
  //
586
  //   Erases the elements matching the key, if any exist, returning the
587
  //   number of elements erased.
588
  using Base::erase;
589
590
  // btree_multiset::insert()
591
  //
592
  // Inserts an element of the specified value into the `btree_multiset`,
593
  // returning an iterator pointing to the newly inserted element.
594
  // Any references, pointers, or iterators are invalidated.  Overloads are
595
  // listed below.
596
  //
597
  // iterator insert(const value_type& value):
598
  //
599
  //   Inserts a value into the `btree_multiset`, returning an iterator to the
600
  //   inserted element.
601
  //
602
  // iterator insert(value_type&& value):
603
  //
604
  //   Inserts a moveable value into the `btree_multiset`, returning an iterator
605
  //   to the inserted element.
606
  //
607
  // iterator insert(const_iterator hint, const value_type& value):
608
  // iterator insert(const_iterator hint, value_type&& value):
609
  //
610
  //   Inserts a value, using the position of `hint` as a non-binding suggestion
611
  //   for where to begin the insertion search. Returns an iterator to the
612
  //   inserted element.
613
  //
614
  // void insert(InputIterator first, InputIterator last):
615
  //
616
  //   Inserts a range of values [`first`, `last`).
617
  //
618
  // void insert(std::initializer_list<init_type> ilist):
619
  //
620
  //   Inserts the elements within the initializer list `ilist`.
621
  using Base::insert;
622
623
  // btree_multiset::emplace()
624
  //
625
  // Inserts an element of the specified value by constructing it in-place
626
  // within the `btree_multiset`. Any references, pointers, or iterators are
627
  // invalidated.
628
  using Base::emplace;
629
630
  // btree_multiset::emplace_hint()
631
  //
632
  // Inserts an element of the specified value by constructing it in-place
633
  // within the `btree_multiset`, using the position of `hint` as a non-binding
634
  // suggestion for where to begin the insertion search.
635
  //
636
  // Any references, pointers, or iterators are invalidated.
637
  using Base::emplace_hint;
638
639
  // btree_multiset::extract()
640
  //
641
  // Extracts the indicated element, erasing it in the process, and returns it
642
  // as a C++17-compatible node handle. Overloads are listed below.
643
  //
644
  // node_type extract(const_iterator position):
645
  //
646
  //   Extracts the element at the indicated position and returns a node handle
647
  //   owning that extracted data.
648
  //
649
  // template <typename K> node_type extract(const K& k):
650
  //
651
  //   Extracts the element with the key matching the passed key value and
652
  //   returns a node handle owning that extracted data. If the `btree_multiset`
653
  //   does not contain an element with a matching key, this function returns an
654
  //   empty node handle.
655
  //
656
  // NOTE: In this context, `node_type` refers to the C++17 concept of a
657
  // move-only type that owns and provides access to the elements in associative
658
  // containers (https://en.cppreference.com/w/cpp/container/node_handle).
659
  // It does NOT refer to the data layout of the underlying btree.
660
  using Base::extract;
661
662
  // btree_multiset::extract_and_get_next()
663
  //
664
  // Extracts the indicated element, erasing it in the process, and returns it
665
  // as a C++17-compatible node handle along with an iterator to the next
666
  // element.
667
  //
668
  // extract_and_get_next_return_type extract_and_get_next(
669
  //     const_iterator position):
670
  //
671
  //   Extracts the element at the indicated position, returns a struct
672
  //   containing a member named `node`: a node handle owning that extracted
673
  //   data and a member named `next`: an iterator pointing to the next element
674
  //   in the btree.
675
  using Base::extract_and_get_next;
676
677
  // btree_multiset::merge()
678
  //
679
  // Extracts all elements from a given `source` btree_multiset into this
680
  // `btree_multiset`.
681
  using Base::merge;
682
683
  // btree_multiset::swap(btree_multiset& other)
684
  //
685
  // Exchanges the contents of this `btree_multiset` with those of the `other`
686
  // btree_multiset, avoiding invocation of any move, copy, or swap operations
687
  // on individual elements.
688
  //
689
  // All iterators and references on the `btree_multiset` remain valid,
690
  // excepting for the past-the-end iterator, which is invalidated.
691
  using Base::swap;
692
693
  // btree_multiset::contains()
694
  //
695
  // template <typename K> bool contains(const K& key) const:
696
  //
697
  // Determines whether an element comparing equal to the given `key` exists
698
  // within the `btree_multiset`, returning `true` if so or `false` otherwise.
699
  //
700
  // Supports heterogeneous lookup, provided that the set has a compatible
701
  // heterogeneous comparator.
702
  using Base::contains;
703
704
  // btree_multiset::count()
705
  //
706
  // template <typename K> size_type count(const K& key) const:
707
  //
708
  // Returns the number of elements comparing equal to the given `key` within
709
  // the `btree_multiset`.
710
  //
711
  // Supports heterogeneous lookup, provided that the set has a compatible
712
  // heterogeneous comparator.
713
  using Base::count;
714
715
  // btree_multiset::equal_range()
716
  //
717
  // Returns a closed range [first, last], defined by a `std::pair` of two
718
  // iterators, containing all elements with the passed key in the
719
  // `btree_multiset`.
720
  using Base::equal_range;
721
722
  // btree_multiset::find()
723
  //
724
  // template <typename K> iterator find(const K& key):
725
  // template <typename K> const_iterator find(const K& key) const:
726
  //
727
  // Finds an element with the passed `key` within the `btree_multiset`.
728
  //
729
  // Supports heterogeneous lookup, provided that the set has a compatible
730
  // heterogeneous comparator.
731
  using Base::find;
732
733
  // btree_multiset::lower_bound()
734
  //
735
  // template <typename K> iterator lower_bound(const K& key):
736
  // template <typename K> const_iterator lower_bound(const K& key) const:
737
  //
738
  // Finds the first element that is not less than `key` within the
739
  // `btree_multiset`.
740
  //
741
  // Supports heterogeneous lookup, provided that the set has a compatible
742
  // heterogeneous comparator.
743
  using Base::lower_bound;
744
745
  // btree_multiset::upper_bound()
746
  //
747
  // template <typename K> iterator upper_bound(const K& key):
748
  // template <typename K> const_iterator upper_bound(const K& key) const:
749
  //
750
  // Finds the first element that is greater than `key` within the
751
  // `btree_multiset`.
752
  //
753
  // Supports heterogeneous lookup, provided that the set has a compatible
754
  // heterogeneous comparator.
755
  using Base::upper_bound;
756
757
  // btree_multiset::get_allocator()
758
  //
759
  // Returns the allocator function associated with this `btree_multiset`.
760
  using Base::get_allocator;
761
762
  // btree_multiset::key_comp();
763
  //
764
  // Returns the key comparator associated with this `btree_multiset`.
765
  using Base::key_comp;
766
767
  // btree_multiset::value_comp();
768
  //
769
  // Returns the value comparator associated with this `btree_multiset`. The
770
  // keys to sort the elements are the values themselves, therefore `value_comp`
771
  // and its sibling member function `key_comp` are equivalent.
772
  using Base::value_comp;
773
};
774
775
// absl::swap(absl::btree_multiset<>, absl::btree_multiset<>)
776
//
777
// Swaps the contents of two `absl::btree_multiset` containers.
778
template <typename K, typename C, typename A>
779
void swap(btree_multiset<K, C, A> &x, btree_multiset<K, C, A> &y) {
780
  return x.swap(y);
781
}
782
783
// absl::erase_if(absl::btree_multiset<>, Pred)
784
//
785
// Erases all elements that satisfy the predicate pred from the container.
786
// Returns the number of erased elements.
787
template <typename K, typename C, typename A, typename Pred>
788
typename btree_multiset<K, C, A>::size_type erase_if(
789
   btree_multiset<K, C, A> & set, Pred pred) {
790
  return container_internal::btree_access::erase_if(set, std::move(pred));
791
}
792
793
namespace container_internal {
794
795
// This type implements the necessary functions from the
796
// absl::container_internal::slot_type interface for btree_(multi)set.
797
template <typename Key>
798
struct set_slot_policy {
799
  using slot_type = Key;
800
  using value_type = Key;
801
  using mutable_value_type = Key;
802
803
53.6M
  static value_type &element(slot_type *slot) { return *slot; }
absl::lts_20260107::container_internal::set_slot_policy<unsigned long>::element(unsigned long*)
Line
Count
Source
803
32.0M
  static value_type &element(slot_type *slot) { return *slot; }
absl::lts_20260107::container_internal::set_slot_policy<sentencepiece::bpe::Trainer::Symbol*>::element(sentencepiece::bpe::Trainer::Symbol**)
Line
Count
Source
803
21.6M
  static value_type &element(slot_type *slot) { return *slot; }
804
  static const value_type &element(const slot_type *slot) { return *slot; }
805
806
  template <typename Alloc, class... Args>
807
2.89M
  static void construct(Alloc *alloc, slot_type *slot, Args &&...args) {
808
2.89M
    absl::allocator_traits<Alloc>::construct(*alloc, slot,
809
2.89M
                                             std::forward<Args>(args)...);
810
2.89M
  }
void absl::lts_20260107::container_internal::set_slot_policy<sentencepiece::bpe::Trainer::Symbol*>::construct<std::__1::allocator<sentencepiece::bpe::Trainer::Symbol*>, sentencepiece::bpe::Trainer::Symbol* const&>(std::__1::allocator<sentencepiece::bpe::Trainer::Symbol*>*, sentencepiece::bpe::Trainer::Symbol**, sentencepiece::bpe::Trainer::Symbol* const&)
Line
Count
Source
807
323k
  static void construct(Alloc *alloc, slot_type *slot, Args &&...args) {
808
323k
    absl::allocator_traits<Alloc>::construct(*alloc, slot,
809
323k
                                             std::forward<Args>(args)...);
810
323k
  }
void absl::lts_20260107::container_internal::set_slot_policy<unsigned long>::construct<std::__1::allocator<unsigned long>, unsigned long>(std::__1::allocator<unsigned long>*, unsigned long*, unsigned long&&)
Line
Count
Source
807
2.46M
  static void construct(Alloc *alloc, slot_type *slot, Args &&...args) {
808
2.46M
    absl::allocator_traits<Alloc>::construct(*alloc, slot,
809
2.46M
                                             std::forward<Args>(args)...);
810
2.46M
  }
void absl::lts_20260107::container_internal::set_slot_policy<sentencepiece::bpe::Trainer::Symbol*>::construct<std::__1::allocator<sentencepiece::bpe::Trainer::Symbol*>, sentencepiece::bpe::Trainer::Symbol*&>(std::__1::allocator<sentencepiece::bpe::Trainer::Symbol*>*, sentencepiece::bpe::Trainer::Symbol**, sentencepiece::bpe::Trainer::Symbol*&)
Line
Count
Source
807
101k
  static void construct(Alloc *alloc, slot_type *slot, Args &&...args) {
808
101k
    absl::allocator_traits<Alloc>::construct(*alloc, slot,
809
101k
                                             std::forward<Args>(args)...);
810
101k
  }
811
812
  template <typename Alloc>
813
84.2k
  static void construct(Alloc *alloc, slot_type *slot, slot_type *other) {
814
84.2k
    absl::allocator_traits<Alloc>::construct(*alloc, slot, std::move(*other));
815
84.2k
  }
void absl::lts_20260107::container_internal::set_slot_policy<unsigned long>::construct<std::__1::allocator<unsigned long> >(std::__1::allocator<unsigned long>*, unsigned long*, unsigned long*)
Line
Count
Source
813
70.2k
  static void construct(Alloc *alloc, slot_type *slot, slot_type *other) {
814
70.2k
    absl::allocator_traits<Alloc>::construct(*alloc, slot, std::move(*other));
815
70.2k
  }
void absl::lts_20260107::container_internal::set_slot_policy<sentencepiece::bpe::Trainer::Symbol*>::construct<std::__1::allocator<sentencepiece::bpe::Trainer::Symbol*> >(std::__1::allocator<sentencepiece::bpe::Trainer::Symbol*>*, sentencepiece::bpe::Trainer::Symbol**, sentencepiece::bpe::Trainer::Symbol**)
Line
Count
Source
813
13.9k
  static void construct(Alloc *alloc, slot_type *slot, slot_type *other) {
814
13.9k
    absl::allocator_traits<Alloc>::construct(*alloc, slot, std::move(*other));
815
13.9k
  }
816
817
  template <typename Alloc>
818
  static void construct(Alloc *alloc, slot_type *slot, const slot_type *other) {
819
    absl::allocator_traits<Alloc>::construct(*alloc, slot, *other);
820
  }
821
822
  template <typename Alloc>
823
2.97M
  static void destroy(Alloc *alloc, slot_type *slot) {
824
2.97M
    absl::allocator_traits<Alloc>::destroy(*alloc, slot);
825
2.97M
  }
void absl::lts_20260107::container_internal::set_slot_policy<sentencepiece::bpe::Trainer::Symbol*>::destroy<std::__1::allocator<sentencepiece::bpe::Trainer::Symbol*> >(std::__1::allocator<sentencepiece::bpe::Trainer::Symbol*>*, sentencepiece::bpe::Trainer::Symbol**)
Line
Count
Source
823
438k
  static void destroy(Alloc *alloc, slot_type *slot) {
824
438k
    absl::allocator_traits<Alloc>::destroy(*alloc, slot);
825
438k
  }
void absl::lts_20260107::container_internal::set_slot_policy<unsigned long>::destroy<std::__1::allocator<unsigned long> >(std::__1::allocator<unsigned long>*, unsigned long*)
Line
Count
Source
823
2.53M
  static void destroy(Alloc *alloc, slot_type *slot) {
824
2.53M
    absl::allocator_traits<Alloc>::destroy(*alloc, slot);
825
2.53M
  }
826
};
827
828
// A parameters structure for holding the type parameters for a btree_set.
829
// Compare and Alloc should be nothrow copy-constructible.
830
template <typename Key, typename... Params>
831
struct set_params_impl
832
    : common_params<
833
          Key,
834
          GetFromListOr<typename btree_set_defaults<Key>::Compare, 0,
835
                        Params...>,
836
          GetFromListOr<typename btree_set_defaults<Key>::Alloc, 1, Params...>,
837
          GetFromListOr<typename btree_set_defaults<Key>::TargetNodeSize, 2,
838
                        Params...>::value,
839
          GetFromListOr<typename btree_set_defaults<Key>::IsMulti, 3,
840
                        Params...>::value,
841
          /*IsMap=*/false, set_slot_policy<Key>> {
842
  using value_type = Key;
843
  using slot_type = typename set_params_impl::common_params::slot_type;
844
845
  static_assert(
846
      std::is_same_v<
847
          set_params<
848
              Key,
849
              GetFromListOr<typename btree_set_defaults<Key>::Compare, 0,
850
                            Params...>,
851
              GetFromListOr<typename btree_set_defaults<Key>::Alloc, 1,
852
                            Params...>,
853
              GetFromListOr<typename btree_set_defaults<Key>::TargetNodeSize, 2,
854
                            Params...>::value,
855
              GetFromListOr<typename btree_set_defaults<Key>::IsMulti, 3,
856
                            Params...>::value>,
857
          set_params_impl>);
858
859
  template <typename V>
860
5.03M
  static const V &key(const V &value) {
861
5.03M
    return value;
862
5.03M
  }
sentencepiece::bpe::Trainer::Symbol* const& absl::lts_20260107::container_internal::set_params_impl<sentencepiece::bpe::Trainer::Symbol*>::key<sentencepiece::bpe::Trainer::Symbol*>(sentencepiece::bpe::Trainer::Symbol* const&)
Line
Count
Source
860
2.56M
  static const V &key(const V &value) {
861
2.56M
    return value;
862
2.56M
  }
unsigned long const& absl::lts_20260107::container_internal::set_params_impl<unsigned long>::key<unsigned long>(unsigned long const&)
Line
Count
Source
860
2.46M
  static const V &key(const V &value) {
861
2.46M
    return value;
862
2.46M
  }
863
61.0M
  static const Key &key(const slot_type *slot) { return *slot; }
absl::lts_20260107::container_internal::set_params_impl<sentencepiece::bpe::Trainer::Symbol*>::key(sentencepiece::bpe::Trainer::Symbol* const*)
Line
Count
Source
863
19.0M
  static const Key &key(const slot_type *slot) { return *slot; }
absl::lts_20260107::container_internal::set_params_impl<unsigned long>::key(unsigned long const*)
Line
Count
Source
863
41.9M
  static const Key &key(const slot_type *slot) { return *slot; }
864
  static const Key &key(slot_type *slot) { return *slot; }
865
};
866
867
}  // namespace container_internal
868
869
ABSL_NAMESPACE_END
870
}  // namespace absl
871
872
#endif  // ABSL_CONTAINER_BTREE_SET_H_