xrpld
Loading...
Searching...
No Matches
include
xrpl
basics
safe_cast.h
1
#pragma once
2
3
#include <xrpl/beast/utility/instrumentation.h>
// IWYU pragma: keep
4
5
#include <
type_traits
>
6
7
namespace
xrpl
{
8
9
// safe_cast adds compile-time checks to a static_cast to ensure that
10
// the destination can hold all values of the source. This is particularly
11
// handy when the source or destination is an enumeration type.
12
13
template
<
class
Src,
class
Dest>
14
concept
SafeToCast
= (
std::is_integral_v<Src>
&&
std::is_integral_v<Dest>
) &&
15
(
std::is_signed_v<Src>
||
std::is_unsigned_v<Dest>
) &&
16
(
std::is_signed_v<Src>
!=
std::is_signed_v<Dest>
?
sizeof
(Dest) >
sizeof
(Src)
17
:
sizeof
(Dest) >=
sizeof
(Src));
18
19
template
<
class
Dest,
class
Src>
20
constexpr
Dest
21
safeCast
(Src s)
noexcept
22
requires
(
std::is_integral_v<Dest>
&&
std::is_integral_v<Src>
)
23
{
24
static_assert
(
25
std::is_signed_v<Dest>
||
std::is_unsigned_v<Src>
,
"Cannot cast signed to unsigned"
);
26
constexpr
unsigned
kNotSame =
std::is_signed_v<Dest>
!=
std::is_signed_v<Src>
;
27
static_assert
(
28
sizeof
(Dest) >=
sizeof
(Src) + kNotSame,
29
"Destination is too small to hold all values of source"
);
30
return
static_cast<
Dest
>
(s);
31
}
32
33
template
<
class
Dest,
class
Src>
34
constexpr
Dest
35
safeCast
(Src s)
noexcept
36
requires
(
std::is_enum_v<Dest>
&&
std::is_integral_v<Src>
)
37
{
38
return
static_cast<
Dest
>
(
safeCast<std::underlying_type_t<Dest>
>(s));
39
}
40
41
template
<
class
Dest,
class
Src>
42
constexpr
Dest
43
safeCast
(Src s)
noexcept
44
requires
(
std::is_integral_v<Dest>
&&
std::is_enum_v<Src>
)
45
{
46
return
safeCast<Dest>
(
static_cast<
std::underlying_type_t<Src>
>
(s));
47
}
48
49
// unsafe_cast explicitly flags a static_cast as not necessarily able to hold
50
// all values of the source. It includes a compile-time check so that if
51
// underlying types become safe, it can be converted to a safe_cast.
52
53
template
<
class
Dest,
class
Src>
54
constexpr
Dest
55
unsafeCast
(Src s)
noexcept
56
requires
(
std::is_integral_v<Dest>
&&
std::is_integral_v<Src>
)
57
{
58
static_assert
(
59
!
SafeToCast<Src, Dest>
,
60
"Only unsafe if casting signed to unsigned or "
61
"destination is too small"
);
62
return
static_cast<
Dest
>
(s);
63
}
64
65
template
<
class
Dest,
class
Src>
66
constexpr
Dest
67
unsafeCast
(Src s)
noexcept
68
requires
(
std::is_enum_v<Dest>
&&
std::is_integral_v<Src>
)
69
{
70
return
static_cast<
Dest
>
(
unsafeCast<std::underlying_type_t<Dest>
>(s));
71
}
72
73
template
<
class
Dest,
class
Src>
74
constexpr
Dest
75
unsafeCast
(Src s)
noexcept
76
requires
(
std::is_integral_v<Dest>
&&
std::is_enum_v<Src>
)
77
{
78
return
unsafeCast<Dest>
(
static_cast<
std::underlying_type_t<Src>
>
(s));
79
}
80
81
template
<
class
Dest,
class
Src>
82
requires
std::is_pointer_v<Dest>
83
inline
Dest
84
safeDowncast
(Src* s)
noexcept
85
{
86
#ifdef NDEBUG
87
return
static_cast<
Dest
>
(s);
// NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
88
#else
89
auto
* result =
dynamic_cast<
Dest
>
(s);
90
XRPL_ASSERT(result !=
nullptr
,
"xrpl::safeDowncast : pointer downcast is valid"
);
91
return
result;
92
#endif
93
}
94
95
template
<
class
Dest,
class
Src>
96
requires
std::is_lvalue_reference_v<Dest>
97
inline
Dest
98
safeDowncast
(Src& s)
noexcept
99
{
100
#ifndef NDEBUG
101
XRPL_ASSERT(
102
dynamic_cast<
std::add_pointer_t<std::remove_reference_t<Dest>
>
>(&s) !=
nullptr
,
103
"xrpl::safeDowncast : reference downcast is valid"
);
104
#endif
105
return
static_cast<
Dest
>
(s);
// NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
106
}
107
108
}
// namespace xrpl
std::add_pointer_t
xrpl::SafeToCast
Definition
safe_cast.h:14
std::is_enum_v
T is_enum_v
std::is_integral_v
T is_integral_v
std::is_lvalue_reference_v
T is_lvalue_reference_v
std::is_pointer_v
T is_pointer_v
std::is_signed_v
T is_signed_v
std::is_unsigned_v
T is_unsigned_v
xrpl
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition
algorithm.h:5
xrpl::safeDowncast
Dest safeDowncast(Src *s) noexcept
Definition
safe_cast.h:84
xrpl::safeCast
constexpr Dest safeCast(Src s) noexcept
Definition
safe_cast.h:21
xrpl::unsafeCast
constexpr Dest unsafeCast(Src s) noexcept
Definition
safe_cast.h:55
type_traits
std::underlying_type_t
Generated by
1.16.1