VCCC  2024.05
VisualCamp Common C++ library
saturate_cast.hpp
Go to the documentation of this file.
1 //
2 // Created by YongGyu Lee on 4/15/24.
3 //
4 
5 #ifndef VCCC_NUMERIC_SATURATE_CAST_HPP_
6 #define VCCC_NUMERIC_SATURATE_CAST_HPP_
7 
8 #include <limits>
9 #include <type_traits>
10 
13 
14 namespace vccc {
15 namespace detail {
16 
17 // high bit -> low bit
18 template<typename To, typename From, typename Any>
19 inline constexpr To saturate_cast_impl(From x, Any, Any, std::true_type /* digit<To> < digit<From> */) noexcept {
20  if (x < static_cast<From>((std::numeric_limits<To>::min)()))
22  if (x > static_cast<From>((std::numeric_limits<To>::max)()))
24  return static_cast<To>(x);
25 }
26 
27 // low bit -> high bit
28 template<typename To, typename From, typename Any>
29 inline constexpr To saturate_cast_impl(From x, Any, Any, std::false_type /* digit<To> < digit<From> */) noexcept {
30  return static_cast<To>(x);
31 }
32 
33 // unsigned -> signed
34 template<typename To, typename From, typename Any>
35 inline constexpr To saturate_cast_impl(From x, std::false_type /* signed */, std::true_type /* signed */, Any) noexcept {
36  if (x > std::make_unsigned_t<To>((std::numeric_limits<To>::max)()))
38  return static_cast<To>(x);
39 }
40 
41 // signed -> unsigned
42 template<typename To, typename From, typename Any>
43 inline constexpr To saturate_cast_impl(From x, std::true_type /* signed */, std::false_type /* signed */, Any) noexcept {
44  if (x < 0)
45  return 0;
46  if (std::make_unsigned_t<From>(x) > (std::numeric_limits<To>::max)())
48  return static_cast<To>(x);
49 }
50 
51 } // namespace detail
52 
55 
56 template<typename To, typename From, std::enable_if_t<conjunction<
57  std::is_integral<To>,
58  std::is_integral<From>
59 >::value, int> = 0>
60 inline constexpr To saturate_cast(From x) noexcept {
61  return vccc::detail::saturate_cast_impl<To>(
62  x,
63  std::is_signed<From>{},
64  std::is_signed<To>{},
65  vccc::bool_constant<((std::numeric_limits<To>::digits) < (std::numeric_limits<From>::digits))>{}
66  );
67 }
68 
70 
71 } // namespace vccc
72 
73 #endif // VCCC_NUMERIC_SATURATE_CAST_HPP_
constexpr VCCC_INLINE_OR_STATIC detail::max_niebloid max
Definition: max.hpp:95
constexpr VCCC_INLINE_OR_STATIC detail::min_niebloid min
Definition: min.hpp:90
constexpr To saturate_cast(From x) noexcept
Definition: saturate_cast.hpp:60
std::integral_constant< bool, v > bool_constant
Definition: bool_constant.hpp:19
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35