19#include "private/qglobal_p.h"
23#include <initializer_list>
52#ifndef QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT
53# if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
54# define QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT
65template <
class Key,
class T,
class Compare>
77 std::declval<Compare>()(std::declval<const Key &>(), std::declval<const Key &>()));
82 return Compare::operator()(lhs.first, rhs.first);
106template<
class Key,
class T,
class Compare = std::less<Key>,
class KeyContainer = QList<Key>,
107 class MappedContainer = QList<T>>
110 static_assert(std::is_nothrow_destructible_v<T>,
"Types with throwing destructors are not supported in Qt containers.");
122 using size_type =
typename key_container_type::size_type;
149 return {
c->keys[i],
c->values[i] };
159 return c ==
o.c && i ==
o.i;
231 return {
c->keys[k],
c->values[k] };
255 T &
value()
const {
return c->values[i]; }
286 return {
c->keys[i],
c->values[i] };
296 return c ==
o.c && i ==
o.i;
368 return {
c->keys[k],
c->values[k] };
392 const T &
value()
const {
return c->values[i]; }
401 template <
class,
class =
void>
402 struct is_marked_transparent_type : std::false_type { };
405 struct is_marked_transparent_type<
X,
std::void_t<typename X::is_transparent>> : std::true_type { };
408 using is_marked_transparent =
typename std::enable_if<
409 is_marked_transparent_type<X>::value>
::type *;
411 template <
typename It>
412 using is_compatible_iterator =
typename std::enable_if<
413 std::is_same<value_type, typename std::iterator_traits<It>::value_type>
::value>
::type *;
418#ifdef QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT
422 ensureOrderedUnique();
428 ensureOrderedUnique();
434 ensureOrderedUnique();
440 ensureOrderedUnique();
443 explicit QFlatMap(std::initializer_list<value_type> lst)
448 template <
class InputIt, is_compatible_iterator<InputIt> =
nullptr>
451 initWithRange(
first, last);
452 ensureOrderedUnique();
485 template <
class InputIt, is_compatible_iterator<InputIt> =
nullptr>
488 initWithRange(
first, last);
496#ifdef QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT
501 ensureOrderedUnique();
508 ensureOrderedUnique();
515 ensureOrderedUnique();
522 ensureOrderedUnique();
530 template <
class InputIt, is_compatible_iterator<InputIt> =
nullptr>
534 initWithRange(
first, last);
535 ensureOrderedUnique();
569 template <
class InputIt, is_compatible_iterator<InputIt> =
nullptr>
573 initWithRange(
first, last);
579 bool isEmpty() const noexcept {
return c.keys.empty(); }
580 bool empty() const noexcept {
return c.keys.empty(); }
602 template <
class X,
class Y = Compare, is_marked_transparent<Y> =
nullptr>
610 c.values.erase(toValuesIterator(
it));
611 return fromKeysIterator(
c.keys.erase(toKeysIterator(
it)));
619 template <
class X,
class Y = Compare, is_marked_transparent<Y> =
nullptr>
630 template <
class X,
class Y = Compare, is_marked_transparent<Y> =
nullptr>
639 return it ==
end() ? defaultValue :
it.value();
642 template <
class X,
class Y = Compare, is_marked_transparent<Y> =
nullptr>
646 return it ==
end() ? defaultValue :
it.value();
652 return it ==
end() ? T() :
it.value();
655 template <
class X,
class Y = Compare, is_marked_transparent<Y> =
nullptr>
659 return it ==
end() ? T() :
it.value();
677#ifdef QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT
699 template <
typename...Args>
703 if (
it ==
end() || key_compare::operator()(
key,
it.key())) {
704 c.values.emplace(toValuesIterator(
it), std::forward<Args>(
args)...);
705 return { fromKeysIterator(
c.keys.insert(toKeysIterator(
it),
key)),
true };
711 template <
typename...Args>
715 if (
it ==
end() || key_compare::operator()(
key,
it.key())) {
716 c.values.emplace(toValuesIterator(
it), std::forward<Args>(
args)...);
717 return { fromKeysIterator(
c.keys.insert(toKeysIterator(
it), std::move(
key))),
true };
723 template <
typename M>
728 *toValuesIterator(
r.first) = std::forward<M>(
obj);
732 template <
typename M>
737 *toValuesIterator(
r.first) = std::forward<M>(
obj);
741#ifdef QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT
742 template <
class InputIt, is_compatible_iterator<InputIt> =
nullptr>
745 insertRange(
first, last);
752 insertRange(
first, last);
755 template <
class InputIt, is_compatible_iterator<InputIt> =
nullptr>
758 insertOrderedUniqueRange(
first, last);
765 insertOrderedUniqueRange(
first, last);
777 std::reverse_iterator<iterator>
rbegin() {
return std::reverse_iterator<iterator>(
end()); }
778 std::reverse_iterator<const_iterator>
rbegin()
const
780 return std::reverse_iterator<const_iterator>(
end());
783 std::reverse_iterator<iterator>
rend() {
784 return std::reverse_iterator<iterator>(
begin());
786 std::reverse_iterator<const_iterator>
rend()
const
788 return std::reverse_iterator<const_iterator>(
begin());
790 std::reverse_iterator<const_iterator>
crend()
const {
return rend(); }
794 auto cit = std::as_const(*this).lower_bound(
key);
795 return { &
c, cit.i };
798 template <
class X,
class Y = Compare, is_marked_transparent<Y> =
nullptr>
801 auto cit = std::as_const(*this).lower_bound(
key);
802 return { &
c, cit.i };
807 return fromKeysIterator(std::lower_bound(
c.keys.begin(),
c.keys.end(),
key,
key_comp()));
810 template <
class X,
class Y = Compare, is_marked_transparent<Y> =
nullptr>
813 return fromKeysIterator(std::lower_bound(
c.keys.begin(),
c.keys.end(),
key,
key_comp()));
818 return { &
c, std::as_const(*this).find(
key).i };
821 template <
class X,
class Y = Compare, is_marked_transparent<Y> =
nullptr>
824 return { &
c, std::as_const(*this).find(
key).i };
831 if (!key_compare::operator()(
key,
it.key()))
838 template <
class X,
class Y = Compare, is_marked_transparent<Y> =
nullptr>
843 if (!key_compare::operator()(
key,
it.key()))
850 template <
typename Predicate>
853 const auto indirect_call_to_pred = [pred = std::move(pred)](
iterator it) {
854 using Pair =
decltype(*it);
855 using K =
decltype(
it.key());
856 using V =
decltype(
it.value());
858 if constexpr (std::is_invocable_v<P, K, V>) {
859 return pred(
it.key(),
it.value());
860 }
else if constexpr (std::is_invocable_v<P, Pair> && !std::is_invocable_v<P, K>) {
862 }
else if constexpr (std::is_invocable_v<P, K> && !std::is_invocable_v<P, Pair>) {
863 return pred(
it.key());
866 "Don't know how to call the predicate.\n"
869 "- pred(it.key(), it.value())\n"
875 const auto last =
end();
878 while (
first != last && !indirect_call_to_pred(
first))
886 auto kdest = toKeysIterator(
first);
887 auto vdest = toValuesIterator(
first);
891 auto k = std::next(kdest);
892 auto v = std::next(vdest);
905 while (
first != last) {
906 if (!indirect_call_to_pred(
first)) {
908 *kdest = std::move(*k);
909 *vdest = std::move(*
v);
918 const size_type r = std::distance(kdest,
c.keys.end());
919 c.keys.erase(kdest,
c.keys.end());
920 c.values.erase(vdest,
c.values.end());
935 bool do_remove(iterator
it)
944 T do_take(iterator
it)
954 template <
class InputIt, is_compatible_iterator<InputIt> =
nullptr>
955 void initWithRange(InputIt
first, InputIt last)
958 while (
first != last) {
959 c.keys.push_back(
first->first);
960 c.values.push_back(
first->second);
965 iterator fromKeysIterator(
typename key_container_type::iterator kit)
967 return { &
c,
static_cast<size_type>(std::distance(
c.keys.begin(), kit)) };
970 const_iterator fromKeysIterator(
typename key_container_type::const_iterator kit)
const
972 return { &
c,
static_cast<size_type>(std::distance(
c.keys.begin(), kit)) };
975 typename key_container_type::iterator toKeysIterator(iterator
it)
977 return c.keys.begin() +
it.i;
980 typename mapped_container_type::iterator toValuesIterator(iterator
it)
985 template <
class InputIt>
986 void insertRange(InputIt
first, InputIt last)
989 c.keys.resize(
i + std::distance(
first, last));
990 c.values.resize(
c.keys.size());
995 ensureOrderedUnique();
998 class IndexedKeyComparator
1001 IndexedKeyComparator(
const QFlatMap *am)
1008 return m->key_comp()(
m->c.keys[
i],
m->c.keys[k]);
1015 template <
class InputIt>
1016 void insertOrderedUniqueRange(InputIt
first, InputIt last)
1019 c.keys.resize(
s + std::distance(
first, last));
1020 c.values.resize(
c.keys.size());
1026 std::vector<size_type>
p(
size_t(
c.keys.size()));
1027 std::iota(
p.begin(),
p.end(), 0);
1028 std::inplace_merge(
p.begin(),
p.begin() +
s,
p.end(), IndexedKeyComparator(
this));
1029 applyPermutation(
p);
1033 void ensureOrderedUnique()
1035 std::vector<size_type>
p(
size_t(
c.keys.size()));
1036 std::iota(
p.begin(),
p.end(), 0);
1037 std::stable_sort(
p.begin(),
p.end(), IndexedKeyComparator(
this));
1038 applyPermutation(
p);
1042 void applyPermutation(
const std::vector<size_type> &
p)
1045 std::vector<bool>
done(
s);
1065 auto equivalent = [
this](
const auto &lhs,
const auto &rhs) {
1066 return !key_compare::operator()(lhs, rhs) && !key_compare::operator()(rhs, lhs);
1068 const auto kb =
c.keys.begin();
1069 const auto ke =
c.keys.end();
1070 auto k = std::adjacent_find(kb, ke, equivalent);
1075 auto v = std::next(
c.values.begin(), std::distance(kb, k));
1088 while ((++
v, ++k) != ke) {
1089 if (!equivalent(*kdest, *k)) {
1090 *++kdest = std::move(*k);
1091 *++vdest = std::move(*
v);
1095 c.keys.erase(std::next(kdest), ke);
1096 c.values.erase(std::next(vdest),
c.values.end());
1102template<
class Key,
class T, qsizetype N = 256,
class Compare = std::less<Key>>
bool operator()(const value_type &lhs, const value_type &rhs) const noexcept(is_comparator_noexcept)
std::pair< const Key, T > value_type
QFlatMapValueCompare()=default
static constexpr bool is_comparator_noexcept
QFlatMapValueCompare(const Compare &key_compare)
bool operator>=(const const_iterator &other) const
friend const_iterator operator+(size_type n, const const_iterator a)
const_iterator(const containers *ac, size_type ai)
const_iterator & operator-=(size_type n)
const_iterator operator++(int)
bool operator>(const const_iterator &other) const
friend difference_type operator-(const const_iterator b, const const_iterator a)
const_iterator(iterator o)
std::random_access_iterator_tag iterator_category
reference operator*() const
const_iterator & operator++()
bool operator==(const const_iterator &o) const
reference operator[](size_type n) const
pointer operator->() const
bool operator<(const const_iterator &other) const
ptrdiff_t difference_type
bool operator<=(const const_iterator &other) const
bool operator!=(const const_iterator &o) const
const_iterator & operator+=(size_type n)
std::pair< const Key, const T > value_type
friend const_iterator operator-(const const_iterator a, size_type n)
std::pair< const Key &, const T & > reference
friend const_iterator operator+(const const_iterator a, size_type n)
const_iterator & operator--()
const_iterator operator--(int)
iterator(containers *ac, size_type ai)
bool operator>(const iterator &other) const
reference operator[](size_type n) const
iterator & operator-=(size_type n)
std::random_access_iterator_tag iterator_category
friend iterator operator-(const iterator a, size_type n)
friend iterator operator+(size_type n, const iterator a)
pointer operator->() const
bool operator==(const iterator &o) const
reference operator*() const
bool operator>=(const iterator &other) const
bool operator<(const iterator &other) const
std::pair< const Key &, T & > reference
bool operator<=(const iterator &other) const
ptrdiff_t difference_type
bool operator!=(const iterator &o) const
friend iterator operator+(const iterator a, size_type n)
std::pair< const Key, T > value_type
iterator & operator+=(size_type n)
friend difference_type operator-(const iterator b, const iterator a)
bool isEmpty() const noexcept
bool empty() const noexcept
QFlatMap(Qt::OrderedUniqueRange_t, const key_container_type &keys, const mapped_container_type &values, const Compare &compare)
QFlatMap(Qt::OrderedUniqueRange_t, InputIt first, InputIt last)
std::reverse_iterator< const_iterator > crend() const
QFlatMap(const key_container_type &keys, mapped_container_type &&values, const Compare &compare)
size_type count() const noexcept
QFlatMap(key_container_type &&keys, mapped_container_type &&values)
std::pair< iterator, bool > insert_or_assign(const Key &key, M &&obj)
T value(const Key &key) const
const_iterator lower_bound(const X &key) const
const_iterator begin() const
const_iterator lower_bound(const Key &key) const
std::reverse_iterator< const_iterator > rbegin() const
void insert(Qt::OrderedUniqueRange_t, const value_type *first, const value_type *last)
QFlatMap(Qt::OrderedUniqueRange_t, key_container_type &&keys, const mapped_container_type &values, const Compare &compare)
QFlatMap(const Compare &compare)
std::pair< iterator, bool > insert(Key &&key, T &&value)
std::reverse_iterator< const_iterator > crbegin() const
T & operator[](const Key &key)
key_compare key_comp() const noexcept
iterator find(const X &key)
bool contains(const X &key) const
std::pair< iterator, bool > insert(const Key &key, T &&value)
bool contains(const Key &key) const
const_iterator find(const Key &key) const
T value(const X &key) const
std::reverse_iterator< iterator > rbegin()
void insert(Qt::OrderedUniqueRange_t, InputIt first, InputIt last)
iterator erase(iterator it)
const_iterator cbegin() const
iterator lower_bound(const Key &key)
T & operator[](Key &&key)
const key_container_type & keys() const noexcept
typename key_container_type::size_type size_type
QFlatMap(key_container_type &&keys, const mapped_container_type &values)
T value(const X &key, const T &defaultValue) const
size_type remove_if(Predicate pred)
QFlatMap(key_container_type &&keys, const mapped_container_type &values, const Compare &compare)
QFlatMap(Qt::OrderedUniqueRange_t, key_container_type &&keys, mapped_container_type &&values)
const_iterator constBegin() const
iterator find(const Key &key)
QFlatMap(Qt::OrderedUniqueRange_t, std::initializer_list< value_type > lst, const Compare &compare)
bool remove(const Key &key)
const_iterator cend() const
QFlatMap(key_container_type &&keys, mapped_container_type &&values, const Compare &compare)
const_iterator constEnd() const
QFlatMap(Qt::OrderedUniqueRange_t, const key_container_type &keys, mapped_container_type &&values, const Compare &compare)
void insert(const value_type *first, const value_type *last)
typename value_compare::value_type value_type
QFlatMap(Qt::OrderedUniqueRange_t, std::initializer_list< value_type > lst)
QFlatMap(InputIt first, InputIt last)
const mapped_container_type & values() const noexcept
const_iterator find(const X &key) const
void reserve(size_type s)
QFlatMap(const key_container_type &keys, mapped_container_type &&values)
QFlatMap(Qt::OrderedUniqueRange_t, const key_container_type &keys, mapped_container_type &&values)
iterator lower_bound(const X &key)
KeyContainer key_container_type
std::pair< iterator, bool > insert(const Key &key, const T &value)
QFlatMap(Qt::OrderedUniqueRange_t, key_container_type &&keys, const mapped_container_type &values)
MappedContainer mapped_container_type
QFlatMap(InputIt first, InputIt last, const Compare &compare)
T value(const Key &key, const T &defaultValue) const
bool remove(const X &key)
std::reverse_iterator< iterator > rend()
QFlatMap(const key_container_type &keys, const mapped_container_type &values)
std::pair< iterator, bool > try_emplace(Key &&key, Args &&...args)
const_iterator end() const
void insert(InputIt first, InputIt last)
std::pair< iterator, bool > try_emplace(const Key &key, Args &&...args)
QFlatMap(const key_container_type &keys, const mapped_container_type &values, const Compare &compare)
value_compare value_comp() const noexcept
std::reverse_iterator< const_iterator > rend() const
size_type size() const noexcept
size_type capacity() const noexcept
T operator[](const Key &key) const
std::pair< iterator, bool > insert_or_assign(Key &&key, M &&obj)
QFlatMap(std::initializer_list< value_type > lst, const Compare &compare)
QFlatMap(Qt::OrderedUniqueRange_t, const key_container_type &keys, const mapped_container_type &values)
QFlatMap(Qt::OrderedUniqueRange_t, key_container_type &&keys, mapped_container_type &&values, const Compare &compare)
QFlatMap(std::initializer_list< value_type > lst)
QFlatMap(Qt::OrderedUniqueRange_t, InputIt first, InputIt last, const Compare &compare)
std::pair< iterator, bool > insert(Key &&key, const T &value)
QList< T > values() const
QSet< QString >::iterator it
typename C::const_iterator const_iterator
typename C::iterator iterator
Combined button and popup list for selecting options.
void reserveIfForwardIterator(Container *, InputIterator, InputIterator)
constexpr OrderedUniqueRange_t OrderedUniqueRange
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLenum GLsizei GLsizei GLint * values
[15]
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
static int compare(quint64 a, quint64 b)
mapped_container_type values
virtual HRESULT STDMETHODCALLTYPE Compare(__RPC__in_opt ITextRangeProvider *range, __RPC__out BOOL *pRetVal)=0