Program Listing for File safe_cast.hpp¶
↰ Return to documentation for file (include/uitsl/debug/safe_cast.hpp)
#pragma once
#ifndef UITSL_DEBUG_SAFE_CAST_HPP_INCLUDE
#define UITSL_DEBUG_SAFE_CAST_HPP_INCLUDE
#include <limits>
#include <stddef.h>
#include "safe_compare.hpp"
namespace uitsl {
// adapted from https://stackoverflow.com/a/49658950
template<typename Dst, typename Src>
inline Dst safe_cast(const Src value)
{
typedef std::numeric_limits<Dst> DstLim;
typedef std::numeric_limits<Src> SrcLim;
const bool positive_overflow_possible = safe_less(
DstLim::max(),
SrcLim::max()
);
const bool negative_overflow_possible =
SrcLim::is_signed
or
safe_greater(DstLim::lowest(), SrcLim::lowest());
// unsigned <-- unsigned
if((not DstLim::is_signed) and (not SrcLim::is_signed)) {
if(positive_overflow_possible and (value > DstLim::max())) {
throw std::overflow_error(__PRETTY_FUNCTION__ +
std::string(": positive overflow"));
}
}
// unsigned <-- signed
else if((not DstLim::is_signed) and SrcLim::is_signed) {
if(positive_overflow_possible and safe_greater(value, DstLim::max())) {
throw std::overflow_error(__PRETTY_FUNCTION__ +
std::string(": positive overflow"));
}
else if(negative_overflow_possible and (value < 0)) {
throw std::overflow_error(__PRETTY_FUNCTION__ +
std::string(": negative overflow"));
}
}
// signed <-- unsigned
else if(DstLim::is_signed and (not SrcLim::is_signed)) {
if(positive_overflow_possible and safe_greater(value, DstLim::max())) {
throw std::overflow_error(__PRETTY_FUNCTION__ +
std::string(": positive overflow"));
}
}
// signed <-- signed
else if(DstLim::is_signed and SrcLim::is_signed) {
if(positive_overflow_possible and safe_greater(value, DstLim::max())) {
throw std::overflow_error(__PRETTY_FUNCTION__ +
std::string(": positive overflow"));
} else if(negative_overflow_possible and safe_less(value, DstLim::lowest())) {
throw std::overflow_error(__PRETTY_FUNCTION__ +
std::string(": negative overflow"));
}
}
// limits have been checked, therefore safe to cast
return static_cast<Dst>(value);
}
} // namespace uitsl
#endif // #ifndef UITSL_DEBUG_SAFE_CAST_HPP_INCLUDE