You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

btree_container.h 35 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  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. #ifndef ABSL_CONTAINER_INTERNAL_BTREE_CONTAINER_H_
  15. #define ABSL_CONTAINER_INTERNAL_BTREE_CONTAINER_H_
  16. #include <algorithm>
  17. #include <initializer_list>
  18. #include <iterator>
  19. #include <utility>
  20. #include "absl/base/attributes.h"
  21. #include "absl/base/internal/throw_delegate.h"
  22. #include "absl/container/internal/btree.h" // IWYU pragma: export
  23. #include "absl/container/internal/common.h"
  24. #include "absl/memory/memory.h"
  25. #include "absl/meta/type_traits.h"
  26. namespace absl
  27. {
  28. ABSL_NAMESPACE_BEGIN
  29. namespace container_internal
  30. {
  31. // A common base class for btree_set, btree_map, btree_multiset, and
  32. // btree_multimap.
  33. template<typename Tree>
  34. class btree_container
  35. {
  36. using params_type = typename Tree::params_type;
  37. protected:
  38. // Alias used for heterogeneous lookup functions.
  39. // `key_arg<K>` evaluates to `K` when the functors are transparent and to
  40. // `key_type` otherwise. It permits template argument deduction on `K` for the
  41. // transparent case.
  42. template<class K>
  43. using key_arg =
  44. typename KeyArg<params_type::kIsKeyCompareTransparent>::template type<
  45. K,
  46. typename Tree::key_type>;
  47. public:
  48. using key_type = typename Tree::key_type;
  49. using value_type = typename Tree::value_type;
  50. using size_type = typename Tree::size_type;
  51. using difference_type = typename Tree::difference_type;
  52. using key_compare = typename Tree::original_key_compare;
  53. using value_compare = typename Tree::value_compare;
  54. using allocator_type = typename Tree::allocator_type;
  55. using reference = typename Tree::reference;
  56. using const_reference = typename Tree::const_reference;
  57. using pointer = typename Tree::pointer;
  58. using const_pointer = typename Tree::const_pointer;
  59. using iterator = typename Tree::iterator;
  60. using const_iterator = typename Tree::const_iterator;
  61. using reverse_iterator = typename Tree::reverse_iterator;
  62. using const_reverse_iterator = typename Tree::const_reverse_iterator;
  63. using node_type = typename Tree::node_handle_type;
  64. // Constructors/assignments.
  65. btree_container() :
  66. tree_(key_compare(), allocator_type())
  67. {
  68. }
  69. explicit btree_container(const key_compare& comp, const allocator_type& alloc = allocator_type()) :
  70. tree_(comp, alloc)
  71. {
  72. }
  73. explicit btree_container(const allocator_type& alloc) :
  74. tree_(key_compare(), alloc)
  75. {
  76. }
  77. btree_container(const btree_container& other) :
  78. btree_container(other, absl::allocator_traits<allocator_type>::select_on_container_copy_construction(other.get_allocator()))
  79. {
  80. }
  81. btree_container(const btree_container& other, const allocator_type& alloc) :
  82. tree_(other.tree_, alloc)
  83. {
  84. }
  85. btree_container(btree_container&& other) noexcept(
  86. std::is_nothrow_move_constructible<Tree>::value
  87. ) = default;
  88. btree_container(btree_container&& other, const allocator_type& alloc) :
  89. tree_(std::move(other.tree_), alloc)
  90. {
  91. }
  92. btree_container& operator=(const btree_container& other) = default;
  93. btree_container& operator=(btree_container&& other) noexcept(
  94. std::is_nothrow_move_assignable<Tree>::value
  95. ) = default;
  96. // Iterator routines.
  97. iterator begin()
  98. {
  99. return tree_.begin();
  100. }
  101. const_iterator begin() const
  102. {
  103. return tree_.begin();
  104. }
  105. const_iterator cbegin() const
  106. {
  107. return tree_.begin();
  108. }
  109. iterator end()
  110. {
  111. return tree_.end();
  112. }
  113. const_iterator end() const
  114. {
  115. return tree_.end();
  116. }
  117. const_iterator cend() const
  118. {
  119. return tree_.end();
  120. }
  121. reverse_iterator rbegin()
  122. {
  123. return tree_.rbegin();
  124. }
  125. const_reverse_iterator rbegin() const
  126. {
  127. return tree_.rbegin();
  128. }
  129. const_reverse_iterator crbegin() const
  130. {
  131. return tree_.rbegin();
  132. }
  133. reverse_iterator rend()
  134. {
  135. return tree_.rend();
  136. }
  137. const_reverse_iterator rend() const
  138. {
  139. return tree_.rend();
  140. }
  141. const_reverse_iterator crend() const
  142. {
  143. return tree_.rend();
  144. }
  145. // Lookup routines.
  146. template<typename K = key_type>
  147. size_type count(const key_arg<K>& key) const
  148. {
  149. auto equal_range = this->equal_range(key);
  150. return std::distance(equal_range.first, equal_range.second);
  151. }
  152. template<typename K = key_type>
  153. iterator find(const key_arg<K>& key)
  154. {
  155. return tree_.find(key);
  156. }
  157. template<typename K = key_type>
  158. const_iterator find(const key_arg<K>& key) const
  159. {
  160. return tree_.find(key);
  161. }
  162. template<typename K = key_type>
  163. bool contains(const key_arg<K>& key) const
  164. {
  165. return find(key) != end();
  166. }
  167. template<typename K = key_type>
  168. iterator lower_bound(const key_arg<K>& key)
  169. {
  170. return tree_.lower_bound(key);
  171. }
  172. template<typename K = key_type>
  173. const_iterator lower_bound(const key_arg<K>& key) const
  174. {
  175. return tree_.lower_bound(key);
  176. }
  177. template<typename K = key_type>
  178. iterator upper_bound(const key_arg<K>& key)
  179. {
  180. return tree_.upper_bound(key);
  181. }
  182. template<typename K = key_type>
  183. const_iterator upper_bound(const key_arg<K>& key) const
  184. {
  185. return tree_.upper_bound(key);
  186. }
  187. template<typename K = key_type>
  188. std::pair<iterator, iterator> equal_range(const key_arg<K>& key)
  189. {
  190. return tree_.equal_range(key);
  191. }
  192. template<typename K = key_type>
  193. std::pair<const_iterator, const_iterator> equal_range(
  194. const key_arg<K>& key
  195. ) const
  196. {
  197. return tree_.equal_range(key);
  198. }
  199. // Deletion routines. Note that there is also a deletion routine that is
  200. // specific to btree_set_container/btree_multiset_container.
  201. // Erase the specified iterator from the btree. The iterator must be valid
  202. // (i.e. not equal to end()). Return an iterator pointing to the node after
  203. // the one that was erased (or end() if none exists).
  204. iterator erase(const_iterator iter)
  205. {
  206. return tree_.erase(iterator(iter));
  207. }
  208. iterator erase(iterator iter)
  209. {
  210. return tree_.erase(iter);
  211. }
  212. iterator erase(const_iterator first, const_iterator last)
  213. {
  214. return tree_.erase_range(iterator(first), iterator(last)).second;
  215. }
  216. template<typename K = key_type>
  217. size_type erase(const key_arg<K>& key)
  218. {
  219. auto equal_range = this->equal_range(key);
  220. return tree_.erase_range(equal_range.first, equal_range.second).first;
  221. }
  222. // Extract routines.
  223. node_type extract(iterator position)
  224. {
  225. // Use Construct instead of Transfer because the rebalancing code will
  226. // destroy the slot later.
  227. auto node =
  228. CommonAccess::Construct<node_type>(get_allocator(), position.slot());
  229. erase(position);
  230. return node;
  231. }
  232. node_type extract(const_iterator position)
  233. {
  234. return extract(iterator(position));
  235. }
  236. // Utility routines.
  237. ABSL_ATTRIBUTE_REINITIALIZES void clear()
  238. {
  239. tree_.clear();
  240. }
  241. void swap(btree_container& other)
  242. {
  243. tree_.swap(other.tree_);
  244. }
  245. void verify() const
  246. {
  247. tree_.verify();
  248. }
  249. // Size routines.
  250. size_type size() const
  251. {
  252. return tree_.size();
  253. }
  254. size_type max_size() const
  255. {
  256. return tree_.max_size();
  257. }
  258. bool empty() const
  259. {
  260. return tree_.empty();
  261. }
  262. friend bool operator==(const btree_container& x, const btree_container& y)
  263. {
  264. if (x.size() != y.size())
  265. return false;
  266. return std::equal(x.begin(), x.end(), y.begin());
  267. }
  268. friend bool operator!=(const btree_container& x, const btree_container& y)
  269. {
  270. return !(x == y);
  271. }
  272. friend bool operator<(const btree_container& x, const btree_container& y)
  273. {
  274. return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
  275. }
  276. friend bool operator>(const btree_container& x, const btree_container& y)
  277. {
  278. return y < x;
  279. }
  280. friend bool operator<=(const btree_container& x, const btree_container& y)
  281. {
  282. return !(y < x);
  283. }
  284. friend bool operator>=(const btree_container& x, const btree_container& y)
  285. {
  286. return !(x < y);
  287. }
  288. // The allocator used by the btree.
  289. allocator_type get_allocator() const
  290. {
  291. return tree_.get_allocator();
  292. }
  293. // The key comparator used by the btree.
  294. key_compare key_comp() const
  295. {
  296. return key_compare(tree_.key_comp());
  297. }
  298. value_compare value_comp() const
  299. {
  300. return tree_.value_comp();
  301. }
  302. // Support absl::Hash.
  303. template<typename State>
  304. friend State AbslHashValue(State h, const btree_container& b)
  305. {
  306. for (const auto& v : b)
  307. {
  308. h = State::combine(std::move(h), v);
  309. }
  310. return State::combine(std::move(h), b.size());
  311. }
  312. protected:
  313. friend struct btree_access;
  314. Tree tree_;
  315. };
  316. // A common base class for btree_set and btree_map.
  317. template<typename Tree>
  318. class btree_set_container : public btree_container<Tree>
  319. {
  320. using super_type = btree_container<Tree>;
  321. using params_type = typename Tree::params_type;
  322. using init_type = typename params_type::init_type;
  323. using is_key_compare_to = typename params_type::is_key_compare_to;
  324. friend class BtreeNodePeer;
  325. protected:
  326. template<class K>
  327. using key_arg = typename super_type::template key_arg<K>;
  328. public:
  329. using key_type = typename Tree::key_type;
  330. using value_type = typename Tree::value_type;
  331. using size_type = typename Tree::size_type;
  332. using key_compare = typename Tree::original_key_compare;
  333. using allocator_type = typename Tree::allocator_type;
  334. using iterator = typename Tree::iterator;
  335. using const_iterator = typename Tree::const_iterator;
  336. using node_type = typename super_type::node_type;
  337. using insert_return_type = InsertReturnType<iterator, node_type>;
  338. // Inherit constructors.
  339. using super_type::super_type;
  340. btree_set_container()
  341. {
  342. }
  343. // Range constructors.
  344. template<class InputIterator>
  345. btree_set_container(InputIterator b, InputIterator e, const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()) :
  346. super_type(comp, alloc)
  347. {
  348. insert(b, e);
  349. }
  350. template<class InputIterator>
  351. btree_set_container(InputIterator b, InputIterator e, const allocator_type& alloc) :
  352. btree_set_container(b, e, key_compare(), alloc)
  353. {
  354. }
  355. // Initializer list constructors.
  356. btree_set_container(std::initializer_list<init_type> init, const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()) :
  357. btree_set_container(init.begin(), init.end(), comp, alloc)
  358. {
  359. }
  360. btree_set_container(std::initializer_list<init_type> init, const allocator_type& alloc) :
  361. btree_set_container(init.begin(), init.end(), alloc)
  362. {
  363. }
  364. // Insertion routines.
  365. std::pair<iterator, bool> insert(const value_type& v)
  366. {
  367. return this->tree_.insert_unique(params_type::key(v), v);
  368. }
  369. std::pair<iterator, bool> insert(value_type&& v)
  370. {
  371. return this->tree_.insert_unique(params_type::key(v), std::move(v));
  372. }
  373. template<typename... Args>
  374. std::pair<iterator, bool> emplace(Args&&... args)
  375. {
  376. // Use a node handle to manage a temp slot.
  377. auto node = CommonAccess::Construct<node_type>(this->get_allocator(), std::forward<Args>(args)...);
  378. auto* slot = CommonAccess::GetSlot(node);
  379. return this->tree_.insert_unique(params_type::key(slot), slot);
  380. }
  381. iterator insert(const_iterator hint, const value_type& v)
  382. {
  383. return this->tree_
  384. .insert_hint_unique(iterator(hint), params_type::key(v), v)
  385. .first;
  386. }
  387. iterator insert(const_iterator hint, value_type&& v)
  388. {
  389. return this->tree_
  390. .insert_hint_unique(iterator(hint), params_type::key(v), std::move(v))
  391. .first;
  392. }
  393. template<typename... Args>
  394. iterator emplace_hint(const_iterator hint, Args&&... args)
  395. {
  396. // Use a node handle to manage a temp slot.
  397. auto node = CommonAccess::Construct<node_type>(this->get_allocator(), std::forward<Args>(args)...);
  398. auto* slot = CommonAccess::GetSlot(node);
  399. return this->tree_
  400. .insert_hint_unique(iterator(hint), params_type::key(slot), slot)
  401. .first;
  402. }
  403. template<typename InputIterator>
  404. void insert(InputIterator b, InputIterator e)
  405. {
  406. this->tree_.insert_iterator_unique(b, e, 0);
  407. }
  408. void insert(std::initializer_list<init_type> init)
  409. {
  410. this->tree_.insert_iterator_unique(init.begin(), init.end(), 0);
  411. }
  412. insert_return_type insert(node_type&& node)
  413. {
  414. if (!node)
  415. return {this->end(), false, node_type()};
  416. std::pair<iterator, bool> res =
  417. this->tree_.insert_unique(params_type::key(CommonAccess::GetSlot(node)), CommonAccess::GetSlot(node));
  418. if (res.second)
  419. {
  420. CommonAccess::Destroy(&node);
  421. return {res.first, true, node_type()};
  422. }
  423. else
  424. {
  425. return {res.first, false, std::move(node)};
  426. }
  427. }
  428. iterator insert(const_iterator hint, node_type&& node)
  429. {
  430. if (!node)
  431. return this->end();
  432. std::pair<iterator, bool> res = this->tree_.insert_hint_unique(
  433. iterator(hint), params_type::key(CommonAccess::GetSlot(node)), CommonAccess::GetSlot(node)
  434. );
  435. if (res.second)
  436. CommonAccess::Destroy(&node);
  437. return res.first;
  438. }
  439. // Node extraction routines.
  440. template<typename K = key_type>
  441. node_type extract(const key_arg<K>& key)
  442. {
  443. const std::pair<iterator, bool> lower_and_equal =
  444. this->tree_.lower_bound_equal(key);
  445. return lower_and_equal.second ? extract(lower_and_equal.first) : node_type();
  446. }
  447. using super_type::extract;
  448. // Merge routines.
  449. // Moves elements from `src` into `this`. If the element already exists in
  450. // `this`, it is left unmodified in `src`.
  451. template<
  452. typename T,
  453. typename absl::enable_if_t<
  454. absl::conjunction<
  455. std::is_same<value_type, typename T::value_type>,
  456. std::is_same<allocator_type, typename T::allocator_type>,
  457. std::is_same<typename params_type::is_map_container, typename T::params_type::is_map_container>>::value,
  458. int> = 0>
  459. void merge(btree_container<T>& src)
  460. { // NOLINT
  461. for (auto src_it = src.begin(); src_it != src.end();)
  462. {
  463. if (insert(std::move(params_type::element(src_it.slot()))).second)
  464. {
  465. src_it = src.erase(src_it);
  466. }
  467. else
  468. {
  469. ++src_it;
  470. }
  471. }
  472. }
  473. template<
  474. typename T,
  475. typename absl::enable_if_t<
  476. absl::conjunction<
  477. std::is_same<value_type, typename T::value_type>,
  478. std::is_same<allocator_type, typename T::allocator_type>,
  479. std::is_same<typename params_type::is_map_container, typename T::params_type::is_map_container>>::value,
  480. int> = 0>
  481. void merge(btree_container<T>&& src)
  482. {
  483. merge(src);
  484. }
  485. };
  486. // Base class for btree_map.
  487. template<typename Tree>
  488. class btree_map_container : public btree_set_container<Tree>
  489. {
  490. using super_type = btree_set_container<Tree>;
  491. using params_type = typename Tree::params_type;
  492. friend class BtreeNodePeer;
  493. private:
  494. template<class K>
  495. using key_arg = typename super_type::template key_arg<K>;
  496. public:
  497. using key_type = typename Tree::key_type;
  498. using mapped_type = typename params_type::mapped_type;
  499. using value_type = typename Tree::value_type;
  500. using key_compare = typename Tree::original_key_compare;
  501. using allocator_type = typename Tree::allocator_type;
  502. using iterator = typename Tree::iterator;
  503. using const_iterator = typename Tree::const_iterator;
  504. // Inherit constructors.
  505. using super_type::super_type;
  506. btree_map_container()
  507. {
  508. }
  509. // Insertion routines.
  510. // Note: the nullptr template arguments and extra `const M&` overloads allow
  511. // for supporting bitfield arguments.
  512. template<typename K = key_type, class M>
  513. std::pair<iterator, bool> insert_or_assign(const key_arg<K>& k, const M& obj)
  514. {
  515. return insert_or_assign_impl(k, obj);
  516. }
  517. template<typename K = key_type, class M, K* = nullptr>
  518. std::pair<iterator, bool> insert_or_assign(key_arg<K>&& k, const M& obj)
  519. {
  520. return insert_or_assign_impl(std::forward<K>(k), obj);
  521. }
  522. template<typename K = key_type, class M, M* = nullptr>
  523. std::pair<iterator, bool> insert_or_assign(const key_arg<K>& k, M&& obj)
  524. {
  525. return insert_or_assign_impl(k, std::forward<M>(obj));
  526. }
  527. template<typename K = key_type, class M, K* = nullptr, M* = nullptr>
  528. std::pair<iterator, bool> insert_or_assign(key_arg<K>&& k, M&& obj)
  529. {
  530. return insert_or_assign_impl(std::forward<K>(k), std::forward<M>(obj));
  531. }
  532. template<typename K = key_type, class M>
  533. iterator insert_or_assign(const_iterator hint, const key_arg<K>& k, const M& obj)
  534. {
  535. return insert_or_assign_hint_impl(hint, k, obj);
  536. }
  537. template<typename K = key_type, class M, K* = nullptr>
  538. iterator insert_or_assign(const_iterator hint, key_arg<K>&& k, const M& obj)
  539. {
  540. return insert_or_assign_hint_impl(hint, std::forward<K>(k), obj);
  541. }
  542. template<typename K = key_type, class M, M* = nullptr>
  543. iterator insert_or_assign(const_iterator hint, const key_arg<K>& k, M&& obj)
  544. {
  545. return insert_or_assign_hint_impl(hint, k, std::forward<M>(obj));
  546. }
  547. template<typename K = key_type, class M, K* = nullptr, M* = nullptr>
  548. iterator insert_or_assign(const_iterator hint, key_arg<K>&& k, M&& obj)
  549. {
  550. return insert_or_assign_hint_impl(hint, std::forward<K>(k), std::forward<M>(obj));
  551. }
  552. template<typename K = key_type, typename... Args, typename absl::enable_if_t<!std::is_convertible<K, const_iterator>::value, int> = 0>
  553. std::pair<iterator, bool> try_emplace(const key_arg<K>& k, Args&&... args)
  554. {
  555. return try_emplace_impl(k, std::forward<Args>(args)...);
  556. }
  557. template<typename K = key_type, typename... Args, typename absl::enable_if_t<!std::is_convertible<K, const_iterator>::value, int> = 0>
  558. std::pair<iterator, bool> try_emplace(key_arg<K>&& k, Args&&... args)
  559. {
  560. return try_emplace_impl(std::forward<K>(k), std::forward<Args>(args)...);
  561. }
  562. template<typename K = key_type, typename... Args>
  563. iterator try_emplace(const_iterator hint, const key_arg<K>& k, Args&&... args)
  564. {
  565. return try_emplace_hint_impl(hint, k, std::forward<Args>(args)...);
  566. }
  567. template<typename K = key_type, typename... Args>
  568. iterator try_emplace(const_iterator hint, key_arg<K>&& k, Args&&... args)
  569. {
  570. return try_emplace_hint_impl(hint, std::forward<K>(k), std::forward<Args>(args)...);
  571. }
  572. template<typename K = key_type>
  573. mapped_type& operator[](const key_arg<K>& k)
  574. {
  575. return try_emplace(k).first->second;
  576. }
  577. template<typename K = key_type>
  578. mapped_type& operator[](key_arg<K>&& k)
  579. {
  580. return try_emplace(std::forward<K>(k)).first->second;
  581. }
  582. template<typename K = key_type>
  583. mapped_type& at(const key_arg<K>& key)
  584. {
  585. auto it = this->find(key);
  586. if (it == this->end())
  587. base_internal::ThrowStdOutOfRange("absl::btree_map::at");
  588. return it->second;
  589. }
  590. template<typename K = key_type>
  591. const mapped_type& at(const key_arg<K>& key) const
  592. {
  593. auto it = this->find(key);
  594. if (it == this->end())
  595. base_internal::ThrowStdOutOfRange("absl::btree_map::at");
  596. return it->second;
  597. }
  598. private:
  599. // Note: when we call `std::forward<M>(obj)` twice, it's safe because
  600. // insert_unique/insert_hint_unique are guaranteed to not consume `obj` when
  601. // `ret.second` is false.
  602. template<class K, class M>
  603. std::pair<iterator, bool> insert_or_assign_impl(K&& k, M&& obj)
  604. {
  605. const std::pair<iterator, bool> ret =
  606. this->tree_.insert_unique(k, std::forward<K>(k), std::forward<M>(obj));
  607. if (!ret.second)
  608. ret.first->second = std::forward<M>(obj);
  609. return ret;
  610. }
  611. template<class K, class M>
  612. iterator insert_or_assign_hint_impl(const_iterator hint, K&& k, M&& obj)
  613. {
  614. const std::pair<iterator, bool> ret = this->tree_.insert_hint_unique(
  615. iterator(hint), k, std::forward<K>(k), std::forward<M>(obj)
  616. );
  617. if (!ret.second)
  618. ret.first->second = std::forward<M>(obj);
  619. return ret.first;
  620. }
  621. template<class K, class... Args>
  622. std::pair<iterator, bool> try_emplace_impl(K&& k, Args&&... args)
  623. {
  624. return this->tree_.insert_unique(
  625. k, std::piecewise_construct, std::forward_as_tuple(std::forward<K>(k)), std::forward_as_tuple(std::forward<Args>(args)...)
  626. );
  627. }
  628. template<class K, class... Args>
  629. iterator try_emplace_hint_impl(const_iterator hint, K&& k, Args&&... args)
  630. {
  631. return this->tree_
  632. .insert_hint_unique(iterator(hint), k, std::piecewise_construct, std::forward_as_tuple(std::forward<K>(k)), std::forward_as_tuple(std::forward<Args>(args)...))
  633. .first;
  634. }
  635. };
  636. // A common base class for btree_multiset and btree_multimap.
  637. template<typename Tree>
  638. class btree_multiset_container : public btree_container<Tree>
  639. {
  640. using super_type = btree_container<Tree>;
  641. using params_type = typename Tree::params_type;
  642. using init_type = typename params_type::init_type;
  643. using is_key_compare_to = typename params_type::is_key_compare_to;
  644. friend class BtreeNodePeer;
  645. template<class K>
  646. using key_arg = typename super_type::template key_arg<K>;
  647. public:
  648. using key_type = typename Tree::key_type;
  649. using value_type = typename Tree::value_type;
  650. using size_type = typename Tree::size_type;
  651. using key_compare = typename Tree::original_key_compare;
  652. using allocator_type = typename Tree::allocator_type;
  653. using iterator = typename Tree::iterator;
  654. using const_iterator = typename Tree::const_iterator;
  655. using node_type = typename super_type::node_type;
  656. // Inherit constructors.
  657. using super_type::super_type;
  658. btree_multiset_container()
  659. {
  660. }
  661. // Range constructors.
  662. template<class InputIterator>
  663. btree_multiset_container(InputIterator b, InputIterator e, const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()) :
  664. super_type(comp, alloc)
  665. {
  666. insert(b, e);
  667. }
  668. template<class InputIterator>
  669. btree_multiset_container(InputIterator b, InputIterator e, const allocator_type& alloc) :
  670. btree_multiset_container(b, e, key_compare(), alloc)
  671. {
  672. }
  673. // Initializer list constructors.
  674. btree_multiset_container(std::initializer_list<init_type> init, const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()) :
  675. btree_multiset_container(init.begin(), init.end(), comp, alloc)
  676. {
  677. }
  678. btree_multiset_container(std::initializer_list<init_type> init, const allocator_type& alloc) :
  679. btree_multiset_container(init.begin(), init.end(), alloc)
  680. {
  681. }
  682. // Insertion routines.
  683. iterator insert(const value_type& v)
  684. {
  685. return this->tree_.insert_multi(v);
  686. }
  687. iterator insert(value_type&& v)
  688. {
  689. return this->tree_.insert_multi(std::move(v));
  690. }
  691. iterator insert(const_iterator hint, const value_type& v)
  692. {
  693. return this->tree_.insert_hint_multi(iterator(hint), v);
  694. }
  695. iterator insert(const_iterator hint, value_type&& v)
  696. {
  697. return this->tree_.insert_hint_multi(iterator(hint), std::move(v));
  698. }
  699. template<typename InputIterator>
  700. void insert(InputIterator b, InputIterator e)
  701. {
  702. this->tree_.insert_iterator_multi(b, e);
  703. }
  704. void insert(std::initializer_list<init_type> init)
  705. {
  706. this->tree_.insert_iterator_multi(init.begin(), init.end());
  707. }
  708. template<typename... Args>
  709. iterator emplace(Args&&... args)
  710. {
  711. // Use a node handle to manage a temp slot.
  712. auto node = CommonAccess::Construct<node_type>(this->get_allocator(), std::forward<Args>(args)...);
  713. return this->tree_.insert_multi(CommonAccess::GetSlot(node));
  714. }
  715. template<typename... Args>
  716. iterator emplace_hint(const_iterator hint, Args&&... args)
  717. {
  718. // Use a node handle to manage a temp slot.
  719. auto node = CommonAccess::Construct<node_type>(this->get_allocator(), std::forward<Args>(args)...);
  720. return this->tree_.insert_hint_multi(iterator(hint), CommonAccess::GetSlot(node));
  721. }
  722. iterator insert(node_type&& node)
  723. {
  724. if (!node)
  725. return this->end();
  726. iterator res =
  727. this->tree_.insert_multi(params_type::key(CommonAccess::GetSlot(node)), CommonAccess::GetSlot(node));
  728. CommonAccess::Destroy(&node);
  729. return res;
  730. }
  731. iterator insert(const_iterator hint, node_type&& node)
  732. {
  733. if (!node)
  734. return this->end();
  735. iterator res = this->tree_.insert_hint_multi(
  736. iterator(hint),
  737. std::move(params_type::element(CommonAccess::GetSlot(node)))
  738. );
  739. CommonAccess::Destroy(&node);
  740. return res;
  741. }
  742. // Node extraction routines.
  743. template<typename K = key_type>
  744. node_type extract(const key_arg<K>& key)
  745. {
  746. const std::pair<iterator, bool> lower_and_equal =
  747. this->tree_.lower_bound_equal(key);
  748. return lower_and_equal.second ? extract(lower_and_equal.first) : node_type();
  749. }
  750. using super_type::extract;
  751. // Merge routines.
  752. // Moves all elements from `src` into `this`.
  753. template<
  754. typename T,
  755. typename absl::enable_if_t<
  756. absl::conjunction<
  757. std::is_same<value_type, typename T::value_type>,
  758. std::is_same<allocator_type, typename T::allocator_type>,
  759. std::is_same<typename params_type::is_map_container, typename T::params_type::is_map_container>>::value,
  760. int> = 0>
  761. void merge(btree_container<T>& src)
  762. { // NOLINT
  763. for (auto src_it = src.begin(), end = src.end(); src_it != end; ++src_it)
  764. {
  765. insert(std::move(params_type::element(src_it.slot())));
  766. }
  767. src.clear();
  768. }
  769. template<
  770. typename T,
  771. typename absl::enable_if_t<
  772. absl::conjunction<
  773. std::is_same<value_type, typename T::value_type>,
  774. std::is_same<allocator_type, typename T::allocator_type>,
  775. std::is_same<typename params_type::is_map_container, typename T::params_type::is_map_container>>::value,
  776. int> = 0>
  777. void merge(btree_container<T>&& src)
  778. {
  779. merge(src);
  780. }
  781. };
  782. // A base class for btree_multimap.
  783. template<typename Tree>
  784. class btree_multimap_container : public btree_multiset_container<Tree>
  785. {
  786. using super_type = btree_multiset_container<Tree>;
  787. using params_type = typename Tree::params_type;
  788. friend class BtreeNodePeer;
  789. public:
  790. using mapped_type = typename params_type::mapped_type;
  791. // Inherit constructors.
  792. using super_type::super_type;
  793. btree_multimap_container()
  794. {
  795. }
  796. };
  797. } // namespace container_internal
  798. ABSL_NAMESPACE_END
  799. } // namespace absl
  800. #endif // ABSL_CONTAINER_INTERNAL_BTREE_CONTAINER_H_