rippled
Loading...
Searching...
No Matches
safe_cast.h
1#ifndef XRPL_BASICS_SAFE_CAST_H_INCLUDED
2#define XRPL_BASICS_SAFE_CAST_H_INCLUDED
3
4#include <type_traits>
5
6namespace ripple {
7
8// safe_cast adds compile-time checks to a static_cast to ensure that
9// the destination can hold all values of the source. This is particularly
10// handy when the source or destination is an enumeration type.
11
12template <class Src, class Dest>
16 ? sizeof(Dest) > sizeof(Src)
17 : sizeof(Dest) >= sizeof(Src));
18
19template <class Dest, class Src>
20inline constexpr std::
22 safe_cast(Src s) noexcept
23{
24 static_assert(
26 "Cannot cast signed to unsigned");
27 constexpr unsigned not_same =
29 static_assert(
30 sizeof(Dest) >= sizeof(Src) + not_same,
31 "Destination is too small to hold all values of source");
32 return static_cast<Dest>(s);
33}
34
35template <class Dest, class Src>
36inline constexpr std::
38 safe_cast(Src s) noexcept
39{
40 return static_cast<Dest>(safe_cast<std::underlying_type_t<Dest>>(s));
41}
42
43template <class Dest, class Src>
44inline constexpr std::
46 safe_cast(Src s) noexcept
47{
48 return safe_cast<Dest>(static_cast<std::underlying_type_t<Src>>(s));
49}
50
51// unsafe_cast explicitly flags a static_cast as not necessarily able to hold
52// all values of the source. It includes a compile-time check so that if
53// underlying types become safe, it can be converted to a safe_cast.
54
55template <class Dest, class Src>
56inline constexpr std::
58 unsafe_cast(Src s) noexcept
59{
60 static_assert(
62 "Only unsafe if casting signed to unsigned or "
63 "destination is too small");
64 return static_cast<Dest>(s);
65}
66
67template <class Dest, class Src>
68inline constexpr std::
70 unsafe_cast(Src s) noexcept
71{
72 return static_cast<Dest>(unsafe_cast<std::underlying_type_t<Dest>>(s));
73}
74
75template <class Dest, class Src>
76inline constexpr std::
78 unsafe_cast(Src s) noexcept
79{
80 return unsafe_cast<Dest>(static_cast<std::underlying_type_t<Src>>(s));
81}
82
83} // namespace ripple
84
85#endif
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
constexpr std::enable_if_t< std::is_integral_v< Dest > &&std::is_integral_v< Src >, Dest > safe_cast(Src s) noexcept
Definition safe_cast.h:22
constexpr std::enable_if_t< std::is_integral_v< Dest > &&std::is_integral_v< Src >, Dest > unsafe_cast(Src s) noexcept
Definition safe_cast.h:58