[gjs] arg: Add function to handle big numbers warning on rounding
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] arg: Add function to handle big numbers warning on rounding
- Date: Sat, 8 Aug 2020 19:44:08 +0000 (UTC)
commit 25d5db5392bd1c80721d7edae4773cf96f85b9c0
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Mon May 11 03:33:52 2020 +0200
arg: Add function to handle big numbers warning on rounding
gi/arg-inl.h | 40 ++++++++++++++++++++++++++++++++++++++++
gi/arg.cpp | 19 ++-----------------
2 files changed, 42 insertions(+), 17 deletions(-)
---
diff --git a/gi/arg-inl.h b/gi/arg-inl.h
index 996092c2..4e9afb8a 100644
--- a/gi/arg-inl.h
+++ b/gi/arg-inl.h
@@ -10,6 +10,8 @@
#include <stdint.h>
#include <cstddef> // for nullptr_t
+#include <limits>
+#include <string> // for to_string
#include <type_traits>
#include <girepository.h>
@@ -220,3 +222,41 @@ template <typename T, GITypeTag TAG = GI_TYPE_TAG_VOID>
inline std::enable_if_t<std::is_pointer_v<T>> gjs_arg_unset(GIArgument* arg) {
gjs_arg_set<T, TAG>(arg, nullptr);
}
+
+// Implementation to store rounded (u)int64_t numbers into double
+
+template <typename BigT>
+[[nodiscard]] inline BigT max_safe_big_number() {
+ return BigT(1) << std::numeric_limits<double>::digits;
+}
+
+template <typename BigT>
+[[nodiscard]] inline std::enable_if_t<std::is_signed_v<BigT>, BigT>
+min_safe_big_number() {
+ return -(max_safe_big_number<BigT>()) + 1;
+}
+
+template <typename BigT>
+[[nodiscard]] inline std::enable_if_t<std::is_unsigned_v<BigT>, BigT>
+min_safe_big_number() {
+ return std::numeric_limits<BigT>::lowest();
+}
+
+template <typename BigT>
+[[nodiscard]] inline std::enable_if_t<std::is_integral_v<BigT> &&
+ (std::numeric_limits<BigT>::max() >
+ std::numeric_limits<int32_t>::max()),
+ double>
+gjs_arg_get_maybe_rounded(GIArgument* arg) {
+ BigT val = gjs_arg_get<BigT>(arg);
+
+ if (val < min_safe_big_number<BigT>() ||
+ val > max_safe_big_number<BigT>()) {
+ g_warning(
+ "Value %s cannot be safely stored in a JS Number "
+ "and may be rounded",
+ std::to_string(val).c_str());
+ }
+
+ return static_cast<double>(val);
+}
diff --git a/gi/arg.cpp b/gi/arg.cpp
index d02d37d0..2d4fa012 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -26,7 +26,6 @@
#include <string.h> // for strcmp, strlen, memcpy
-#include <cmath> // for std::abs
#include <limits> // for numeric_limits
#include <string>
#include <type_traits>
@@ -2836,9 +2835,6 @@ gjs_object_from_g_hash (JSContext *context,
return true;
}
-static const int64_t MAX_SAFE_INT64 =
- int64_t(1) << std::numeric_limits<double>::digits;
-
bool
gjs_value_from_g_argument (JSContext *context,
JS::MutableHandleValue value_p,
@@ -2874,22 +2870,11 @@ gjs_value_from_g_argument (JSContext *context,
break;
case GI_TYPE_TAG_INT64:
- if (gjs_arg_get<int64_t>(arg) == G_MININT64 ||
- std::abs(gjs_arg_get<int64_t>(arg)) > MAX_SAFE_INT64)
- g_warning("Value %" G_GINT64_FORMAT
- " cannot be safely stored in a JS Number and may be "
- "rounded",
- gjs_arg_get<int64_t>(arg));
- value_p.setNumber(static_cast<double>(gjs_arg_get<int64_t>(arg)));
+ value_p.setNumber(gjs_arg_get_maybe_rounded<int64_t>(arg));
break;
case GI_TYPE_TAG_UINT64:
- if (gjs_arg_get<uint64_t>(arg) > MAX_SAFE_INT64)
- g_warning("Value %" G_GUINT64_FORMAT
- " cannot be safely stored in a JS Number and may be "
- "rounded",
- gjs_arg_get<uint64_t>(arg));
- value_p.setNumber(static_cast<double>(gjs_arg_get<uint64_t>(arg)));
+ value_p.setNumber(gjs_arg_get_maybe_rounded<uint64_t>(arg));
break;
case GI_TYPE_TAG_UINT16:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]