Skip to content

Commit b655f22

Browse files
committed
Add an is_narrowing_v
Just because I wrote it anyway for testing and it could be useful in the future
1 parent fc80e7f commit b655f22

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

include/cpp2util.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,23 @@ struct nonesuch_ {
702702
};
703703
static nonesuch_ nonesuch;
704704

705+
// Most of the 'as' casts are <To, From> so use that order here
706+
// If it's confusing, we can switch this to <From, To>
707+
template< typename To, typename From >
708+
inline constexpr auto is_narrowing_v =
709+
// [dcl.init.list] 7.1
710+
(std::is_floating_point_v<From> && std::is_integral_v<To>) ||
711+
// [dcl.init.list] 7.2
712+
(std::is_floating_point_v<From> && std::is_floating_point_v<To> && sizeof(From) > sizeof(To)) ||
713+
// [dcl.init.list] 7.3
714+
(std::is_integral_v<From> && std::is_floating_point_v<To>) ||
715+
(std::is_enum_v<From> && std::is_floating_point_v<To>) ||
716+
// [dcl.init.list] 7.4
717+
(std::is_integral_v<From> && std::is_integral_v<To> && sizeof(From) > sizeof(To)) ||
718+
(std::is_enum_v<From> && std::is_integral_v<To> && sizeof(From) > sizeof(To)) ||
719+
// [dcl.init.list] 7.5
720+
(std::is_pointer_v<From> && std::is_same_v<To, bool>);
721+
705722
template <typename... Ts>
706723
inline constexpr auto program_violates_type_safety_guarantee = sizeof...(Ts) < 0;
707724

@@ -781,7 +798,7 @@ auto as( X const& x ) -> decltype(auto) {
781798

782799
template< typename C, typename X >
783800
auto as( X const& x ) -> auto
784-
requires (!std::is_same_v<C, X> && requires { C{x}; })
801+
requires (!std::is_same_v<C, X> && requires { C{x}; } && !is_narrowing_v<C, X>)
785802
{
786803
return C{x};
787804
}

0 commit comments

Comments
 (0)