diff --git a/tdutils/td/utils/misc.h b/tdutils/td/utils/misc.h index 0e221cc7..97e8efe4 100644 --- a/tdutils/td/utils/misc.h +++ b/tdutils/td/utils/misc.h @@ -296,23 +296,34 @@ template struct safe_undeflying_type::value>> { using type = std::underlying_type_t; }; + +class NarrowCast { + const char *file_; + int line_; + + public: + NarrowCast(const char *file, int line) : file_(file), line_(line) { + } + + template + R cast(const A &a) { + using RT = typename safe_undeflying_type::type; + using AT = typename safe_undeflying_type::type; + + static_assert(std::is_integral::value, "expected integral type to cast to"); + static_assert(std::is_integral::value, "expected integral type to cast from"); + + auto r = R(a); + CHECK(A(r) == a) << static_cast(a) << " " << static_cast(r) << " " << file_ << " " << line_; + CHECK((is_same_signedness::value) || ((static_cast(r) < RT{}) == (static_cast(a) < AT{}))) + << static_cast(a) << " " << static_cast(r) << " " << file_ << " " << line_; + + return r; + } +}; } // namespace detail -template -R narrow_cast(const A &a) { - using RT = typename detail::safe_undeflying_type::type; - using AT = typename detail::safe_undeflying_type::type; - - static_assert(std::is_integral::value, "expected integral type to cast to"); - static_assert(std::is_integral::value, "expected integral type to cast from"); - - auto r = R(a); - CHECK(A(r) == a) << static_cast(a) << " " << static_cast(r); - CHECK((detail::is_same_signedness::value) || ((static_cast(r) < RT{}) == (static_cast(a) < AT{}))) - << static_cast(a) << " " << static_cast(r); - - return r; -} +#define narrow_cast detail::NarrowCast(__FILE__, __LINE__).cast template Result narrow_cast_safe(const A &a) {