Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/rapidyaml/include/c4/szconv.hpp
4261 views
1
#ifndef _C4_SZCONV_HPP_
2
#define _C4_SZCONV_HPP_
3
4
/** @file szconv.hpp utilities to deal safely with narrowing conversions */
5
6
#include "c4/config.hpp"
7
#include "c4/error.hpp"
8
9
#include <limits>
10
11
namespace c4 {
12
13
C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
14
15
/** @todo this would be so much easier with calls to numeric_limits::max()... */
16
template<class SizeOut, class SizeIn>
17
struct is_narrower_size : std::conditional
18
<
19
(std::is_signed<SizeOut>::value == std::is_signed<SizeIn>::value)
20
?
21
(sizeof(SizeOut) < sizeof(SizeIn))
22
:
23
(
24
(sizeof(SizeOut) < sizeof(SizeIn))
25
||
26
(
27
(sizeof(SizeOut) == sizeof(SizeIn))
28
&&
29
(std::is_signed<SizeOut>::value && std::is_unsigned<SizeIn>::value)
30
)
31
),
32
std::true_type,
33
std::false_type
34
>::type
35
{
36
static_assert(std::is_integral<SizeIn >::value, "must be integral type");
37
static_assert(std::is_integral<SizeOut>::value, "must be integral type");
38
};
39
40
41
/** when SizeOut is wider than SizeIn, assignment can occur without reservations */
42
template<class SizeOut, class SizeIn>
43
C4_ALWAYS_INLINE
44
typename std::enable_if< ! is_narrower_size<SizeOut, SizeIn>::value, SizeOut>::type
45
szconv(SizeIn sz) noexcept
46
{
47
return static_cast<SizeOut>(sz);
48
}
49
50
/** when SizeOut is narrower than SizeIn, narrowing will occur, so we check
51
* for overflow. Note that this check is done only if C4_XASSERT is enabled.
52
* @see C4_XASSERT */
53
template<class SizeOut, class SizeIn>
54
C4_ALWAYS_INLINE
55
typename std::enable_if<is_narrower_size<SizeOut, SizeIn>::value, SizeOut>::type
56
szconv(SizeIn sz) C4_NOEXCEPT_X
57
{
58
C4_XASSERT(sz >= 0);
59
C4_XASSERT_MSG((SizeIn)sz <= (SizeIn)std::numeric_limits<SizeOut>::max(), "size conversion overflow: in=%zu", (size_t)sz);
60
SizeOut szo = static_cast<SizeOut>(sz);
61
return szo;
62
}
63
64
C4_SUPPRESS_WARNING_GCC_CLANG_POP
65
66
} // namespace c4
67
68
#endif /* _C4_SZCONV_HPP_ */
69
70