Program Listing for File clamp_cast.hpp¶
↰ Return to documentation for file (include/uitsl/algorithm/clamp_cast.hpp)
#pragma once
#ifndef UITSL_ALGORITHM_CLAMP_CAST_HPP_INCLUDE
#define UITSL_ALGORITHM_CLAMP_CAST_HPP_INCLUDE
#include <algorithm>
#include <cmath>
#include <limits>
#include "../../uitsl/debug/uitsl_always_assert.hpp"
#include "nan_to_zero.hpp"
namespace uitsl {
template<typename To, typename From>
To clamp_cast( const From from ) {
// ideally, we'd use std::nexttoward but unfortunately it's not constexpr
constexpr double lower_bound =
static_cast<double>( std::numeric_limits<To>::lowest() )
+ std::numeric_limits<double>::epsilon()
;
constexpr double upper_bound =
static_cast<double>( std::numeric_limits<To>::max() )
- std::numeric_limits<double>::epsilon()
;
const double clamped = std::clamp(
static_cast<double>( uitsl::nan_to_zero( from ) ),
lower_bound,
upper_bound
);
#ifdef __EMSCRIPTEN__
// necessary to keep nan sanitization from getting optimized away
// and (I assume?) implicitly taken care of via the static_cast
uitsl_always_assert( !std::isnan( clamped ), "" );
#endif
return static_cast<To>( clamped );
}
} // namespace uitsl
#endif // #ifndef UITSL_ALGORITHM_CLAMP_CAST_HPP_INCLUDE