summaryrefslogtreecommitdiffstats
path: root/dom/quota/QuotaCommon.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/quota/QuotaCommon.h')
-rw-r--r--dom/quota/QuotaCommon.h54
1 files changed, 48 insertions, 6 deletions
diff --git a/dom/quota/QuotaCommon.h b/dom/quota/QuotaCommon.h
index 74855dd16b..166e8de969 100644
--- a/dom/quota/QuotaCommon.h
+++ b/dom/quota/QuotaCommon.h
@@ -22,6 +22,7 @@
#include "mozilla/MacroArgs.h"
#include "mozilla/Maybe.h"
#include "mozilla/ResultExtensions.h"
+#include "mozilla/StaticString.h"
#include "mozilla/Try.h"
#if defined(QM_LOG_ERROR_ENABLED) && defined(QM_ERROR_STACKS_ENABLED)
# include "mozilla/Variant.h"
@@ -1133,7 +1134,7 @@ auto ErrToDefaultOk(const nsresult aValue) -> Result<V, nsresult> {
}
template <typename MozPromiseType, typename RejectValueT = nsresult>
-auto CreateAndRejectMozPromise(const char* aFunc, const RejectValueT& aRv)
+auto CreateAndRejectMozPromise(StaticString aFunc, const RejectValueT& aRv)
-> decltype(auto) {
if constexpr (std::is_same_v<RejectValueT, nsresult>) {
return MozPromiseType::CreateAndReject(aRv, aFunc);
@@ -1142,12 +1143,13 @@ auto CreateAndRejectMozPromise(const char* aFunc, const RejectValueT& aRv)
}
}
-RefPtr<BoolPromise> CreateAndRejectBoolPromise(const char* aFunc, nsresult aRv);
+RefPtr<BoolPromise> CreateAndRejectBoolPromise(StaticString aFunc,
+ nsresult aRv);
-RefPtr<Int64Promise> CreateAndRejectInt64Promise(const char* aFunc,
+RefPtr<Int64Promise> CreateAndRejectInt64Promise(StaticString aFunc,
nsresult aRv);
-RefPtr<BoolPromise> CreateAndRejectBoolPromiseFromQMResult(const char* aFunc,
+RefPtr<BoolPromise> CreateAndRejectBoolPromiseFromQMResult(StaticString aFunc,
const QMResult& aRv);
// Like Rust's collect with a step function, not a generic iterator/range.
@@ -1493,9 +1495,49 @@ Nothing HandleErrorWithCleanupReturnNothing(const char* aExpr, const T& aRv,
return Nothing();
}
-template <size_t NFunc, size_t NExpr, typename T, typename CustomRetVal>
+// Implementation of workaround for GCC bug #114812.
+#if defined(__GNUC__) && !defined(__clang__)
+namespace gcc_detail {
+// usual case: identity function
+template <typename T>
+struct invokabilize_impl {
+ auto operator()(T t) -> T { return t; }
+};
+// reference-to-function: wrap in std::function
+template <typename R, typename... Args>
+struct invokabilize_impl<R (&)(Args...)> {
+ auto operator()(R (&t)(Args...)) -> std::function<R(Args...)> {
+ return std::function{t};
+ }
+};
+// pointer-to-function: wrap in std::function
+template <typename R, typename... Args>
+struct invokabilize_impl<R (*)(Args...)> {
+ auto operator()(R (*t)(Args...)) -> std::function<R(Args...)> {
+ return std::function{t};
+ }
+};
+// entry point
+template <typename T>
+auto invokabilize(T t) {
+ return invokabilize_impl<T>{}(std::forward<T>(t));
+}
+} // namespace gcc_detail
+#endif
+
+template <size_t NFunc, size_t NExpr, typename T, typename CustomRetVal_>
auto HandleCustomRetVal(const char (&aFunc)[NFunc], const char (&aExpr)[NExpr],
- const T& aRv, CustomRetVal&& aCustomRetVal) {
+ const T& aRv, CustomRetVal_&& aCustomRetVal_) {
+#if defined(__GNUC__) && !defined(__clang__)
+ // Workaround for gcc bug #114812. (See either that bug, or our bug 1891541,
+ // for more details.)
+ auto aCustomRetVal =
+ gcc_detail::invokabilize(std::forward<CustomRetVal_>(aCustomRetVal_));
+ using CustomRetVal = decltype(aCustomRetVal);
+#else
+ using CustomRetVal = CustomRetVal_;
+ CustomRetVal& aCustomRetVal = aCustomRetVal_;
+#endif
if constexpr (std::is_invocable<CustomRetVal, const char[NFunc],
const char[NExpr]>::value) {
return std::forward<CustomRetVal>(aCustomRetVal)(aFunc, aExpr);