From 2b067b2c62685f7c4f7afbb7aeb34d55c2cb8733 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 15 Apr 2022 18:28:26 +0100 Subject: If source_location is available, use it for safe numeric conversion exception message --- netfs/ice/numeric.cpp | 14 ++++++++++++++ netfs/ice/numeric.h | 30 ++++++++++++++++++++++++++++-- 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 +#include + +#ifdef __cpp_lib_source_location +# include + +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 #include #include -#include #include +#include #include +#ifdef __cpp_lib_source_location +# include +# include +# include +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 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 constexpr inline operator R() const @@ -26,7 +44,12 @@ template struct safe : safe_base { } else { if (!std::in_range(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(value); } @@ -44,6 +67,9 @@ template 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::min()}; constexpr static T max {std::numeric_limits::max()}; }; -- cgit v1.2.3