Skip to content

Commit

Permalink
types: add narrow_cast
Browse files Browse the repository at this point in the history
  • Loading branch information
Hedede committed Mar 11, 2024
1 parent 170a143 commit 27259f8
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions types/include/aw/types/support/narrow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef aw_types_support_narrow_h
#define aw_types_support_narrow_h

#include <type_traits>
#include <utility>
#include <cassert>

namespace aw {
/*!
* Narrowing cast.
* Identical to static_cast but makes it easier to grep the code.
*/
template <typename To, typename From>
constexpr To narrow_cast(From&& from) noexcept
{
return static_cast<To>(std::forward<From>(from));
}

template <typename T, typename U>
constexpr bool same_sign(const T& t, const U& u)
{
return (t < T{}) == (u < U{});
}

/*!
* Checked narrowing cast. Inspired by GSL.
*/
template <class To, class From>
requires std::is_arithmetic_v<To>
constexpr To narrow(From from)
{
auto to = narrow_cast<To>(from);

assert(static_cast<From>(to) == from);

if constexpr(std::is_signed_v<To> != std::is_signed_v<From>)
assert(same_sign(to, from));

return to;
}

template <class To, class From>
requires (!std::is_arithmetic_v<To>)
constexpr To narrow(From from)
{
auto to = narrow_cast<To>(from);

assert(static_cast<From>(to) == from);

return to;
}
} // namespace aw

#endif // aw_types_support_narrow_h

0 comments on commit 27259f8

Please sign in to comment.