HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
numeric_cast.hpp
1// Copyright 2019 Pokitec
2// All rights reserved.
3
4#pragma once
5
6#include "TTauri/Foundation/required.hpp"
7#include <type_traits>
8#include <limits>
9
10namespace tt {
11
12template<typename To, typename From>
14 static_assert(std::is_floating_point_v<To> || std::is_integral_v<To>, "is_lossless_cast 'To' must be float or integer");
15 static_assert(std::is_floating_point_v<From> || std::is_integral_v<From>, "is_lossless_cast 'From' must be float or integer");
16
17 static constexpr bool value =
18 std::is_floating_point_v<To> ||
19 (std::is_signed_v<To> && sizeof(To) > sizeof(From)) ||
20 (std::is_signed_v<To> == std::is_signed_v<To> && sizeof(To) >= sizeof(From));
21};
22
23template<typename To, typename From>
24constexpr bool is_lossless_cast_v = is_lossless_cast<To,From>::value;
25
26
30template<typename To, typename From>
31constexpr To numeric_cast(From x) noexcept
32{
33 if constexpr (!is_lossless_cast_v<To,From>) {
34 if constexpr (std::is_signed_v<To> == std::is_signed_v<From>) {
35 // When both sides have the same signess, then they both get converted to
36 // the largest fitting type.
37 if constexpr (std::is_signed_v<To>) {
38 // Only signed numbers can be less than zero.
39 tt_assume(x >= std::numeric_limits<To>::min());
40 }
41 tt_assume(x <= std::numeric_limits<To>::max());
42
43 } else if constexpr (std::is_unsigned_v<To>) {
44 // When the destination is unsigned and source is signed.
45 tt_assume(x >= 0);
46 if constexpr(sizeof(To) < sizeof(From)) {
47 // When signed may not fit inside the unsigned number check by first converting
48 // the maximum destination to the larger signed type.
49 tt_assume(x <= static_cast<From>(std::numeric_limits<To>::max()));
50 }
51
52 } else {
53 // When the destination is signed and source is unsigned.
54 if constexpr(sizeof(To) <= sizeof(From)) {
55 // When unsigned may not fit inside the signed number check by first converting
56 // the maximum destination to the larger-or-equal unsigned type.
57 tt_assume(x <= static_cast<From>(std::numeric_limits<To>::max()));
58 }
59 }
60 }
61 return static_cast<To>(x);
62}
63
64}
Definition numeric_cast.hpp:13