9#include <QtCore/QDebug>
10#include <QtCore/QElapsedTimer>
11#include <QtCore/QFuture>
12#include <QtCore/QHashFunctions>
13#include <QtCore/QLatin1String>
14#include <QtCore/QScopedPointer>
19#include <source_location>
20#include <unordered_map>
22#define DECL_DEPRECATED_ENUMERATOR(Deprecated, Recommended)
23 Deprecated Q_DECL_ENUMERATOR_DEPRECATED_X("Use " #Recommended) = Recommended
39#define SLICE(Object, ToType) ToType{static_cast<const ToType&>(Object)}
45 constexpr inline auto toUtf8(S&& s)
47 if constexpr (std::convertible_to<S, std::string_view>)
48 return std::string_view(std::forward<S>(s));
49 else if constexpr (std::convertible_to<S, QByteArray>)
50 return QByteArray(std::forward<S>(s));
52 return QString(std::forward<S>(s)).toUtf8();
63#define QUO_CSTR(StringConvertible_) std::data(::Quotient::_impl::toUtf8(StringConvertible_))
65inline bool alarmX(
bool alarmCondition,
const auto& msg,
bool invertReturnValue =
false,
68 if (alarmCondition) [[unlikely]] {
69 qt_assert_x(loc.function_name(),
QUO_CSTR(msg), loc.file_name(), loc.line());
72 return alarmCondition != invertReturnValue;
85#define QUO_ALARM_X(...) ::Quotient::alarmX(__VA_ARGS__)
87#define QUO_ALARM(...) ::Quotient::alarmX((__VA_ARGS__) ? true : false, "Alarm: " #__VA_ARGS__)
91 ::Quotient::alarmX((__VA_ARGS__) ? false : true, "Failing expression: " #__VA_ARGS__, true)
94[[
deprecated(
"Use QtFuture::makeReadyVoidFuture() directly")]]
97 return QtFuture::makeReadyVoidFuture();
102[[deprecated(
"Use QtFuture::makeReadyValueFuture() directly")]]
105 return QtFuture::makeReadyValueFuture(std::forward<T>(value));
111
112
113
114
115template <
typename InputIt,
typename ForwardIt>
116inline std::pair<InputIt, ForwardIt>
findFirstOf(InputIt first, InputIt last,
118 ForwardIt sLast,
auto pred)
120 for (; first != last; ++first)
121 for (
auto it = sFirst; it != sLast; ++it)
122 if (pred(*first, *it))
123 return { first, it };
125 return { last, sLast };
143template <
typename ImplType,
typename TypeToDelete = ImplType>
144using ImplPtr = std::unique_ptr<ImplType,
void (*)(TypeToDelete*)>;
164template <
typename ImplType,
typename TypeToDelete = ImplType,
typename... ArgTs>
167 return ImplPtr<ImplType, TypeToDelete> {
168 new ImplType{std::forward<ArgTs>(args)...},
169 [](TypeToDelete* impl) {
delete impl; }
173template <
typename ImplType,
typename TypeToDelete = ImplType>
176 return ImplPtr<ImplType, TypeToDelete> { from, [](TypeToDelete* impl) {
181template <
typename ImplType,
typename TypeToDelete = ImplType>
184 return {
nullptr, [](TypeToDelete*) { } };
189 size_t (*destructor)(T*);
193 destructor(toDelete);
194 delete[]
reinterpret_cast<std::byte*>(toDelete);
216inline auto makeCStruct(T* (*constructor)(
void*), size_t (*sizeFn)(),
219 return CStructPtr<T>{ constructor(
new std::byte[sizeFn()]), { destructor } };
227template <
typename... FunctorTs>
229 using FunctorTs::operator()...;
232template <
typename... FunctorTs>
239
240
241
245
246
247
251
252
253
254
258
259
260
261
262
263
288 return dbg.verbosity(QDebug::MinimumVerbosity);
292#ifdef PROFILER_LOG_USECS
307 return std::invoke(manipFn, dbg);
313 dbg <<
static_cast<
double>(et.nsecsElapsed() / 1000) / 1000
330template <
typename FnT>
331inline auto lift(FnT&& fn,
auto&&... args)
333 if constexpr (std::is_void_v<std::invoke_result_t<FnT,
decltype(*args)...>>) {
334 if ((... &&
bool(args)))
335 std::invoke(std::forward<FnT>(fn), *args...);
337 return (... &&
bool(args))
338 ? std::optional(std::invoke(std::forward<FnT>(fn), *args...))
348template <
typename T1,
typename T2>
349 requires std::is_assignable_v<T1&,
const T2&>
350constexpr inline bool merge(T1& lhs,
const std::optional<T2>& rhs)
352 if (!rhs || lhs == *rhs)
364template <
typename StructT>
365constexpr inline size_t
mergeStruct(StructT& lhs,
const StructT& rhs,
const auto... fields)
367 return ((... +
static_cast<size_t>(merge(lhs.*fields, rhs.*fields))));
QUOTIENT_API bool isGuestUserId(const UserId &uId)
auto lift(FnT &&fn, auto &&... args)
Lift an operation into dereferenceable types (std::optional or pointers)
auto makeReadyValueFuture(T &&value)
A substitute for QtFuture::makeReadyValueFuture() for compatibility with Qt pre-6....
QUOTIENT_API int patchVersion()
QUOTIENT_API int minorVersion()
QDebug formatJson(QDebug dbg)
QDebug manipulator to setup the stream for JSON output.
std::pair< InputIt, ForwardIt > findFirstOf(InputIt first, InputIt last, ForwardIt sFirst, ForwardIt sLast, auto pred)
Overloads(FunctorTs &&...) -> Overloads< FunctorTs... >
constexpr qint64 ProfilerMinNsecs
constexpr ImplPtr< ImplType, TypeToDelete > ZeroImpl()
QUOTIENT_API void linkifyUrls(QString &htmlEscapedText)
bool alarmX(bool alarmCondition, const auto &msg, bool invertReturnValue=false, std::source_location loc=std::source_location::current())
constexpr bool merge(T1 &lhs, const std::optional< T2 > &rhs)
Merge the value from an optional.
constexpr size_t mergeStruct(StructT &lhs, const StructT &rhs, const auto... fields)
Merge structure-like types.
ImplPtr< ImplType, TypeToDelete > makeImpl(ArgTs &&... args)
make_unique for ImplPtr
QDebug terse(QDebug dbg)
Suppress full qualification of enums/QFlags when logging.
auto makeReadyVoidFuture()
A substitute for QtFuture::makeReadyVoidFuture() for compatibility with Qt pre-6.6.
auto makeCStruct(T *(*constructor)(void *), size_t(*sizeFn)(), auto destructor)
Create a C structure with pre-programmed deletion logic.
QUOTIENT_API int majorVersion()
ImplPtr< ImplType, TypeToDelete > acquireImpl(ImplType *from)
void operator()(T *toDelete)
Multiplex several functors in one.
QDebug operator<<(QDebug dbg, std::invocable< QDebug > auto manipFn)
A helper operator for QDebug manipulators, e.g. formatJson.
#define QUO_CSTR(StringConvertible_)
q(Utf8)Printable that can handle more than just QStrings