Files
tdesktop/Telegram/lib_base/base/qt/qt_compare.h
allhaileris afb81b8278
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Close stale issues and PRs / stale (push) Successful in 13s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
init
2026-02-16 15:50:16 +03:00

113 lines
3.1 KiB
C++

// This file is part of Desktop App Toolkit,
// a set of libraries for developing nice desktop applications.
//
// For license and copyright information please follow this link:
// https://github.com/desktop-app/legal/blob/master/LEGAL
//
#pragma once
#include <compare>
#include <variant>
#include <gsl/pointers>
#include <QString>
#if !defined(__apple_build_version__) || (__apple_build_version__ > 12000032)
template <typename P>
[[nodiscard]] inline std::strong_ordering operator<=>(
const gsl::not_null<P> &a,
const gsl::not_null<P> &b) noexcept {
return a.get() <=> b.get();
}
#if QT_VERSION < QT_VERSION_CHECK(6, 8, 0) || !defined __cpp_lib_three_way_comparison
[[nodiscard]] inline std::strong_ordering operator<=>(
const QString &a,
const QString &b) noexcept {
return a.compare(b) <=> 0;
}
#endif // Qt < 6.8.0 || !__cpp_lib_three_way_comparison
template <typename T>
[[nodiscard]] inline std::strong_ordering operator<=>(
const QVector<T> &a,
const QVector<T> &b) noexcept {
const auto as = a.size();
const auto bs = b.size();
const auto s = int(std::min(as, bs));
for (auto i = 0; i != s; ++i) {
const auto result = (a[i] <=> b[i]);
if (result != std::strong_ordering::equal
&& result != std::strong_ordering::equivalent) {
return result;
}
}
return (as <=> bs);
}
#ifndef _MSC_VER
namespace base::details {
template <typename T>
using compare_three_way_result_t = decltype(
(std::declval<const std::remove_reference_t<T>&>()
<=> std::declval<const std::remove_reference_t<T>&>()));
template <typename ...Types>
using variant_compare_result = std::common_comparison_category_t<
compare_three_way_result_t<Types>...>;
template <int Index, typename ...Types>
constexpr variant_compare_result<Types...> variant_comparator(
const std::variant<Types...> &a,
const std::variant<Types...> &b,
int index) {
if (index == Index) {
return *std::get_if<Index>(&a) <=> *std::get_if<Index>(&b);
} else if constexpr (Index + 1 < sizeof...(Types)) {
return variant_comparator<Index + 1>(a, b, index);
} else {
Unexpected("Index value in variant_comparator.");
}
}
} // namespace base::details
template <typename ...Types>
inline constexpr auto operator<=>(
const std::variant<Types...> &a,
const std::variant<Types...> &b)
-> base::details::variant_compare_result<Types...> {
const auto index = a.index();
if (const auto result = (index <=> b.index())
; result != std::strong_ordering::equal) {
return result;
}
return base::details::variant_comparator<0>(a, b, index);
}
template <typename Type, typename Result = decltype(std::declval<Type>() <=> std::declval<Type>())>
inline constexpr auto operator<=>(
const std::vector<Type> &a,
const std::vector<Type> &b) -> Result {
const auto asize = a.size();
const auto bsize = b.size();
const auto min = std::min(asize, bsize);
for (auto i = std::size_t(); i != min; ++i) {
const auto result = (a[i] <=> b[i]);
if (result != Result::equivalent) {
return result;
}
}
if (asize < bsize) {
return Result::less;
} else if (asize > bsize) {
return Result::greater;
}
return Result::equivalent;
}
#endif // _MSC_VER
#endif // __apple_build_version__