#ifndef CRUCIBLE_LIMITS_H #define CRUCIBLE_LIMITS_H #include "crucible/error.h" #include #include namespace crucible { using namespace std; template To ranged_cast(From f) { if (typeid(From) == typeid(To)) { return f; } To t; static string f_info = typeid(f).name(); static string t_info = typeid(t).name(); if (numeric_limits::max() > numeric_limits::max() && numeric_limits::max() < numeric_limits::max()) { THROW_ERROR(out_of_range, "ranged_cast: can't compare limits of types " << f_info << " and " << t_info << ", template specialization required"); } if (numeric_limits::max() > numeric_limits::max() && f > static_cast(numeric_limits::max())) { THROW_ERROR(out_of_range, "ranged_cast: " << f_info << "(" << f << ") out of range of target type " << t_info); } if (!numeric_limits::is_signed && numeric_limits::is_signed && f < 0) { THROW_ERROR(out_of_range, "ranged_cast: " << f_info << "(" << f << ") out of range of unsigned target type " << t_info); } t = static_cast(f); From f2 = static_cast(t); if (f2 != f) { THROW_ERROR(out_of_range, "ranged_cast: " << f_info << "(" << f << ") -> " << t_info << " failed: result value " << f2); } return t; } }; #endif // CRUCIBLE_LIMITS_H