cast.hpp helper

I was tired of manually bounds-checking my integer casts.
This commit is contained in:
PJB3005
2026-07-25 15:26:15 +02:00
parent 226a1fc482
commit a6c4419da6
3 changed files with 63 additions and 0 deletions
+1
View File
@@ -1581,6 +1581,7 @@ set(DUSK_FILES
src/helpers/endian.cpp
src/helpers/offset_ptr.cpp
src/helpers/string.cpp
src/helpers/cast.cpp
)
set(DUSK_HTTP_BACKEND_FILES
+48
View File
@@ -0,0 +1,48 @@
#pragma once
#include <limits>
#include <utility>
#include <span>
/**
* Helper functions for performing casts.
*/
namespace dusk::helpers::cast {
/**
* Implementation details of dusk::helpers::cast.
*/
namespace _impl {
[[noreturn]] void overrun_high();
[[noreturn]] void overrun_low();
}
template <typename T>
concept IntCastable = std::is_integral_v<T> && std::is_trivially_copyable_v<T>;
/**
* Helper type that allows easily casting between integer types,
* that safely aborts if an overflow were to occur.
* Usage:
* @code
* size_t foobar = 20;
* int real = bounded_cast(foobar);
* @endcode
*/
template <IntCastable Source>
struct bounded_cast {
Source src;
template <IntCastable Target>
[[nodiscard]] constexpr operator Target() const {
if (std::cmp_greater(src, std::numeric_limits<Target>::max())) [[unlikely]] {
_impl::overrun_high();
}
if (std::cmp_less(src, std::numeric_limits<Target>::min())) [[unlikely]] {
_impl::overrun_low();
}
return static_cast<Target>(src);
}
};
}
+14
View File
@@ -0,0 +1,14 @@
#include "helpers/cast.hpp"
#include "global.h"
namespace dusk::helpers::cast::_impl {
void overrun_high() {
CRASH("bounded cast overran!");
}
void overrun_low() {
CRASH("bounded cast overran!");
}
} // namespace dusk::helpers::cast::_impl