flat_map.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095
  1. // This file is part of Desktop App Toolkit,
  2. // a set of libraries for developing nice desktop applications.
  3. //
  4. // For license and copyright information please follow this link:
  5. // https://github.com/desktop-app/legal/blob/master/LEGAL
  6. //
  7. #pragma once
  8. #include <vector>
  9. #include <algorithm>
  10. #include "base/optional.h"
  11. namespace base {
  12. using std::begin;
  13. using std::end;
  14. template <
  15. typename Key,
  16. typename Type,
  17. typename Compare = std::less<>>
  18. class flat_map;
  19. template <
  20. typename Key,
  21. typename Type,
  22. typename Compare = std::less<>>
  23. class flat_multi_map;
  24. template <
  25. typename Me,
  26. typename Key,
  27. typename Type,
  28. typename iterator_impl,
  29. typename pointer_impl,
  30. typename reference_impl>
  31. class flat_multi_map_iterator_base_impl;
  32. template <typename Key, typename Value>
  33. struct flat_multi_map_pair_type {
  34. using first_type = const Key;
  35. using second_type = Value;
  36. constexpr flat_multi_map_pair_type() noexcept
  37. : first()
  38. , second() {
  39. }
  40. template <typename OtherKey, typename OtherValue>
  41. constexpr flat_multi_map_pair_type(
  42. OtherKey &&key,
  43. OtherValue &&value) noexcept
  44. : first(std::forward<OtherKey>(key))
  45. , second(std::forward<OtherValue>(value)) {
  46. }
  47. constexpr flat_multi_map_pair_type(
  48. const flat_multi_map_pair_type &pair) noexcept
  49. : first(pair.first)
  50. , second(pair.second) {
  51. }
  52. constexpr flat_multi_map_pair_type(
  53. flat_multi_map_pair_type &&pair) noexcept
  54. : first(std::move(const_cast<Key&>(pair.first)))
  55. , second(std::move(pair.second)) {
  56. }
  57. flat_multi_map_pair_type &operator=(
  58. const flat_multi_map_pair_type&) = delete;
  59. constexpr flat_multi_map_pair_type &operator=(
  60. flat_multi_map_pair_type &&other) noexcept {
  61. const_cast<Key&>(first) = std::move(const_cast<Key&>(other.first));
  62. second = std::move(other.second);
  63. return *this;
  64. }
  65. friend inline constexpr bool operator<(
  66. const flat_multi_map_pair_type &a,
  67. const flat_multi_map_pair_type &b) noexcept {
  68. if (a.first < b.first) {
  69. return true;
  70. } else if (a.first > b.first) {
  71. return false;
  72. }
  73. return (a.second < b.second);
  74. }
  75. friend inline constexpr bool operator>(
  76. const flat_multi_map_pair_type &a,
  77. const flat_multi_map_pair_type &b) noexcept {
  78. return b < a;
  79. }
  80. friend inline constexpr bool operator<=(
  81. const flat_multi_map_pair_type &a,
  82. const flat_multi_map_pair_type &b) noexcept {
  83. return !(b < a);
  84. }
  85. friend inline constexpr bool operator>=(
  86. const flat_multi_map_pair_type &a,
  87. const flat_multi_map_pair_type &b) noexcept {
  88. return !(a < b);
  89. }
  90. friend inline constexpr bool operator==(
  91. const flat_multi_map_pair_type &a,
  92. const flat_multi_map_pair_type &b) noexcept {
  93. return (a.first == b.first) && (a.second == b.second);
  94. }
  95. friend inline constexpr bool operator!=(
  96. const flat_multi_map_pair_type &a,
  97. const flat_multi_map_pair_type &b) noexcept {
  98. return !(a == b);
  99. }
  100. constexpr void swap(flat_multi_map_pair_type &other) noexcept {
  101. using std::swap;
  102. if (this != &other) {
  103. std::swap(
  104. const_cast<Key&>(first),
  105. const_cast<Key&>(other.first));
  106. std::swap(second, other.second);
  107. }
  108. }
  109. const Key first;
  110. Value second;
  111. };
  112. template <
  113. typename Me,
  114. typename Key,
  115. typename Type,
  116. typename iterator_impl,
  117. typename pointer_impl,
  118. typename reference_impl>
  119. class flat_multi_map_iterator_base_impl {
  120. public:
  121. using iterator_category = typename iterator_impl::iterator_category;
  122. using pair_type = flat_multi_map_pair_type<Key, Type>;
  123. using value_type = pair_type;
  124. using difference_type = typename iterator_impl::difference_type;
  125. using pointer = pointer_impl;
  126. using reference = reference_impl;
  127. constexpr flat_multi_map_iterator_base_impl(
  128. iterator_impl impl = iterator_impl()) noexcept
  129. : _impl(impl) {
  130. }
  131. constexpr reference operator*() const noexcept {
  132. return *_impl;
  133. }
  134. constexpr pointer operator->() const noexcept {
  135. return std::addressof(**this);
  136. }
  137. constexpr Me &operator++() noexcept {
  138. ++_impl;
  139. return static_cast<Me&>(*this);
  140. }
  141. constexpr Me operator++(int) noexcept {
  142. return _impl++;
  143. }
  144. constexpr Me &operator--() noexcept {
  145. --_impl;
  146. return static_cast<Me&>(*this);
  147. }
  148. constexpr Me operator--(int) noexcept {
  149. return _impl--;
  150. }
  151. constexpr Me &operator+=(difference_type offset) noexcept {
  152. _impl += offset;
  153. return static_cast<Me&>(*this);
  154. }
  155. constexpr Me operator+(difference_type offset) const noexcept {
  156. return _impl + offset;
  157. }
  158. constexpr Me &operator-=(difference_type offset) noexcept {
  159. _impl -= offset;
  160. return static_cast<Me&>(*this);
  161. }
  162. constexpr Me operator-(difference_type offset) const noexcept {
  163. return _impl - offset;
  164. }
  165. template <
  166. typename other_me,
  167. typename other_iterator_impl,
  168. typename other_pointer_impl,
  169. typename other_reference_impl>
  170. constexpr difference_type operator-(
  171. const flat_multi_map_iterator_base_impl<
  172. other_me,
  173. Key,
  174. Type,
  175. other_iterator_impl,
  176. other_pointer_impl,
  177. other_reference_impl> &right) const noexcept {
  178. return _impl - right._impl;
  179. }
  180. constexpr reference operator[](difference_type offset) const noexcept {
  181. return _impl[offset];
  182. }
  183. template <
  184. typename other_me,
  185. typename other_iterator_impl,
  186. typename other_pointer_impl,
  187. typename other_reference_impl>
  188. constexpr bool operator==(
  189. const flat_multi_map_iterator_base_impl<
  190. other_me,
  191. Key,
  192. Type,
  193. other_iterator_impl,
  194. other_pointer_impl,
  195. other_reference_impl> &right) const noexcept {
  196. return _impl == right._impl;
  197. }
  198. template <
  199. typename other_me,
  200. typename other_iterator_impl,
  201. typename other_pointer_impl,
  202. typename other_reference_impl>
  203. constexpr bool operator!=(
  204. const flat_multi_map_iterator_base_impl<
  205. other_me,
  206. Key,
  207. Type,
  208. other_iterator_impl,
  209. other_pointer_impl,
  210. other_reference_impl> &right) const noexcept {
  211. return _impl != right._impl;
  212. }
  213. template <
  214. typename other_me,
  215. typename other_iterator_impl,
  216. typename other_pointer_impl,
  217. typename other_reference_impl>
  218. constexpr bool operator<(
  219. const flat_multi_map_iterator_base_impl<
  220. other_me,
  221. Key,
  222. Type,
  223. other_iterator_impl,
  224. other_pointer_impl,
  225. other_reference_impl> &right) const noexcept {
  226. return _impl < right._impl;
  227. }
  228. private:
  229. iterator_impl _impl;
  230. template <
  231. typename OtherKey,
  232. typename OtherType,
  233. typename OtherCompare>
  234. friend class flat_multi_map;
  235. template <
  236. typename OtherMe,
  237. typename OtherKey,
  238. typename OtherType,
  239. typename other_iterator_impl,
  240. typename other_pointer_impl,
  241. typename other_reference_impl>
  242. friend class flat_multi_map_iterator_base_impl;
  243. };
  244. template <typename Key, typename Type, typename Compare>
  245. class flat_multi_map {
  246. public:
  247. class iterator;
  248. class const_iterator;
  249. class reverse_iterator;
  250. class const_reverse_iterator;
  251. private:
  252. using pair_type = flat_multi_map_pair_type<Key, Type>;
  253. using impl_t = std::vector<pair_type>;
  254. using iterator_base = flat_multi_map_iterator_base_impl<
  255. iterator,
  256. Key,
  257. Type,
  258. typename impl_t::iterator,
  259. pair_type*,
  260. pair_type&>;
  261. using const_iterator_base = flat_multi_map_iterator_base_impl<
  262. const_iterator,
  263. Key,
  264. Type,
  265. typename impl_t::const_iterator,
  266. const pair_type*,
  267. const pair_type&>;
  268. using reverse_iterator_base = flat_multi_map_iterator_base_impl<
  269. reverse_iterator,
  270. Key,
  271. Type,
  272. typename impl_t::reverse_iterator,
  273. pair_type*,
  274. pair_type&>;
  275. using const_reverse_iterator_base = flat_multi_map_iterator_base_impl<
  276. const_reverse_iterator,
  277. Key,
  278. Type,
  279. typename impl_t::const_reverse_iterator,
  280. const pair_type*,
  281. const pair_type&>;
  282. public:
  283. using value_type = pair_type;
  284. using size_type = typename impl_t::size_type;
  285. using difference_type = typename impl_t::difference_type;
  286. using pointer = pair_type*;
  287. using const_pointer = const pair_type*;
  288. using reference = pair_type&;
  289. using const_reference = const pair_type&;
  290. class iterator : public iterator_base {
  291. public:
  292. using iterator_base::iterator_base;
  293. constexpr iterator() = default;
  294. constexpr iterator(const iterator_base &other) noexcept
  295. : iterator_base(other) {
  296. }
  297. friend class const_iterator;
  298. };
  299. class const_iterator : public const_iterator_base {
  300. public:
  301. using const_iterator_base::const_iterator_base;
  302. constexpr const_iterator() = default;
  303. constexpr const_iterator(const_iterator_base other) noexcept
  304. : const_iterator_base(other) {
  305. }
  306. constexpr const_iterator(const iterator &other) noexcept
  307. : const_iterator_base(other._impl) {
  308. }
  309. };
  310. class reverse_iterator : public reverse_iterator_base {
  311. public:
  312. using reverse_iterator_base::reverse_iterator_base;
  313. constexpr reverse_iterator() = default;
  314. constexpr reverse_iterator(reverse_iterator_base other) noexcept
  315. : reverse_iterator_base(other) {
  316. }
  317. friend class const_reverse_iterator;
  318. };
  319. class const_reverse_iterator : public const_reverse_iterator_base {
  320. public:
  321. using const_reverse_iterator_base::const_reverse_iterator_base;
  322. constexpr const_reverse_iterator() = default;
  323. constexpr const_reverse_iterator(
  324. const_reverse_iterator_base other) noexcept
  325. : const_reverse_iterator_base(other) {
  326. }
  327. constexpr const_reverse_iterator(
  328. const reverse_iterator &other) noexcept
  329. : const_reverse_iterator_base(other._impl) {
  330. }
  331. };
  332. constexpr flat_multi_map() = default;
  333. constexpr flat_multi_map(const flat_multi_map &other) = default;
  334. constexpr flat_multi_map(flat_multi_map &&other) = default;
  335. constexpr flat_multi_map &operator=(
  336. const flat_multi_map &other) noexcept {
  337. auto copy = other;
  338. return (*this = std::move(copy));
  339. }
  340. constexpr flat_multi_map &operator=(flat_multi_map &&other) = default;
  341. friend inline constexpr bool operator<(
  342. const flat_multi_map &a,
  343. const flat_multi_map &b) noexcept {
  344. return a.impl() < b.impl();
  345. }
  346. friend inline constexpr bool operator>(
  347. const flat_multi_map &a,
  348. const flat_multi_map &b) noexcept {
  349. return a.impl() > b.impl();
  350. }
  351. friend inline constexpr bool operator<=(
  352. const flat_multi_map &a,
  353. const flat_multi_map &b) noexcept {
  354. return a.impl() <= b.impl();
  355. }
  356. friend inline constexpr bool operator>=(
  357. const flat_multi_map &a,
  358. const flat_multi_map &b) noexcept {
  359. return a.impl() >= b.impl();
  360. }
  361. friend inline constexpr bool operator==(
  362. const flat_multi_map &a,
  363. const flat_multi_map &b) noexcept {
  364. return a.impl() == b.impl();
  365. }
  366. friend inline constexpr bool operator!=(
  367. const flat_multi_map &a,
  368. const flat_multi_map &b) noexcept {
  369. return a.impl() != b.impl();
  370. }
  371. template <
  372. typename Iterator,
  373. typename = typename std::iterator_traits<Iterator>::iterator_category>
  374. constexpr flat_multi_map(Iterator first, Iterator last) noexcept
  375. : _data(first, last) {
  376. std::sort(std::begin(impl()), std::end(impl()), compare());
  377. }
  378. constexpr flat_multi_map(std::initializer_list<pair_type> iter) noexcept
  379. : flat_multi_map(iter.begin(), iter.end()) {
  380. }
  381. constexpr size_type size() const noexcept {
  382. return impl().size();
  383. }
  384. constexpr bool empty() const noexcept {
  385. return impl().empty();
  386. }
  387. constexpr void clear() noexcept {
  388. impl().clear();
  389. }
  390. constexpr void reserve(size_type size) noexcept {
  391. impl().reserve(size);
  392. }
  393. constexpr void shrink_to_fit() noexcept {
  394. impl().shrink_to_fit();
  395. }
  396. constexpr iterator begin() noexcept {
  397. return impl().begin();
  398. }
  399. constexpr iterator end() noexcept {
  400. return impl().end();
  401. }
  402. constexpr const_iterator begin() const noexcept {
  403. return impl().begin();
  404. }
  405. constexpr const_iterator end() const noexcept {
  406. return impl().end();
  407. }
  408. constexpr const_iterator cbegin() const noexcept {
  409. return impl().cbegin();
  410. }
  411. constexpr const_iterator cend() const noexcept {
  412. return impl().cend();
  413. }
  414. constexpr reverse_iterator rbegin() noexcept {
  415. return impl().rbegin();
  416. }
  417. constexpr reverse_iterator rend() noexcept {
  418. return impl().rend();
  419. }
  420. constexpr const_reverse_iterator rbegin() const noexcept {
  421. return impl().rbegin();
  422. }
  423. constexpr const_reverse_iterator rend() const noexcept {
  424. return impl().rend();
  425. }
  426. constexpr const_reverse_iterator crbegin() const noexcept {
  427. return impl().crbegin();
  428. }
  429. constexpr const_reverse_iterator crend() const noexcept {
  430. return impl().crend();
  431. }
  432. constexpr reference front() noexcept {
  433. return *begin();
  434. }
  435. constexpr const_reference front() const noexcept {
  436. return *begin();
  437. }
  438. constexpr reference back() noexcept {
  439. return *(end() - 1);
  440. }
  441. constexpr const_reference back() const noexcept {
  442. return *(end() - 1);
  443. }
  444. constexpr iterator insert(const value_type &value) noexcept {
  445. if (empty() || !compare()(value.first, back().first)) {
  446. impl().push_back(value);
  447. return (end() - 1);
  448. }
  449. auto where = getUpperBound(value.first);
  450. return impl().insert(where, value);
  451. }
  452. constexpr iterator insert(value_type &&value) noexcept {
  453. if (empty() || !compare()(value.first, back().first)) {
  454. impl().push_back(std::move(value));
  455. return (end() - 1);
  456. }
  457. auto where = getUpperBound(value.first);
  458. return impl().insert(where, std::move(value));
  459. }
  460. template <typename... Args>
  461. constexpr iterator emplace(Args&&... args) noexcept {
  462. return insert(value_type(std::forward<Args>(args)...));
  463. }
  464. template <typename OtherKey>
  465. constexpr bool removeOne(const OtherKey &key) noexcept {
  466. if (empty()
  467. || compare()(key, front().first)
  468. || compare()(back().first, key)) {
  469. return false;
  470. }
  471. auto where = getLowerBound(key);
  472. if (compare()(key, where->first)) {
  473. return false;
  474. }
  475. impl().erase(where);
  476. return true;
  477. }
  478. constexpr bool removeOne(const Key &key) noexcept {
  479. return removeOne<Key>(key);
  480. }
  481. template <typename OtherKey>
  482. constexpr int removeAll(const OtherKey &key) noexcept {
  483. if (empty()
  484. || compare()(key, front().first)
  485. || compare()(back().first, key)) {
  486. return 0;
  487. }
  488. auto range = getEqualRange(key);
  489. if (range.first == range.second) {
  490. return 0;
  491. }
  492. const auto result = (range.second - range.first);
  493. impl().erase(range.first, range.second);
  494. return result;
  495. }
  496. constexpr int removeAll(const Key &key) noexcept {
  497. return removeAll<Key>(key);
  498. }
  499. template <typename OtherKey>
  500. constexpr bool remove(const OtherKey &key, const Type &value) noexcept {
  501. if (empty()
  502. || compare()(key, front().first)
  503. || compare()(back().first, key)) {
  504. return false;
  505. }
  506. const auto e = impl().end();
  507. for (auto where = getLowerBound(key);
  508. (where != e) && !compare()(key, where->first);
  509. ++where) {
  510. if (where->second == value) {
  511. impl().erase(where);
  512. return true;
  513. }
  514. }
  515. return false;
  516. }
  517. constexpr bool remove(const Key &key, const Type &value) noexcept {
  518. return remove<Key>(key, value);
  519. }
  520. constexpr iterator erase(const_iterator where) noexcept {
  521. return impl().erase(where._impl);
  522. }
  523. constexpr iterator erase(
  524. const_iterator from,
  525. const_iterator till) noexcept {
  526. return impl().erase(from._impl, till._impl);
  527. }
  528. constexpr int erase(const Key &key) {
  529. return removeAll(key);
  530. }
  531. template <typename OtherKey>
  532. constexpr iterator findFirst(const OtherKey &key) noexcept {
  533. if (empty()
  534. || compare()(key, front().first)
  535. || compare()(back().first, key)) {
  536. return end();
  537. }
  538. auto where = getLowerBound(key);
  539. return compare()(key, where->first) ? impl().end() : where;
  540. }
  541. constexpr iterator findFirst(const Key &key) noexcept {
  542. return findFirst<Key>(key);
  543. }
  544. template <typename OtherKey>
  545. constexpr const_iterator findFirst(const OtherKey &key) const noexcept {
  546. if (empty()
  547. || compare()(key, front().first)
  548. || compare()(back().first, key)) {
  549. return end();
  550. }
  551. auto where = getLowerBound(key);
  552. return compare()(key, where->first) ? impl().end() : where;
  553. }
  554. constexpr const_iterator findFirst(const Key &key) const noexcept {
  555. return findFirst<Key>(key);
  556. }
  557. template <typename OtherKey>
  558. constexpr bool contains(const OtherKey &key) const noexcept {
  559. return findFirst(key) != end();
  560. }
  561. constexpr bool contains(const Key &key) const noexcept {
  562. return contains<Key>(key);
  563. }
  564. template <typename OtherKey>
  565. constexpr int count(const OtherKey &key) const noexcept {
  566. if (empty()
  567. || compare()(key, front().first)
  568. || compare()(back().first, key)) {
  569. return 0;
  570. }
  571. auto range = getEqualRange(key);
  572. return (range.second - range.first);
  573. }
  574. constexpr int count(const Key &key) const noexcept {
  575. return count<Key>(key);
  576. }
  577. template <typename OtherKey>
  578. constexpr iterator lower_bound(const OtherKey &key) noexcept {
  579. return getLowerBound(key);
  580. }
  581. template <typename OtherKey>
  582. constexpr const_iterator lower_bound(
  583. const OtherKey &key) const noexcept {
  584. return getLowerBound(key);
  585. }
  586. template <typename OtherKey>
  587. constexpr iterator upper_bound(const OtherKey &key) noexcept {
  588. return getUpperBound(key);
  589. }
  590. template <typename OtherKey>
  591. constexpr const_iterator upper_bound(
  592. const OtherKey &key) const noexcept {
  593. return getUpperBound(key);
  594. }
  595. template <typename OtherKey>
  596. constexpr std::pair<iterator, iterator> equal_range(
  597. const OtherKey &key) noexcept {
  598. return getEqualRange(key);
  599. }
  600. template <typename OtherKey>
  601. constexpr std::pair<const_iterator, const_iterator> equal_range(
  602. const OtherKey &key) const noexcept {
  603. return getEqualRange(key);
  604. }
  605. private:
  606. friend class flat_map<Key, Type, Compare>;
  607. struct transparent_compare : Compare {
  608. constexpr const Compare &initial() const noexcept {
  609. return *this;
  610. }
  611. template <
  612. typename OtherType1,
  613. typename OtherType2,
  614. typename = std::enable_if_t<
  615. !std::is_same_v<std::decay_t<OtherType1>, pair_type> &&
  616. !std::is_same_v<std::decay_t<OtherType2>, pair_type>>>
  617. constexpr auto operator()(
  618. OtherType1 &&a,
  619. OtherType2 &&b) const noexcept {
  620. return initial()(
  621. std::forward<OtherType1>(a),
  622. std::forward<OtherType2>(b));
  623. }
  624. template <
  625. typename OtherType1,
  626. typename OtherType2>
  627. constexpr auto operator()(
  628. OtherType1 &&a,
  629. OtherType2 &&b) const noexcept -> std::enable_if_t<
  630. std::is_same_v<std::decay_t<OtherType1>, pair_type> &&
  631. std::is_same_v<std::decay_t<OtherType2>, pair_type>, bool> {
  632. return initial()(a.first, b.first);
  633. }
  634. template <
  635. typename OtherType,
  636. typename = std::enable_if_t<
  637. !std::is_same_v<std::decay_t<OtherType>, pair_type>>>
  638. constexpr auto operator()(
  639. const pair_type &a,
  640. OtherType &&b) const noexcept {
  641. return operator()(a.first, std::forward<OtherType>(b));
  642. }
  643. template <
  644. typename OtherType,
  645. typename = std::enable_if_t<
  646. !std::is_same_v<std::decay_t<OtherType>, pair_type>>>
  647. constexpr auto operator()(
  648. OtherType &&a,
  649. const pair_type &b) const noexcept {
  650. return operator()(std::forward<OtherType>(a), b.first);
  651. }
  652. };
  653. struct Data : transparent_compare {
  654. template <typename ...Args>
  655. constexpr Data(Args &&...args) noexcept
  656. : elements(std::forward<Args>(args)...) {
  657. }
  658. impl_t elements;
  659. };
  660. Data _data;
  661. constexpr const transparent_compare &compare() const noexcept {
  662. return _data;
  663. }
  664. constexpr const impl_t &impl() const noexcept {
  665. return _data.elements;
  666. }
  667. constexpr impl_t &impl() noexcept {
  668. return _data.elements;
  669. }
  670. template <typename OtherKey>
  671. constexpr typename impl_t::iterator getLowerBound(
  672. const OtherKey &key) noexcept {
  673. return std::lower_bound(
  674. std::begin(impl()),
  675. std::end(impl()),
  676. key,
  677. compare());
  678. }
  679. template <typename OtherKey>
  680. constexpr typename impl_t::const_iterator getLowerBound(
  681. const OtherKey &key) const noexcept {
  682. return std::lower_bound(
  683. std::begin(impl()),
  684. std::end(impl()),
  685. key,
  686. compare());
  687. }
  688. template <typename OtherKey>
  689. constexpr typename impl_t::iterator getUpperBound(
  690. const OtherKey &key) noexcept {
  691. return std::upper_bound(
  692. std::begin(impl()),
  693. std::end(impl()),
  694. key,
  695. compare());
  696. }
  697. template <typename OtherKey>
  698. constexpr typename impl_t::const_iterator getUpperBound(
  699. const OtherKey &key) const noexcept {
  700. return std::upper_bound(
  701. std::begin(impl()),
  702. std::end(impl()),
  703. key,
  704. compare());
  705. }
  706. template <typename OtherKey>
  707. constexpr std::pair<
  708. typename impl_t::iterator,
  709. typename impl_t::iterator
  710. > getEqualRange(const OtherKey &key) noexcept {
  711. return std::equal_range(
  712. std::begin(impl()),
  713. std::end(impl()),
  714. key,
  715. compare());
  716. }
  717. template <typename OtherKey>
  718. constexpr std::pair<
  719. typename impl_t::const_iterator,
  720. typename impl_t::const_iterator
  721. > getEqualRange(const OtherKey &key) const noexcept {
  722. return std::equal_range(
  723. std::begin(impl()),
  724. std::end(impl()),
  725. key,
  726. compare());
  727. }
  728. };
  729. template <typename Key, typename Type, typename Compare>
  730. class flat_map : private flat_multi_map<Key, Type, Compare> {
  731. using parent = flat_multi_map<Key, Type, Compare>;
  732. using pair_type = typename parent::pair_type;
  733. public:
  734. using value_type = typename parent::value_type;
  735. using size_type = typename parent::size_type;
  736. using difference_type = typename parent::difference_type;
  737. using pointer = typename parent::pointer;
  738. using const_pointer = typename parent::const_pointer;
  739. using reference = typename parent::reference;
  740. using const_reference = typename parent::const_reference;
  741. using iterator = typename parent::iterator;
  742. using const_iterator = typename parent::const_iterator;
  743. using reverse_iterator = typename parent::reverse_iterator;
  744. using const_reverse_iterator = typename parent::const_reverse_iterator;
  745. constexpr flat_map() = default;
  746. template <
  747. typename Iterator,
  748. typename = typename std::iterator_traits<Iterator>::iterator_category
  749. >
  750. constexpr flat_map(Iterator first, Iterator last) noexcept
  751. : parent(first, last) {
  752. finalize();
  753. }
  754. constexpr flat_map(std::initializer_list<pair_type> iter) noexcept
  755. : parent(iter.begin(), iter.end()) {
  756. finalize();
  757. }
  758. using parent::parent;
  759. using parent::size;
  760. using parent::empty;
  761. using parent::clear;
  762. using parent::reserve;
  763. using parent::shrink_to_fit;
  764. using parent::begin;
  765. using parent::end;
  766. using parent::cbegin;
  767. using parent::cend;
  768. using parent::rbegin;
  769. using parent::rend;
  770. using parent::crbegin;
  771. using parent::crend;
  772. using parent::front;
  773. using parent::back;
  774. using parent::erase;
  775. using parent::contains;
  776. using parent::lower_bound;
  777. using parent::upper_bound;
  778. using parent::equal_range;
  779. std::pair<iterator, bool> insert(const value_type &value) {
  780. if (this->empty()
  781. || this->compare()(this->back().first, value.first)) {
  782. this->impl().push_back(value);
  783. return { this->end() - 1, true };
  784. }
  785. auto where = this->getLowerBound(value.first);
  786. if (this->compare()(value.first, where->first)) {
  787. return { this->impl().insert(where, value), true };
  788. }
  789. return { where, false };
  790. }
  791. constexpr std::pair<iterator, bool> insert(value_type &&value) {
  792. if (this->empty() || this->compare()(this->back().first, value.first)) {
  793. this->impl().push_back(std::move(value));
  794. return { this->end() - 1, true };
  795. }
  796. auto where = this->getLowerBound(value.first);
  797. if (this->compare()(value.first, where->first)) {
  798. return { this->impl().insert(where, std::move(value)), true };
  799. }
  800. return { where, false };
  801. }
  802. constexpr std::pair<iterator, bool> insert_or_assign(
  803. const Key &key,
  804. const Type &value) noexcept {
  805. if (this->empty() || this->compare()(this->back().first, key)) {
  806. this->impl().emplace_back(key, value);
  807. return { this->end() - 1, true };
  808. }
  809. auto where = this->getLowerBound(key);
  810. if (this->compare()(key, where->first)) {
  811. return {
  812. this->impl().insert(where, value_type(key, value)),
  813. true
  814. };
  815. }
  816. where->second = value;
  817. return { where, false };
  818. }
  819. constexpr std::pair<iterator, bool> insert_or_assign(
  820. const Key &key,
  821. Type &&value) noexcept {
  822. if (this->empty() || this->compare()(this->back().first, key)) {
  823. this->impl().emplace_back(key, std::move(value));
  824. return { this->end() - 1, true };
  825. }
  826. auto where = this->getLowerBound(key);
  827. if (this->compare()(key, where->first)) {
  828. return {
  829. this->impl().insert(
  830. where,
  831. value_type(key, std::move(value))),
  832. true
  833. };
  834. }
  835. where->second = std::move(value);
  836. return { where, false };
  837. }
  838. template <typename OtherKey, typename... Args>
  839. constexpr std::pair<iterator, bool> emplace(
  840. OtherKey &&key,
  841. Args&&... args) noexcept {
  842. return this->insert(value_type(
  843. std::forward<OtherKey>(key),
  844. Type(std::forward<Args>(args)...)));
  845. }
  846. template <typename... Args>
  847. constexpr std::pair<iterator, bool> emplace_or_assign(
  848. const Key &key,
  849. Args&&... args) noexcept {
  850. return this->insert_or_assign(
  851. key,
  852. Type(std::forward<Args>(args)...));
  853. }
  854. template <typename... Args>
  855. constexpr std::pair<iterator, bool> try_emplace(
  856. const Key &key,
  857. Args&&... args) noexcept {
  858. if (this->empty() || this->compare()(this->back().first, key)) {
  859. this->impl().push_back(value_type(
  860. key,
  861. Type(std::forward<Args>(args)...)));
  862. return { this->end() - 1, true };
  863. }
  864. auto where = this->getLowerBound(key);
  865. if (this->compare()(key, where->first)) {
  866. return {
  867. this->impl().insert(
  868. where,
  869. value_type(
  870. key,
  871. Type(std::forward<Args>(args)...))),
  872. true
  873. };
  874. }
  875. return { where, false };
  876. }
  877. template <typename OtherKey>
  878. constexpr bool remove(const OtherKey &key) noexcept {
  879. return this->removeOne(key);
  880. }
  881. constexpr bool remove(const Key &key) noexcept {
  882. return remove<Key>(key);
  883. }
  884. template <typename OtherKey>
  885. constexpr iterator find(const OtherKey &key) noexcept {
  886. return this->template findFirst<OtherKey>(key);
  887. }
  888. constexpr iterator find(const Key &key) noexcept {
  889. return find<Key>(key);
  890. }
  891. template <typename OtherKey>
  892. constexpr const_iterator find(const OtherKey &key) const noexcept {
  893. return this->template findFirst<OtherKey>(key);
  894. }
  895. constexpr const_iterator find(const Key &key) const noexcept {
  896. return find<Key>(key);
  897. }
  898. constexpr Type &operator[](const Key &key) noexcept {
  899. if (this->empty() || this->compare()(this->back().first, key)) {
  900. this->impl().push_back({ key, Type() });
  901. return this->back().second;
  902. }
  903. auto where = this->getLowerBound(key);
  904. if (this->compare()(key, where->first)) {
  905. return this->impl().insert(where, { key, Type() })->second;
  906. }
  907. return where->second;
  908. }
  909. template <typename OtherKey>
  910. constexpr std::optional<Type> take(const OtherKey &key) noexcept {
  911. auto it = find(key);
  912. if (it == this->end()) {
  913. return std::nullopt;
  914. }
  915. auto result = std::move(it->second);
  916. this->erase(it);
  917. return result;
  918. }
  919. constexpr std::optional<Type> take(const Key &key) noexcept {
  920. return take<Key>(key);
  921. }
  922. friend inline constexpr bool operator<(
  923. const flat_map &a,
  924. const flat_map &b) noexcept {
  925. return static_cast<const parent&>(a) < static_cast<const parent&>(b);
  926. }
  927. friend inline constexpr bool operator>(
  928. const flat_map &a,
  929. const flat_map &b) noexcept {
  930. return static_cast<const parent&>(a) > static_cast<const parent&>(b);
  931. }
  932. friend inline constexpr bool operator<=(
  933. const flat_map &a,
  934. const flat_map &b) noexcept {
  935. return static_cast<const parent&>(a) <= static_cast<const parent&>(b);
  936. }
  937. friend inline constexpr bool operator>=(
  938. const flat_map &a,
  939. const flat_map &b) noexcept {
  940. return static_cast<const parent&>(a) >= static_cast<const parent&>(b);
  941. }
  942. friend inline constexpr bool operator==(
  943. const flat_map &a,
  944. const flat_map &b) noexcept {
  945. return static_cast<const parent&>(a) == static_cast<const parent&>(b);
  946. }
  947. friend inline constexpr bool operator!=(
  948. const flat_map &a,
  949. const flat_map &b) noexcept {
  950. return static_cast<const parent&>(a) != static_cast<const parent&>(b);
  951. }
  952. private:
  953. constexpr void finalize() noexcept {
  954. this->impl().erase(
  955. std::unique(
  956. std::begin(this->impl()),
  957. std::end(this->impl()),
  958. [&](auto &&a, auto &&b) {
  959. return !this->compare()(a, b);
  960. }
  961. ),
  962. std::end(this->impl()));
  963. }
  964. };
  965. } // namespace base
  966. // Structured bindings support.
  967. namespace std {
  968. template <typename Key, typename Value>
  969. class tuple_size<base::flat_multi_map_pair_type<Key, Value>>
  970. : public integral_constant<size_t, 2> {
  971. };
  972. template <typename Key, typename Value>
  973. class tuple_element<0, base::flat_multi_map_pair_type<Key, Value>> {
  974. public:
  975. using type = const Key;
  976. };
  977. template <typename Key, typename Value>
  978. class tuple_element<1, base::flat_multi_map_pair_type<Key, Value>> {
  979. public:
  980. using type = Value;
  981. };
  982. } // namespace std
  983. // Structured bindings support.
  984. namespace base {
  985. namespace details {
  986. template <std::size_t N, typename Key, typename Value>
  987. using flat_multi_map_pair_element = std::tuple_element_t<
  988. N,
  989. flat_multi_map_pair_type<Key, Value>>;
  990. } // namespace details
  991. template <std::size_t N, typename Key, typename Value>
  992. constexpr auto get(base::flat_multi_map_pair_type<Key, Value> &value) noexcept
  993. -> details::flat_multi_map_pair_element<N, Key, Value> & {
  994. if constexpr (N == 0) {
  995. return value.first;
  996. } else {
  997. return value.second;
  998. }
  999. }
  1000. template <std::size_t N, typename Key, typename Value>
  1001. constexpr auto get(
  1002. const base::flat_multi_map_pair_type<Key, Value> &value) noexcept
  1003. -> const details::flat_multi_map_pair_element<N, Key, Value> & {
  1004. if constexpr (N == 0) {
  1005. return value.first;
  1006. } else {
  1007. return value.second;
  1008. }
  1009. }
  1010. } // namespace base