From 7a8e7213e4fe3a83aff3146c0101bcfb2f925ea2 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 13 Feb 2024 16:18:53 +0100 Subject: [PATCH] QMinimalFlatSet: support custom comparators Add a template argument a la std::set and a ctor taking a Compare object (thus supporting stateful comparators, too), and storing it in QtPrivate::CompactStorage. Rewrite lookup() to use the stored comparator instead of std::less, carefully avoiding a copy to match what std::map implementations do, even though key_comp() itself is specified to return by value. Change-Id: I4f74aaf5eda0a4ed276e99f73f407042c2767828 Reviewed-by: Thiago Macieira Reviewed-by: Fabian Kosmale --- src/corelib/tools/qminimalflatset_p.h | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/corelib/tools/qminimalflatset_p.h b/src/corelib/tools/qminimalflatset_p.h index c6466cf361..6074688f6e 100644 --- a/src/corelib/tools/qminimalflatset_p.h +++ b/src/corelib/tools/qminimalflatset_p.h @@ -16,6 +16,7 @@ // #include +#include // CompactStorage #include //#define QMINIMAL_FLAT_SET_DEBUG @@ -29,7 +30,7 @@ #endif #include // for std::lower_bound -#include // for std::less +#include // for std::less, std::ref QT_BEGIN_NAMESPACE @@ -43,20 +44,26 @@ QT_BEGIN_NAMESPACE bit, we can consider moving it as QFlatSet alongside QFlatMap. */ -template > -class QMinimalFlatSet +template , typename Compare = std::less> +class QMinimalFlatSet : QtPrivate::CompactStorage { Container c; + using CompareStorage = QtPrivate::CompactStorage; public: - // compiler-generated default ctor is ok! - // compiler-generated copy/move ctor/assignment operators are ok! - // compiler-generated dtor is ok! + QMinimalFlatSet() = default; + explicit QMinimalFlatSet(const Compare &cmp) : CompareStorage{cmp} {} + // Rule Of Zero applies using const_iterator = typename Container::const_iterator; using iterator = const_iterator; using const_reverse_iterator = typename Container::const_reverse_iterator; using reverse_iterator = const_reverse_iterator; using value_type = T; + using key_compare = Compare; + using value_compare = Compare; + + key_compare key_comp() const { return this->object(); } + value_compare value_comp() const { return key_comp(); } iterator begin() const { return c.cbegin(); } iterator end() const { return c.cend(); } @@ -121,7 +128,7 @@ private: bool exists; }; - auto cmp = std::less{}; + auto cmp = std::ref(this->object()); // don't let std::lower_bound copy it const auto it = std::lower_bound(c.cbegin(), c.cend(), v, cmp); return R{it, it != c.cend() && !cmp(v, *it)};