QtBase  v6.3.1
qflatmap_p.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2020 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QFLATMAP_P_H
41 #define QFLATMAP_P_H
42 
43 //
44 // W A R N I N G
45 // -------------
46 //
47 // This file is not part of the Qt API. It exists for the convenience
48 // of a number of Qt sources files. This header file may change from
49 // version to version without notice, or even be removed.
50 //
51 // We mean it.
52 //
53 
54 #include "qlist.h"
55 
56 #include <algorithm>
57 #include <functional>
58 #include <initializer_list>
59 #include <iterator>
60 #include <numeric>
61 #include <type_traits>
62 #include <utility>
63 #include <vector>
64 
66 
67 /*
68  QFlatMap provides an associative container backed by sorted sequential
69  containers. By default, QList is used.
70 
71  Keys and values are stored in two separate containers. This provides improved
72  cache locality for key iteration and makes keys() and values() fast
73  operations.
74 
75  One can customize the underlying container type by passing the KeyContainer
76  and MappedContainer template arguments:
77  QFlatMap<float, int, std::less<float>, std::vector<float>, std::vector<int>>
78 */
79 
80 namespace Qt {
81 
84 
85 } // namespace Qt
86 
87 template <class Key, class T, class Compare>
88 class QFlatMapValueCompare : protected Compare
89 {
90 public:
91  QFlatMapValueCompare() = default;
92  QFlatMapValueCompare(const Compare &key_compare)
93  : Compare(key_compare)
94  {
95  }
96 
97  using value_type = std::pair<const Key, T>;
98  static constexpr bool is_comparator_noexcept = noexcept(
99  std::declval<Compare>()(std::declval<Key>(), std::declval<Key>()));
100 
101  bool operator()(const value_type &lhs, const value_type &rhs) const
102  noexcept(is_comparator_noexcept)
103  {
104  return Compare::operator()(lhs.first, rhs.first);
105  }
106 };
107 
108 template<class Key, class T, class Compare = std::less<Key>, class KeyContainer = QList<Key>,
109  class MappedContainer = QList<T>>
110 class QFlatMap : private QFlatMapValueCompare<Key, T, Compare>
111 {
112  static_assert(std::is_nothrow_destructible_v<T>, "Types with throwing destructors are not supported in Qt containers.");
113 
114  template <class U>
115  class mock_pointer
116  {
117  U ref;
118  public:
119  mock_pointer(U r)
120  : ref(r)
121  {
122  }
123 
124  U *operator->()
125  {
126  return &ref;
127  }
128  };
129 
130 public:
131  using key_type = Key;
132  using mapped_type = T;
135  using key_container_type = KeyContainer;
136  using mapped_container_type = MappedContainer;
137  using size_type = typename key_container_type::size_type;
139 
140  struct containers
141  {
144  };
145 
146  class iterator
147  {
148  public:
149  using difference_type = ptrdiff_t;
150  using value_type = std::pair<const Key, T>;
151  using reference = std::pair<const Key &, T &>;
152  using pointer = mock_pointer<reference>;
153  using iterator_category = std::random_access_iterator_tag;
154 
155  iterator() = default;
156 
158  : c(ac), i(ai)
159  {
160  }
161 
163  {
164  return { c->keys[i], c->values[i] };
165  }
166 
168  {
169  return { operator*() };
170  }
171 
172  bool operator==(const iterator &o) const
173  {
174  return c == o.c && i == o.i;
175  }
176 
177  bool operator!=(const iterator &o) const
178  {
179  return !operator==(o);
180  }
181 
183  {
184  ++i;
185  return *this;
186  }
187 
189  {
190 
191  iterator r = *this;
192  ++*this;
193  return r;
194  }
195 
197  {
198  --i;
199  return *this;
200  }
201 
203  {
204  iterator r = *this;
205  --*this;
206  return r;
207  }
208 
210  {
211  i += n;
212  return *this;
213  }
214 
216  {
217  iterator ret = a;
218  return ret += n;
219  }
220 
222  {
223  return n + a;
224  }
225 
227  {
228  i -= n;
229  return *this;
230  }
231 
233  {
234  iterator ret = a;
235  return ret -= n;
236  }
237 
239  {
240  return b.i - a.i;
241  }
242 
244  {
245  size_type k = i + n;
246  return { c->keys[k], c->values[k] };
247  }
248 
249  bool operator<(const iterator &other) const
250  {
251  return i < other.i;
252  }
253 
254  bool operator>(const iterator &other) const
255  {
256  return i > other.i;
257  }
258 
259  bool operator<=(const iterator &other) const
260  {
261  return i <= other.i;
262  }
263 
264  bool operator>=(const iterator &other) const
265  {
266  return i >= other.i;
267  }
268 
269  const Key &key() const { return c->keys[i]; }
270  T &value() const { return c->values[i]; }
271 
272  private:
273  containers *c = nullptr;
274  size_type i = 0;
275  friend QFlatMap;
276  };
277 
279  {
280  public:
281  using difference_type = ptrdiff_t;
282  using value_type = std::pair<const Key, const T>;
283  using reference = std::pair<const Key &, const T &>;
284  using pointer = mock_pointer<reference>;
285  using iterator_category = std::random_access_iterator_tag;
286 
287  const_iterator() = default;
288 
290  : c(ac), i(ai)
291  {
292  }
293 
295  : c(o.c), i(o.i)
296  {
297  }
298 
300  {
301  return { c->keys[i], c->values[i] };
302  }
303 
305  {
306  return { operator*() };
307  }
308 
309  bool operator==(const const_iterator &o) const
310  {
311  return c == o.c && i == o.i;
312  }
313 
314  bool operator!=(const const_iterator &o) const
315  {
316  return !operator==(o);
317  }
318 
320  {
321  ++i;
322  return *this;
323  }
324 
326  {
327 
328  const_iterator r = *this;
329  ++*this;
330  return r;
331  }
332 
334  {
335  --i;
336  return *this;
337  }
338 
340  {
341  const_iterator r = *this;
342  --*this;
343  return r;
344  }
345 
347  {
348  i += n;
349  return *this;
350  }
351 
353  {
354  const_iterator ret = a;
355  return ret += n;
356  }
357 
359  {
360  return n + a;
361  }
362 
364  {
365  i -= n;
366  return *this;
367  }
368 
370  {
371  const_iterator ret = a;
372  return ret -= n;
373  }
374 
376  {
377  return b.i - a.i;
378  }
379 
381  {
382  size_type k = i + n;
383  return { c->keys[k], c->values[k] };
384  }
385 
386  bool operator<(const const_iterator &other) const
387  {
388  return i < other.i;
389  }
390 
391  bool operator>(const const_iterator &other) const
392  {
393  return i > other.i;
394  }
395 
396  bool operator<=(const const_iterator &other) const
397  {
398  return i <= other.i;
399  }
400 
401  bool operator>=(const const_iterator &other) const
402  {
403  return i >= other.i;
404  }
405 
406  const Key &key() const { return c->keys[i]; }
407  const T &value() const { return c->values[i]; }
408 
409  private:
410  const containers *c = nullptr;
411  size_type i = 0;
412  friend QFlatMap;
413  };
414 
415 private:
416  template <class, class = void>
417  struct is_marked_transparent_type : std::false_type { };
418 
419  template <class X>
420  struct is_marked_transparent_type<X, std::void_t<typename X::is_transparent>> : std::true_type { };
421 
422  template <class X>
423  using is_marked_transparent = typename std::enable_if<
425 
426  template <typename It>
427  using is_compatible_iterator = typename std::enable_if<
429 
430 public:
431  QFlatMap() = default;
432 
434  : c{keys, values}
435  {
436  ensureOrderedUnique();
437  }
438 
440  : c{std::move(keys), values}
441  {
442  ensureOrderedUnique();
443  }
444 
446  : c{keys, std::move(values)}
447  {
448  ensureOrderedUnique();
449  }
450 
452  : c{std::move(keys), std::move(values)}
453  {
454  ensureOrderedUnique();
455  }
456 
457  explicit QFlatMap(std::initializer_list<value_type> lst)
458  : QFlatMap(lst.begin(), lst.end())
459  {
460  }
461 
462  template <class InputIt, is_compatible_iterator<InputIt> = nullptr>
463  explicit QFlatMap(InputIt first, InputIt last)
464  {
465  initWithRange(first, last);
466  ensureOrderedUnique();
467  }
468 
471  : c{keys, values}
472  {
473  }
474 
477  : c{std::move(keys), values}
478  {
479  }
480 
483  : c{keys, std::move(values)}
484  {
485  }
486 
489  : c{std::move(keys), std::move(values)}
490  {
491  }
492 
493  explicit QFlatMap(Qt::OrderedUniqueRange_t, std::initializer_list<value_type> lst)
494  : QFlatMap(Qt::OrderedUniqueRange, lst.begin(), lst.end())
495  {
496  }
497 
498  template <class InputIt, is_compatible_iterator<InputIt> = nullptr>
499  explicit QFlatMap(Qt::OrderedUniqueRange_t, InputIt first, InputIt last)
500  {
501  initWithRange(first, last);
502  }
503 
504  explicit QFlatMap(const Compare &compare)
506  {
507  }
508 
510  const Compare &compare)
512  {
513  ensureOrderedUnique();
514  }
515 
517  const Compare &compare)
518  : value_compare(compare), c{std::move(keys), values}
519  {
520  ensureOrderedUnique();
521  }
522 
524  const Compare &compare)
525  : value_compare(compare), c{keys, std::move(values)}
526  {
527  ensureOrderedUnique();
528  }
529 
531  const Compare &compare)
532  : value_compare(compare), c{std::move(keys), std::move(values)}
533  {
534  ensureOrderedUnique();
535  }
536 
537  explicit QFlatMap(std::initializer_list<value_type> lst, const Compare &compare)
538  : QFlatMap(lst.begin(), lst.end(), compare)
539  {
540  }
541 
542  template <class InputIt, is_compatible_iterator<InputIt> = nullptr>
543  explicit QFlatMap(InputIt first, InputIt last, const Compare &compare)
545  {
546  initWithRange(first, last);
547  ensureOrderedUnique();
548  }
549 
553  {
554  }
555 
558  : value_compare(compare), c{std::move(keys), values}
559  {
560  }
561 
564  : value_compare(compare), c{keys, std::move(values)}
565  {
566  }
567 
570  : value_compare(compare), c{std::move(keys), std::move(values)}
571  {
572  }
573 
574  explicit QFlatMap(Qt::OrderedUniqueRange_t, std::initializer_list<value_type> lst,
575  const Compare &compare)
576  : QFlatMap(Qt::OrderedUniqueRange, lst.begin(), lst.end(), compare)
577  {
578  }
579 
580  template <class InputIt, is_compatible_iterator<InputIt> = nullptr>
581  explicit QFlatMap(Qt::OrderedUniqueRange_t, InputIt first, InputIt last, const Compare &compare)
583  {
584  initWithRange(first, last);
585  }
586 
587  size_type count() const noexcept { return c.keys.size(); }
588  size_type size() const noexcept { return c.keys.size(); }
589  size_type capacity() const noexcept { return c.keys.capacity(); }
590  bool isEmpty() const noexcept { return c.keys.empty(); }
591  bool empty() const noexcept { return c.keys.empty(); }
592  containers extract() && { return std::move(c); }
593  const key_container_type &keys() const noexcept { return c.keys; }
594  const mapped_container_type &values() const noexcept { return c.values; }
595 
597  {
598  c.keys.reserve(s);
599  c.values.reserve(s);
600  }
601 
602  void clear()
603  {
604  c.keys.clear();
605  c.values.clear();
606  }
607 
608  bool remove(const Key &key)
609  {
610  return do_remove(find(key));
611  }
612 
613  template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr>
614  bool remove(const X &key)
615  {
616  return do_remove(find(key));
617  }
618 
620  {
621  c.values.erase(toValuesIterator(it));
622  return fromKeysIterator(c.keys.erase(toKeysIterator(it)));
623  }
624 
625  T take(const Key &key)
626  {
627  return do_take(find(key));
628  }
629 
630  template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr>
631  T take(const X &key)
632  {
633  return do_take(find(key));
634  }
635 
636  bool contains(const Key &key) const
637  {
638  return find(key) != end();
639  }
640 
641  template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr>
642  bool contains(const X &key) const
643  {
644  return find(key) != end();
645  }
646 
647  T value(const Key &key, const T &defaultValue) const
648  {
649  auto it = find(key);
650  return it == end() ? defaultValue : it.value();
651  }
652 
653  template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr>
654  T value(const X &key, const T &defaultValue) const
655  {
656  auto it = find(key);
657  return it == end() ? defaultValue : it.value();
658  }
659 
660  T value(const Key &key) const
661  {
662  auto it = find(key);
663  return it == end() ? T() : it.value();
664  }
665 
666  template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr>
667  T value(const X &key) const
668  {
669  auto it = find(key);
670  return it == end() ? T() : it.value();
671  }
672 
673  T &operator[](const Key &key)
674  {
675  return try_emplace(key).first.value();
676  }
677 
679  {
680  return try_emplace(std::move(key)).first.value();
681  }
682 
683  T operator[](const Key &key) const
684  {
685  return value(key);
686  }
687 
688  std::pair<iterator, bool> insert(const Key &key, const T &value)
689  {
690  return insert_or_assign(key, value);
691  }
692 
693  std::pair<iterator, bool> insert(Key &&key, const T &value)
694  {
695  return insert_or_assign(std::move(key), value);
696  }
697 
698  std::pair<iterator, bool> insert(const Key &key, T &&value)
699  {
700  return insert_or_assign(key, std::move(value));
701  }
702 
703  std::pair<iterator, bool> insert(Key &&key, T &&value)
704  {
705  return insert_or_assign(std::move(key), std::move(value));
706  }
707 
708  template <typename...Args>
709  std::pair<iterator, bool> try_emplace(const Key &key, Args&&...args)
710  {
711  auto it = lower_bound(key);
712  if (it == end() || key_compare::operator()(key, it.key())) {
713  c.values.emplace(toValuesIterator(it), std::forward<Args>(args)...);
714  return { fromKeysIterator(c.keys.insert(toKeysIterator(it), key)), true };
715  } else {
716  return {it, false};
717  }
718  }
719 
720  template <typename...Args>
721  std::pair<iterator, bool> try_emplace(Key &&key, Args&&...args)
722  {
723  auto it = lower_bound(key);
724  if (it == end() || key_compare::operator()(key, it.key())) {
725  c.values.emplace(toValuesIterator(it), std::forward<Args>(args)...);
726  return { fromKeysIterator(c.keys.insert(toKeysIterator(it), std::move(key))), true };
727  } else {
728  return {it, false};
729  }
730  }
731 
732  template <typename M>
733  std::pair<iterator, bool> insert_or_assign(const Key &key, M &&obj)
734  {
735  auto r = try_emplace(key, std::forward<M>(obj));
736  if (!r.second)
737  *toValuesIterator(r.first) = std::forward<M>(obj);
738  return r;
739  }
740 
741  template <typename M>
742  std::pair<iterator, bool> insert_or_assign(Key &&key, M &&obj)
743  {
744  auto r = try_emplace(std::move(key), std::forward<M>(obj));
745  if (!r.second)
746  *toValuesIterator(r.first) = std::forward<M>(obj);
747  return r;
748  }
749 
750  template <class InputIt, is_compatible_iterator<InputIt> = nullptr>
751  void insert(InputIt first, InputIt last)
752  {
753  insertRange(first, last);
754  }
755 
756  // ### Merge with the templated version above
757  // once we can use std::disjunction in is_compatible_iterator.
758  void insert(const value_type *first, const value_type *last)
759  {
760  insertRange(first, last);
761  }
762 
763  template <class InputIt, is_compatible_iterator<InputIt> = nullptr>
764  void insert(Qt::OrderedUniqueRange_t, InputIt first, InputIt last)
765  {
766  insertOrderedUniqueRange(first, last);
767  }
768 
769  // ### Merge with the templated version above
770  // once we can use std::disjunction in is_compatible_iterator.
772  {
773  insertOrderedUniqueRange(first, last);
774  }
775 
776  iterator begin() { return { &c, 0 }; }
777  const_iterator begin() const { return { &c, 0 }; }
778  const_iterator cbegin() const { return begin(); }
779  const_iterator constBegin() const { return cbegin(); }
780  iterator end() { return { &c, c.keys.size() }; }
781  const_iterator end() const { return { &c, c.keys.size() }; }
782  const_iterator cend() const { return end(); }
783  const_iterator constEnd() const { return cend(); }
784  std::reverse_iterator<iterator> rbegin() { return std::reverse_iterator<iterator>(end()); }
785  std::reverse_iterator<const_iterator> rbegin() const
786  {
787  return std::reverse_iterator<const_iterator>(end());
788  }
789  std::reverse_iterator<const_iterator> crbegin() const { return rbegin(); }
790  std::reverse_iterator<iterator> rend() {
791  return std::reverse_iterator<iterator>(begin());
792  }
793  std::reverse_iterator<const_iterator> rend() const
794  {
795  return std::reverse_iterator<const_iterator>(begin());
796  }
797  std::reverse_iterator<const_iterator> crend() const { return rend(); }
798 
800  {
801  auto cit = std::as_const(*this).lower_bound(key);
802  return { &c, cit.i };
803  }
804 
805  template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr>
807  {
808  auto cit = std::as_const(*this).lower_bound(key);
809  return { &c, cit.i };
810  }
811 
813  {
814  return fromKeysIterator(std::lower_bound(c.keys.begin(), c.keys.end(), key, key_comp()));
815  }
816 
817  template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr>
819  {
820  return fromKeysIterator(std::lower_bound(c.keys.begin(), c.keys.end(), key, key_comp()));
821  }
822 
824  {
825  return { &c, std::as_const(*this).find(key).i };
826  }
827 
828  template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr>
829  iterator find(const X &key)
830  {
831  return { &c, std::as_const(*this).find(key).i };
832  }
833 
834  const_iterator find(const Key &key) const
835  {
836  auto it = lower_bound(key);
837  if (it != end()) {
838  if (!key_compare::operator()(key, it.key()))
839  return it;
840  it = end();
841  }
842  return it;
843  }
844 
845  template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr>
846  const_iterator find(const X &key) const
847  {
848  auto it = lower_bound(key);
849  if (it != end()) {
850  if (!key_compare::operator()(key, it.key()))
851  return it;
852  it = end();
853  }
854  return it;
855  }
856 
858  {
859  return static_cast<key_compare>(*this);
860  }
861 
863  {
864  return static_cast<value_compare>(*this);
865  }
866 
867 private:
868  bool do_remove(iterator it)
869  {
870  if (it != end()) {
871  erase(it);
872  return true;
873  }
874  return false;
875  }
876 
877  T do_take(iterator it)
878  {
879  if (it != end()) {
880  T result = std::move(it.value());
881  erase(it);
882  return result;
883  }
884  return {};
885  }
886 
887  template <class InputIt, is_compatible_iterator<InputIt> = nullptr>
888  void initWithRange(InputIt first, InputIt last)
889  {
891  while (first != last) {
892  c.keys.push_back(first->first);
893  c.values.push_back(first->second);
894  ++first;
895  }
896  }
897 
898  iterator fromKeysIterator(typename key_container_type::iterator kit)
899  {
900  return { &c, static_cast<size_type>(std::distance(c.keys.begin(), kit)) };
901  }
902 
903  const_iterator fromKeysIterator(typename key_container_type::const_iterator kit) const
904  {
905  return { &c, static_cast<size_type>(std::distance(c.keys.begin(), kit)) };
906  }
907 
908  typename key_container_type::iterator toKeysIterator(iterator it)
909  {
910  return c.keys.begin() + it.i;
911  }
912 
913  typename mapped_container_type::iterator toValuesIterator(iterator it)
914  {
915  return c.values.begin() + it.i;
916  }
917 
918  template <class InputIt>
919  void insertRange(InputIt first, InputIt last)
920  {
921  size_type i = c.keys.size();
922  c.keys.resize(i + std::distance(first, last));
923  c.values.resize(c.keys.size());
924  for (; first != last; ++first, ++i) {
925  c.keys[i] = first->first;
926  c.values[i] = first->second;
927  }
928  ensureOrderedUnique();
929  }
930 
931  class IndexedKeyComparator
932  {
933  public:
934  IndexedKeyComparator(const QFlatMap *am)
935  : m(am)
936  {
937  }
938 
939  bool operator()(size_type i, size_type k) const
940  {
941  return m->key_comp()(m->c.keys[i], m->c.keys[k]);
942  }
943 
944  private:
945  const QFlatMap *m;
946  };
947 
948  template <class InputIt>
949  void insertOrderedUniqueRange(InputIt first, InputIt last)
950  {
951  const size_type s = c.keys.size();
952  c.keys.resize(s + std::distance(first, last));
953  c.values.resize(c.keys.size());
954  for (size_type i = s; first != last; ++first, ++i) {
955  c.keys[i] = first->first;
956  c.values[i] = first->second;
957  }
958 
959  std::vector<size_type> p(size_t(c.keys.size()));
960  std::iota(p.begin(), p.end(), 0);
961  std::inplace_merge(p.begin(), p.begin() + s, p.end(), IndexedKeyComparator(this));
962  applyPermutation(p);
963  makeUnique();
964  }
965 
966  void ensureOrderedUnique()
967  {
968  std::vector<size_type> p(size_t(c.keys.size()));
969  std::iota(p.begin(), p.end(), 0);
970  std::stable_sort(p.begin(), p.end(), IndexedKeyComparator(this));
971  applyPermutation(p);
972  makeUnique();
973  }
974 
975  void applyPermutation(const std::vector<size_type> &p)
976  {
977  const size_type s = c.keys.size();
978  std::vector<bool> done(s);
979  for (size_type i = 0; i < s; ++i) {
980  if (done[i])
981  continue;
982  done[i] = true;
983  size_type j = i;
984  size_type k = p[i];
985  while (i != k) {
986  qSwap(c.keys[j], c.keys[k]);
987  qSwap(c.values[j], c.values[k]);
988  done[k] = true;
989  j = k;
990  k = p[j];
991  }
992  }
993  }
994 
995  void makeUnique()
996  {
997  if (c.keys.size() < 2)
998  return;
999  auto k = std::end(c.keys) - 1;
1000  auto i = k - 1;
1001  for (;;) {
1002  if (key_compare::operator()(*i, *k) || key_compare::operator()(*k, *i)) {
1003  if (i == std::begin(c.keys))
1004  break;
1005  --i;
1006  --k;
1007  } else {
1008  c.values.erase(std::begin(c.values) + std::distance(std::begin(c.keys), i));
1009  i = c.keys.erase(i);
1010  if (i == std::begin(c.keys))
1011  break;
1012  k = i + 1;
1013  }
1014  }
1015  }
1016 
1017  containers c;
1018 };
1019 
1020 template<class Key, class T, qsizetype N = 256, class Compare = std::less<Key>>
1022 
1024 
1025 #endif // QFLATMAP_P_H
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
#define value
[5]
mock_pointer< reference > pointer
Definition: qflatmap_p.h:284
const_iterator & operator+=(size_type n)
Definition: qflatmap_p.h:346
bool operator>=(const const_iterator &other) const
Definition: qflatmap_p.h:401
friend const_iterator operator+(size_type n, const const_iterator a)
Definition: qflatmap_p.h:352
const_iterator(const containers *ac, size_type ai)
Definition: qflatmap_p.h:289
const Key & key() const
Definition: qflatmap_p.h:406
const_iterator operator++(int)
Definition: qflatmap_p.h:325
bool operator>(const const_iterator &other) const
Definition: qflatmap_p.h:391
friend difference_type operator-(const const_iterator b, const const_iterator a)
Definition: qflatmap_p.h:375
const_iterator(iterator o)
Definition: qflatmap_p.h:294
std::random_access_iterator_tag iterator_category
Definition: qflatmap_p.h:285
const_iterator & operator++()
Definition: qflatmap_p.h:319
reference operator*() const
Definition: qflatmap_p.h:299
const_iterator & operator-=(size_type n)
Definition: qflatmap_p.h:363
bool operator==(const const_iterator &o) const
Definition: qflatmap_p.h:309
reference operator[](size_type n) const
Definition: qflatmap_p.h:380
pointer operator->() const
Definition: qflatmap_p.h:304
bool operator<(const const_iterator &other) const
Definition: qflatmap_p.h:386
bool operator<=(const const_iterator &other) const
Definition: qflatmap_p.h:396
bool operator!=(const const_iterator &o) const
Definition: qflatmap_p.h:314
std::pair< const Key, const T > value_type
Definition: qflatmap_p.h:282
friend const_iterator operator-(const const_iterator a, size_type n)
Definition: qflatmap_p.h:369
std::pair< const Key &, const T & > reference
Definition: qflatmap_p.h:283
friend const_iterator operator+(const const_iterator a, size_type n)
Definition: qflatmap_p.h:358
const_iterator & operator--()
Definition: qflatmap_p.h:333
const T & value() const
Definition: qflatmap_p.h:407
const_iterator operator--(int)
Definition: qflatmap_p.h:339
iterator(containers *ac, size_type ai)
Definition: qflatmap_p.h:157
bool operator>(const iterator &other) const
Definition: qflatmap_p.h:254
iterator & operator-=(size_type n)
Definition: qflatmap_p.h:226
T & value() const
Definition: qflatmap_p.h:270
reference operator[](size_type n) const
Definition: qflatmap_p.h:243
iterator & operator+=(size_type n)
Definition: qflatmap_p.h:209
iterator operator--(int)
Definition: qflatmap_p.h:202
std::random_access_iterator_tag iterator_category
Definition: qflatmap_p.h:153
const Key & key() const
Definition: qflatmap_p.h:269
iterator & operator++()
Definition: qflatmap_p.h:182
iterator & operator--()
Definition: qflatmap_p.h:196
friend iterator operator-(const iterator a, size_type n)
Definition: qflatmap_p.h:232
friend iterator operator+(size_type n, const iterator a)
Definition: qflatmap_p.h:215
pointer operator->() const
Definition: qflatmap_p.h:167
bool operator==(const iterator &o) const
Definition: qflatmap_p.h:172
reference operator*() const
Definition: qflatmap_p.h:162
bool operator>=(const iterator &other) const
Definition: qflatmap_p.h:264
bool operator<(const iterator &other) const
Definition: qflatmap_p.h:249
std::pair< const Key &, T & > reference
Definition: qflatmap_p.h:151
bool operator<=(const iterator &other) const
Definition: qflatmap_p.h:259
ptrdiff_t difference_type
Definition: qflatmap_p.h:149
bool operator!=(const iterator &o) const
Definition: qflatmap_p.h:177
mock_pointer< reference > pointer
Definition: qflatmap_p.h:152
iterator operator++(int)
Definition: qflatmap_p.h:188
friend iterator operator+(const iterator a, size_type n)
Definition: qflatmap_p.h:221
std::pair< const Key, T > value_type
Definition: qflatmap_p.h:150
friend difference_type operator-(const iterator b, const iterator a)
Definition: qflatmap_p.h:238
std::reverse_iterator< const_iterator > crbegin() const
Definition: qflatmap_p.h:789
std::reverse_iterator< const_iterator > rend() const
Definition: qflatmap_p.h:793
std::pair< iterator, bool > insert_or_assign(Key &&key, M &&obj)
Definition: qflatmap_p.h:742
bool isEmpty() const noexcept
Definition: qflatmap_p.h:590
bool empty() const noexcept
Definition: qflatmap_p.h:591
std::reverse_iterator< iterator > rend()
Definition: qflatmap_p.h:790
QFlatMap(Qt::OrderedUniqueRange_t, const key_container_type &keys, const mapped_container_type &values, const Compare &compare)
Definition: qflatmap_p.h:550
QFlatMap(Qt::OrderedUniqueRange_t, InputIt first, InputIt last)
Definition: qflatmap_p.h:499
std::reverse_iterator< const_iterator > rbegin() const
Definition: qflatmap_p.h:785
containers extract() &&
Definition: qflatmap_p.h:592
QFlatMap(const key_container_type &keys, mapped_container_type &&values, const Compare &compare)
Definition: qflatmap_p.h:523
size_type count() const noexcept
Definition: qflatmap_p.h:587
QFlatMap(key_container_type &&keys, mapped_container_type &&values)
Definition: qflatmap_p.h:451
T & operator[](Key &&key)
Definition: qflatmap_p.h:678
T value(const Key &key) const
Definition: qflatmap_p.h:660
const_iterator lower_bound(const X &key) const
Definition: qflatmap_p.h:818
std::pair< iterator, bool > insert_or_assign(const Key &key, M &&obj)
Definition: qflatmap_p.h:733
const_iterator begin() const
Definition: qflatmap_p.h:777
Key key_type
Definition: qflatmap_p.h:131
const mapped_container_type & values() const noexcept
Definition: qflatmap_p.h:594
std::reverse_iterator< const_iterator > crend() const
Definition: qflatmap_p.h:797
iterator begin()
Definition: qflatmap_p.h:776
const_iterator lower_bound(const Key &key) const
Definition: qflatmap_p.h:812
void insert(Qt::OrderedUniqueRange_t, const value_type *first, const value_type *last)
Definition: qflatmap_p.h:771
QFlatMap(Qt::OrderedUniqueRange_t, key_container_type &&keys, const mapped_container_type &values, const Compare &compare)
Definition: qflatmap_p.h:556
QFlatMap(const Compare &compare)
Definition: qflatmap_p.h:504
std::pair< iterator, bool > try_emplace(Key &&key, Args &&...args)
Definition: qflatmap_p.h:721
std::reverse_iterator< iterator > rbegin()
Definition: qflatmap_p.h:784
key_compare key_comp() const noexcept
Definition: qflatmap_p.h:857
iterator find(const X &key)
Definition: qflatmap_p.h:829
bool contains(const X &key) const
Definition: qflatmap_p.h:642
Compare key_compare
Definition: qflatmap_p.h:138
iterator end()
Definition: qflatmap_p.h:780
bool contains(const Key &key) const
Definition: qflatmap_p.h:636
const_iterator find(const Key &key) const
Definition: qflatmap_p.h:834
T value(const X &key) const
Definition: qflatmap_p.h:667
void insert(Qt::OrderedUniqueRange_t, InputIt first, InputIt last)
Definition: qflatmap_p.h:764
iterator erase(iterator it)
Definition: qflatmap_p.h:619
const_iterator cbegin() const
Definition: qflatmap_p.h:778
iterator lower_bound(const Key &key)
Definition: qflatmap_p.h:799
const key_container_type & keys() const noexcept
Definition: qflatmap_p.h:593
typename key_container_type::size_type size_type
Definition: qflatmap_p.h:137
QFlatMap(key_container_type &&keys, const mapped_container_type &values)
Definition: qflatmap_p.h:439
T value(const X &key, const T &defaultValue) const
Definition: qflatmap_p.h:654
QFlatMap(key_container_type &&keys, const mapped_container_type &values, const Compare &compare)
Definition: qflatmap_p.h:516
QFlatMap(Qt::OrderedUniqueRange_t, key_container_type &&keys, mapped_container_type &&values)
Definition: qflatmap_p.h:487
const_iterator constBegin() const
Definition: qflatmap_p.h:779
iterator find(const Key &key)
Definition: qflatmap_p.h:823
QFlatMap(Qt::OrderedUniqueRange_t, std::initializer_list< value_type > lst, const Compare &compare)
Definition: qflatmap_p.h:574
std::pair< iterator, bool > insert(Key &&key, const T &value)
Definition: qflatmap_p.h:693
bool remove(const Key &key)
Definition: qflatmap_p.h:608
const_iterator cend() const
Definition: qflatmap_p.h:782
QFlatMap()=default
QFlatMap(key_container_type &&keys, mapped_container_type &&values, const Compare &compare)
Definition: qflatmap_p.h:530
T & operator[](const Key &key)
Definition: qflatmap_p.h:673
const_iterator constEnd() const
Definition: qflatmap_p.h:783
QFlatMap(Qt::OrderedUniqueRange_t, const key_container_type &keys, mapped_container_type &&values, const Compare &compare)
Definition: qflatmap_p.h:562
void insert(const value_type *first, const value_type *last)
Definition: qflatmap_p.h:758
typename value_compare::value_type value_type
Definition: qflatmap_p.h:134
QFlatMap(Qt::OrderedUniqueRange_t, std::initializer_list< value_type > lst)
Definition: qflatmap_p.h:493
QFlatMap(InputIt first, InputIt last)
Definition: qflatmap_p.h:463
const_iterator find(const X &key) const
Definition: qflatmap_p.h:846
void reserve(size_type s)
Definition: qflatmap_p.h:596
std::pair< iterator, bool > insert(const Key &key, T &&value)
Definition: qflatmap_p.h:698
T take(const Key &key)
Definition: qflatmap_p.h:625
std::pair< iterator, bool > try_emplace(const Key &key, Args &&...args)
Definition: qflatmap_p.h:709
QFlatMap(const key_container_type &keys, mapped_container_type &&values)
Definition: qflatmap_p.h:445
std::pair< iterator, bool > insert(Key &&key, T &&value)
Definition: qflatmap_p.h:703
QFlatMap(Qt::OrderedUniqueRange_t, const key_container_type &keys, mapped_container_type &&values)
Definition: qflatmap_p.h:481
iterator lower_bound(const X &key)
Definition: qflatmap_p.h:806
KeyContainer key_container_type
Definition: qflatmap_p.h:135
QFlatMap(Qt::OrderedUniqueRange_t, key_container_type &&keys, const mapped_container_type &values)
Definition: qflatmap_p.h:475
MappedContainer mapped_container_type
Definition: qflatmap_p.h:136
QFlatMap(InputIt first, InputIt last, const Compare &compare)
Definition: qflatmap_p.h:543
T value(const Key &key, const T &defaultValue) const
Definition: qflatmap_p.h:647
bool remove(const X &key)
Definition: qflatmap_p.h:614
QFlatMap(const key_container_type &keys, const mapped_container_type &values)
Definition: qflatmap_p.h:433
void clear()
Definition: qflatmap_p.h:602
const_iterator end() const
Definition: qflatmap_p.h:781
void insert(InputIt first, InputIt last)
Definition: qflatmap_p.h:751
QFlatMap(const key_container_type &keys, const mapped_container_type &values, const Compare &compare)
Definition: qflatmap_p.h:509
value_compare value_comp() const noexcept
Definition: qflatmap_p.h:862
T take(const X &key)
Definition: qflatmap_p.h:631
size_type size() const noexcept
Definition: qflatmap_p.h:588
size_type capacity() const noexcept
Definition: qflatmap_p.h:589
T operator[](const Key &key) const
Definition: qflatmap_p.h:683
QFlatMap(std::initializer_list< value_type > lst, const Compare &compare)
Definition: qflatmap_p.h:537
QFlatMap(Qt::OrderedUniqueRange_t, const key_container_type &keys, const mapped_container_type &values)
Definition: qflatmap_p.h:469
QFlatMap(Qt::OrderedUniqueRange_t, key_container_type &&keys, mapped_container_type &&values, const Compare &compare)
Definition: qflatmap_p.h:568
std::pair< iterator, bool > insert(const Key &key, const T &value)
Definition: qflatmap_p.h:688
QFlatMap(std::initializer_list< value_type > lst)
Definition: qflatmap_p.h:457
QFlatMap(Qt::OrderedUniqueRange_t, InputIt first, InputIt last, const Compare &compare)
Definition: qflatmap_p.h:581
bool operator()(const value_type &lhs, const value_type &rhs) const noexcept(is_comparator_noexcept)
Definition: qflatmap_p.h:101
std::pair< const Key, T > value_type
Definition: qflatmap_p.h:97
QFlatMapValueCompare()=default
static constexpr bool is_comparator_noexcept
Definition: qflatmap_p.h:98
QFlatMapValueCompare(const Compare &key_compare)
Definition: qflatmap_p.h:92
#define T(x)
Definition: main.cpp:42
qSwap(pi, e)
constexpr T & operator()(T &v) const
Definition: hb-algs.hh:2
auto it unsigned count const
Definition: hb-iter.hh:848
typename C::value_type value_type
typename C::const_iterator const_iterator
typename C::iterator iterator
Definition: qnamespace.h:55
constexpr OrderedUniqueRange_t OrderedUniqueRange
Definition: qflatmap_p.h:83
void reserveIfForwardIterator(Container *, InputIterator, InputIterator)
Definition: qfloat16.h:381
int distance(TestIterator &a, TestIterator &b)
EGLOutputLayerEXT EGLint EGLAttrib value
QT_BEGIN_NAMESPACE bool done
GLenum type
Definition: qopengl.h:270
GLenum GLsizei GLsizei GLint * values
[16]
GLboolean GLboolean GLboolean b
const GLfloat * m
GLuint64 key
GLboolean r
[2]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLuint end
GLint ref
GLint first
GLfloat n
GLhandleARB obj
[2]
Definition: qopenglext.h:4164
const GLubyte * c
Definition: qopenglext.h:12701
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLdouble s
[6]
Definition: qopenglext.h:235
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
QSharedPointer< T > other(t)
[5]
QStringList::Iterator it
Definition: main.cpp:58
mapped_container_type values
Definition: qflatmap_p.h:143
key_container_type keys
Definition: qflatmap_p.h:142
Definition: main.cpp:38
void compare(Input input, FnUnderTest fn_under_test, const QByteArray &output)
#define rhs
virtual HRESULT STDMETHODCALLTYPE Compare(__RPC__in_opt ITextRangeProvider *range, __RPC__out BOOL *pRetVal)=0