2
2
#define LIBRAPID_UTILS_MEMUTILS_HPP
3
3
4
4
namespace librapid {
5
- // / Cast the bits of one value directly into another type -- no conversion is performed
6
- // / \tparam To The type to cast to
7
- // / \tparam From The type to cast from
8
- // / \param val The value to cast
9
- // / \return The value bitwise mapped to the new type
10
- template <typename To, typename From>
11
- LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE constexpr To bitCast (const From &val) noexcept {
12
- static_assert (
13
- sizeof (To) == sizeof (From),
14
- " Types have different sizes, and cannot be cast bit-for-bit between each other" );
5
+ // / Cast the bits of one value directly into another type -- no conversion is performed
6
+ // / \tparam To The type to cast to
7
+ // / \tparam From The type to cast from
8
+ // / \param val The value to cast
9
+ // / \return The value bitwise mapped to the new type
10
+ template <typename To, typename From>
11
+ LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE constexpr To bitCast (const From &val) noexcept {
12
+ static_assert (
13
+ sizeof (To) == sizeof (From),
14
+ " Types have different sizes, and cannot be cast bit-for-bit between each other" );
15
15
16
16
#if defined(__CUDACC__)
17
- To toOjb; // assumes default-init
18
- ::std::memcpy (::std::memcpy::addressof(toOjb), ::std::memcpy::addressof(val), sizeof(To));
19
- return _To_obj;
17
+ To toOjb; // assumes default-init
18
+ ::std::memcpy (::std::memcpy::addressof(toOjb), ::std::memcpy::addressof(val), sizeof(To));
19
+ return _To_obj;
20
20
#elif defined(LIBRAPID_MSVC)
21
- // MSVC doesn't support std::bit_cast until C++20
22
- return *(To *)(&val);
21
+ // MSVC doesn't support std::bit_cast until C++20
22
+ return *(To *)(&val);
23
23
#elif defined(LIBRAPID_GCC) || defined(LIBRAPID_CLANG)
24
- # if __cplusplus > 201703l && __has_builtin(__builtin_bit_cast)
25
- return __builtin_bit_cast (To, val);
26
- # else
27
- // Fallback option
28
- return *(To *)(&val);
29
- # endif // __has_builtin(__builtin_bit_cast)
24
+ # if __cplusplus > 201703l && __has_builtin(__builtin_bit_cast)
25
+ return __builtin_bit_cast (To, val);
26
+ # else
27
+ // Fallback option
28
+ return *(To *)(&val);
29
+ # endif // __has_builtin(__builtin_bit_cast)
30
30
#else
31
- // Further fallback option
32
- return *(To *)(&val);
31
+ // Further fallback option
32
+ return *(To *)(&val);
33
33
#endif
34
- }
34
+ }
35
35
36
- // / Returns true if the input value is NaN
37
- // / \tparam T The type of the value
38
- // / \param val The value to check
39
- // / \return True if the value is NaN, false otherwise
40
- template <typename T>
41
- LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool isNaN (const T &val) noexcept {
42
- return std::isnan (val);
43
- }
36
+ // / Returns true if the input value is NaN
37
+ // / \tparam T The type of the value
38
+ // / \param val The value to check
39
+ // / \return True if the value is NaN, false otherwise
40
+ template <typename T>
41
+ LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool isNaN (const T &val) noexcept {
42
+ return std::isnan (val);
43
+ }
44
44
45
- // / Returns true if the input value is finite
46
- // / \tparam T The type of the value
47
- // / \param val The value to check
48
- // / \return True if the value is finite,
49
- template <typename T>
50
- LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool isFinite (const T &val) noexcept {
51
- return std::isfinite (val);
52
- }
45
+ // / Returns true if the input value is finite
46
+ // / \tparam T The type of the value
47
+ // / \param val The value to check
48
+ // / \return True if the value is finite,
49
+ template <typename T>
50
+ LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool isFinite (const T &val) noexcept {
51
+ return std::isfinite (val);
52
+ }
53
53
54
- // / Returns true if the input value is infinite
55
- // / \tparam T The type of the value
56
- // / \param val The value to check
57
- // / \return True if the value is infinite,
58
- template <typename T>
59
- LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool isInf (const T &val) noexcept {
60
- return std::isinf (val);
61
- }
54
+ // / Returns true if the input value is infinite
55
+ // / \tparam T The type of the value
56
+ // / \param val The value to check
57
+ // / \return True if the value is infinite,
58
+ template <typename T>
59
+ LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool isInf (const T &val) noexcept {
60
+ return std::isinf (val);
61
+ }
62
62
63
- // / Create a new number with a given magnitude and sign
64
- // / \tparam T The type of the magnitude
65
- // / \tparam M The type of the sign
66
- // / \param mag The magnitude of the number
67
- // / \param sign The value from which to copy the sign
68
- // / \return
69
- template <typename T, typename M>
70
- LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE T copySign (const T &mag, const M &sign) noexcept {
63
+ // / Create a new number with a given magnitude and sign
64
+ // / \tparam T The type of the magnitude
65
+ // / \tparam M The type of the sign
66
+ // / \param mag The magnitude of the number
67
+ // / \param sign The value from which to copy the sign
68
+ // / \return
69
+ template <typename T, typename M>
70
+ LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE T copySign (const T &mag, const M &sign) noexcept {
71
71
#if defined(LIBRAPID_MSVC)
72
- return std::copysign (mag, static_cast <T>(sign));
72
+ return std::copysign (mag, static_cast <T>(sign));
73
73
#else
74
- if constexpr (std::is_fundamental_v<T> && std::is_fundamental_v<M>) {
75
- return std::copysign (mag, static_cast <T>(sign));
76
- } else {
77
- if (sign < 0 ) return -mag;
78
- return mag;
79
- }
74
+ if constexpr (std::is_fundamental_v<T> && std::is_fundamental_v<M>) {
75
+ return std::copysign (mag, static_cast <T>(sign));
76
+ } else {
77
+ if (sign < 0 ) return -mag;
78
+ return mag;
79
+ }
80
80
#endif
81
- }
81
+ }
82
82
83
- // / Extract the sign bit from a value
84
- // / \tparam T The type of the value
85
- // / \param val The value to extract the sign bit from
86
- // / \return The sign bit of the value
87
- template <typename T>
88
- LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit (const T &val) noexcept {
89
- return signBit ((double )val);
90
- }
83
+ // / Extract the sign bit from a value
84
+ // / \tparam T The type of the value
85
+ // / \param val The value to extract the sign bit from
86
+ // / \return The sign bit of the value
87
+ template <typename T>
88
+ LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit (const T &val) noexcept {
89
+ return signBit ((double )val);
90
+ }
91
91
92
- // / Extract the sign bit from a value
93
- // / \param val The value to extract the sign bit from
94
- // / \return The sign bit of the value
95
- template <>
96
- LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit (const long double &val) noexcept {
97
- return std::signbit (val);
98
- }
92
+ // / Extract the sign bit from a value
93
+ // / \param val The value to extract the sign bit from
94
+ // / \return The sign bit of the value
95
+ template <>
96
+ LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit (const long double &val) noexcept {
97
+ return std::signbit (val);
98
+ }
99
99
100
- // / Extract the sign bit from a value
101
- // / \param val The value to extract the sign bit from
102
- // / \return The sign bit of the value
103
- template <>
104
- LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit (const double &val) noexcept {
105
- return std::signbit (val);
106
- }
100
+ // / Extract the sign bit from a value
101
+ // / \param val The value to extract the sign bit from
102
+ // / \return The sign bit of the value
103
+ template <>
104
+ LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit (const double &val) noexcept {
105
+ return std::signbit (val);
106
+ }
107
107
108
- // / Extract the sign bit from a value
109
- // / \param val The value to extract the sign bit from
110
- // / \return The sign bit of the value
111
- template <>
112
- LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit (const float &val) noexcept {
113
- return std::signbit (val);
114
- }
108
+ // / Extract the sign bit from a value
109
+ // / \param val The value to extract the sign bit from
110
+ // / \return The sign bit of the value
111
+ template <>
112
+ LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit (const float &val) noexcept {
113
+ return std::signbit (val);
114
+ }
115
115
116
- // / Return a value multiplied by 2 raised to the power of an exponent
117
- // / \tparam T The type of the value
118
- // / \param x The value to multiply
119
- // / \param exp The exponent to raise 2 to
120
- // / \return x * 2^exp
121
- template <typename T>
122
- LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE T ldexp (const T &x, const int64_t exp) noexcept {
123
- return std::ldexp (x, (int )exp );
124
- }
116
+ // / Return a value multiplied by 2 raised to the power of an exponent
117
+ // / \tparam T The type of the value
118
+ // / \param x The value to multiply
119
+ // / \param exp The exponent to raise 2 to
120
+ // / \return x * 2^exp
121
+ template <typename T>
122
+ LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE T ldexp (const T &x, const int64_t exp) noexcept {
123
+ return std::ldexp (x, (int )exp );
124
+ }
125
+
126
+ // / \brief Copy \p bytes bytes from \p src to \p dest, ignoring the datatypes. There are no
127
+ // / conversions performed and no error checking.
128
+ // / \tparam A First type
129
+ // / \tparam B Second type
130
+ // / \param dest Destination pointer
131
+ // / \param src Source pointer
132
+ // / \param bytes Number of bytes to copy
133
+ template <typename A, typename B>
134
+ void memcpy (A *dest, const B *src, size_t bytes) {
135
+ std::memcpy ((void *)dest, (void *)src, bytes);
136
+ }
125
137
} // namespace librapid
126
138
127
139
#endif // LIBRAPID_UTILS_MEMUTILS_HPP
0 commit comments