9 #include <QtCore/QDebug>
10 #include <QtCore/QElapsedTimer>
11 #include <QtCore/QHashFunctions>
12 #include <QtCore/QLatin1String>
13 #include <QtCore/QUrl>
17 #include <source_location>
18 #include <unordered_map>
20 #define DECL_DEPRECATED_ENUMERATOR(Deprecated, Recommended)
21 Deprecated Q_DECL_ENUMERATOR_DEPRECATED_X("Use " #Recommended) = Recommended
37 #define SLICE(Object, ToType) ToType{static_cast<const ToType&>(Object)}
43 constexpr inline auto toUtf8(S&& s)
45 if constexpr (std::convertible_to<S, std::string_view>)
46 return std::string_view(std::forward<S>(s));
47 else if constexpr (std::convertible_to<S, QByteArray>)
48 return QByteArray(std::forward<S>(s));
50 return QString(std::forward<S>(s)).toUtf8();
61 #define QUO_CSTR(StringConvertible_) std::data(::Quotient::_impl::toUtf8(StringConvertible_))
63 inline bool alarmX(
bool alarmCondition,
const auto& msg,
66 if (alarmCondition) [[unlikely]] {
67 qt_assert_x(loc.function_name(),
QUO_CSTR(msg), loc.file_name(), loc.line());
70 return alarmCondition;
83 #define QUO_ALARM_X(...) ::Quotient::alarmX(__VA_ARGS__)
85 #define QUO_ALARM(...) ::Quotient::alarmX((__VA_ARGS__) ? true : false, "Alarm: " #__VA_ARGS__)
88 #define QUO_CHECK(...)
89 !::Quotient::alarmX(!(__VA_ARGS__) ? true : false, "Failing expression: " #__VA_ARGS__)
91 #if Quotient_VERSION_MAJOR == 0
&& Quotient_VERSION_MINOR < 10
101 template <
typename KeyT,
typename ValT>
103 [[deprecated(
"Use std::unordered_map directly")]] = std::unordered_map<KeyT, ValT, HashQ<KeyT>>;
107 #if Quotient_VERSION_MAJOR == 0
&& Quotient_VERSION_MINOR > 9
108 [[deprecated(
"Use operators from Qt::Literals (aka Quotient::Literals) instead")]]
110 constexpr auto operator""_ls(
const char* s, std::size_t size)
112 return operator
""_L1(s, size);
115 template <
typename ArrayT>
116 class [[deprecated(
"Use std::ranges::subrange instead")]]
Range {
117 using iterator =
typename ArrayT::iterator;
118 using const_iterator =
typename ArrayT::const_iterator;
119 using size_type =
typename ArrayT::size_type;
122 constexpr Range(ArrayT& arr) : from(std::begin(arr)), to(std::end(arr)) {}
123 constexpr Range(iterator from, iterator to) : from(from), to(to) {}
125 constexpr size_type
size()
const
127 Q_ASSERT(std::distance(from, to) >= 0);
128 return size_type(std::distance(from, to));
130 constexpr bool empty()
const {
return from == to; }
131 constexpr const_iterator
begin()
const {
return from; }
132 constexpr const_iterator
end()
const {
return to; }
133 constexpr iterator
begin() {
return from; }
134 constexpr iterator
end() {
return to; }
142 template <
typename T>
143 concept Holds_NonConst_LValue_Ref =
144 std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference<T>>;
160 template <
typename T>
162 "Use the member function with the same name of the respective container")]]
asKeyValueRange {
185 template <
typename U>
186 asKeyValueRange(U&) -> asKeyValueRange<U&>;
188 template <
typename U>
189 asKeyValueRange(U&&) -> asKeyValueRange<U>;
198 template <
typename InputIt,
typename ForwardIt,
typename Pred>
199 inline std::pair<InputIt, ForwardIt> findFirstOf(InputIt first, InputIt last,
201 ForwardIt sLast, Pred pred)
203 for (; first != last; ++first)
204 for (
auto it = sFirst; it != sLast; ++it)
205 if (pred(*first, *it))
206 return { first, it };
208 return { last, sLast };
217 template <
typename ImplType,
typename TypeToDelete = ImplType>
218 using ImplPtr = std::unique_ptr<ImplType,
void (*)(TypeToDelete*)>;
238 template <
typename ImplType,
typename TypeToDelete = ImplType,
typename... ArgTs>
241 return ImplPtr<ImplType, TypeToDelete> {
242 new ImplType{std::forward<ArgTs>(args)...},
243 [](TypeToDelete* impl) {
delete impl; }
247 template <
typename ImplType,
typename TypeToDelete = ImplType>
250 return ImplPtr<ImplType, TypeToDelete> { from, [](TypeToDelete* impl) {
255 template <
typename ImplType,
typename TypeToDelete = ImplType>
258 return {
nullptr, [](TypeToDelete*) { } };
261 template <
typename T>
263 size_t (*destructor)(T*);
267 destructor(toDelete);
268 delete[]
reinterpret_cast<std::byte*>(toDelete);
276 template <
typename T>
289 template <
typename T>
290 inline auto makeCStruct(T* (*constructor)(
void*), size_t (*sizeFn)(),
293 return CStructPtr<T>{ constructor(
new std::byte[sizeFn()]), { destructor } };
301 template <
typename... FunctorTs>
302 struct Overloads : FunctorTs... {
303 using FunctorTs::operator()...;
306 template <
typename... FunctorTs>
307 Overloads(FunctorTs&&...) -> Overloads<FunctorTs...>;
357 inline QDebug formatJson(QDebug dbg) {
return dbg.noquote(); }
360 inline QDebug terse(QDebug dbg)
362 return dbg.verbosity(QDebug::MinimumVerbosity);
365 constexpr qint64 ProfilerMinNsecs =
366 #ifdef PROFILER_LOG_USECS
379 inline QDebug operator<<(QDebug dbg, std::invocable<QDebug>
auto manipFn)
381 return std::invoke(manipFn, dbg);
384 inline QDebug operator<<(QDebug dbg, QElapsedTimer et)
387 dbg <<
static_cast<
double>(et.nsecsElapsed() / 1000) / 1000
404 template <
typename FnT>
405 inline auto lift(FnT&& fn,
auto&&... args)
407 if constexpr (std::is_void_v<std::invoke_result_t<FnT,
decltype(*args)...>>) {
408 if ((... &&
bool(args)))
409 std::invoke(std::forward<FnT>(fn), *args...);
411 return (... &&
bool(args))
412 ? std::optional(std::invoke(std::forward<FnT>(fn), *args...))
422 template <
typename T1,
typename T2>
423 requires std::is_assignable_v<T1&,
const T2&>
424 constexpr inline bool merge(T1& lhs,
const std::optional<T2>& rhs)
426 if (!rhs || lhs == *rhs)
438 template <
typename StructT>
439 constexpr inline size_t mergeStruct(StructT& lhs,
const StructT& rhs,
const auto... fields)
441 return ((... +
static_cast<size_t>(merge(lhs.*fields, rhs.*fields))));
448 using UserId = QString;
449 using RoomId = QString;
450 using EventId = QString;
456 QByteArray accessToken = {};
457 QStringList supportedSpecVersions = {};
459 bool checkMatrixSpecVersion(QStringView targetVersion)
const;