diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2022-04-15 18:28:26 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2022-04-15 18:28:26 +0100 |
commit | 2b067b2c62685f7c4f7afbb7aeb34d55c2cb8733 (patch) | |
tree | 3d473cd9ee1d16fefcfcc7b539051ccda8e7b810 | |
parent | Enable lots of warnings, fix the few bits of fallout (diff) | |
download | netfs-2b067b2c62685f7c4f7afbb7aeb34d55c2cb8733.tar.bz2 netfs-2b067b2c62685f7c4f7afbb7aeb34d55c2cb8733.tar.xz netfs-2b067b2c62685f7c4f7afbb7aeb34d55c2cb8733.zip |
If source_location is available, use it for safe numeric conversion exception message
-rw-r--r-- | netfs/ice/numeric.cpp | 14 | ||||
-rw-r--r-- | 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 <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()}; }; |