summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--netfs/ice/numeric.cpp14
-rw-r--r--netfs/ice/numeric.h30
2 files changed, 42 insertions, 2 deletions
diff --git a/netfs/ice/numeric.cpp b/netfs/ice/numeric.cpp
index 2ec05af..3d86f28 100644
--- a/netfs/ice/numeric.cpp
+++ b/netfs/ice/numeric.cpp
@@ -1,7 +1,21 @@
#include "numeric.h"
+#include <stdexcept>
+#include <version>
+
+#ifdef __cpp_lib_source_location
+# include <string>
+
+void
+safe_base::out_of_range(std::string desc)
+{
+ throw std::out_of_range {std::move(desc)};
+}
+
+#else
void
safe_base::out_of_range(const char * const function)
{
throw std::out_of_range {function};
}
+#endif
diff --git a/netfs/ice/numeric.h b/netfs/ice/numeric.h
index cdfec2a..302df91 100644
--- a/netfs/ice/numeric.h
+++ b/netfs/ice/numeric.h
@@ -5,17 +5,35 @@
#include <concepts>
#include <limits>
#include <optional>
-#include <stdexcept>
#include <utility>
+#include <version>
#include <visibility.h>
+#ifdef __cpp_lib_source_location
+# include <compileTimeFormatter.h>
+# include <source_location>
+# include <string>
+AdHocFormatter(ConvPos, "%?:%?(value: %?)");
+#endif
+
struct DLL_PUBLIC safe_base {
protected:
+#ifdef __cpp_lib_source_location
+ [[noreturn]] static void out_of_range(std::string);
+#else
[[noreturn]] static void out_of_range(const char * const);
+#endif
};
template<std::integral T> struct safe : safe_base {
+#ifdef __cpp_lib_source_location
+ constexpr explicit safe(T v, const std::source_location w = std::source_location::current()) noexcept :
+ value {v}, where {w}
+ {
+ }
+#else
constexpr explicit safe(T v) noexcept : value {v} { }
+#endif
// NOLINTNEXTLINE(hicpp-explicit-conversions)
template<std::integral R> constexpr inline operator R() const
@@ -26,7 +44,12 @@ template<std::integral T> struct safe : safe_base {
}
else {
if (!std::in_range<R>(value)) {
- [[unlikely]] out_of_range(__PRETTY_FUNCTION__);
+ [[unlikely]]
+#ifdef __cpp_lib_source_location
+ out_of_range(ConvPos::get(where.function_name(), where.line(), value));
+#else
+ out_of_range(__PRETTY_FUNCTION__);
+#endif
}
return static_cast<R>(value);
}
@@ -44,6 +67,9 @@ template<std::integral T> struct safe : safe_base {
private:
T value;
+#ifdef __cpp_lib_source_location
+ const std::source_location where;
+#endif
constexpr static T min {std::numeric_limits<T>::min()};
constexpr static T max {std::numeric_limits<T>::max()};
};