-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlib_bit
More file actions
199 lines (150 loc) · 6.14 KB
/
Copy pathlib_bit
File metadata and controls
199 lines (150 loc) · 6.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/* File: /cpp/lib_bit
*
* This file is a part of cpplib project which is distributed under MIT License.
* See file LICENSE for full license details.
*
* Copyright (c) 2020-present Nikita Zuev (V.Slavski!) <[email protected]>
*/
#ifndef CPPLIB__cpp__lib_bit
#define CPPLIB__cpp__lib_bit
#include <bit>
/////////////////////////////////// bit_cast /////////////////////////////////////////////
#ifdef __cpp_lib_bit_cast
namespace cpp {
template <class To, class From>
requires ( false/*Consider use `std::bit_cast`*/ )
inline constexpr To bit_cast( const From & from ) noexcept { return ::std::bit_cast<To>( from ); }
} // namespace cpp
#else
#pragma message("__cpp_lib_bit_cast feature unavailable, consider use `cpp::bit_cast`")
#include <cstring>
#include <type_traits>
namespace cpp {
/** @copyright As the original source code was taken from [cppreference.com](https://cppreference.com/) site, source
* code of this function is distributed under [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) license.
* @see https://en.cppreference.com/w/cpp/numeric/bit_cast
*/
template <class To, class From>
// constexpr support needs compiler magic
inline To bit_cast( const From & src ) noexcept {
static_assert( sizeof(To) == sizeof(From) );
// this implementation requires that To is trivially default constructible
static_assert( ::std::is_trivially_copyable_v<From> );
static_assert( ::std::is_trivial_v<To> );
To dst;
::std::memcpy( &dst, &src, sizeof(To) );
return dst;
}
} // namespace cpp
#endif // __cpp_lib_bit_cast
/////////////////////////////////// byteswap /////////////////////////////////////////////
#ifdef __cpp_lib_byteswap
#pragma message("__cpp_lib_byteswap feature support found")
namespace cpp {
template <class T>
inline constexpr T byteswap( T x ) noexcept { return ::std::byteswap( x ); }
} // namespace cpp
#else
#include <cstdint>
namespace cpp {
inline constexpr ::std::uint16_t byteswap( ::std::uint16_t v ) noexcept {
return ( v << 8U ) | ( v >> 8U );
}
inline constexpr ::std::uint32_t byteswap( ::std::uint32_t v ) noexcept {
return
( (::std::uint32_t)byteswap((::std::uint16_t)( v & 0xFFFFU )) << 16U )
|
( (::std::uint32_t)byteswap((::std::uint16_t)( v >> 16U )) );
}
inline constexpr uint64_t byteswap( ::std::uint64_t v ) noexcept {
return
( (::std::uint64_t)byteswap((::std::uint32_t)( v & 0xFFFFFFFFUL )) << 32U )
|
( (::std::uint64_t)byteswap((::std::uint32_t)( v >> 32U )) );
}
} // namespace cpp
#endif // __cpp_lib_byteswap
//////////////// has_single_bit, bit_ceil, bit_floor, bit_width //////////////////////////
#ifdef __cpp_lib_int_pow2
namespace cpp {
template <class T> requires ( false/*Consider use `std::has_single_bit`*/ )
inline constexpr bool has_single_bit( T x ) noexcept { return ::std::has_single_bit( x ); }
template <class T> requires ( false/*Consider use `std::bit_ceil`*/ )
inline constexpr T bit_ceil( T x ) noexcept { return ::std::bit_ceil( x ); }
template <class T> requires ( false/*Consider use `std::bit_floor`*/ )
inline constexpr T bit_floor( T x ) noexcept { return ::std::bit_floor( x ); }
template <class T> requires ( false/*Consider use `std::bit_width`*/ )
inline constexpr T bit_width( T x ) noexcept { return ::std::bit_width( x ); }
} // namespace cpp
#else
#pragma message("__cpp_lib_int_pow2 feature unavailable, consider use `cpp::has_single_bit` \
, `cpp::bit_ceil`, `cpp::bit_floor`, `cpp::bit_width`")
#include <limits>
#include <type_traits>
namespace cpp {
/** @copyright As the original source code was taken from [cppreference.com](https://cppreference.com/) site, source
* code of this function is distributed under [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) license.
* @see https://en.cppreference.com/w/cpp/numeric/has_single_bit
*/
template <class T>
inline constexpr bool has_single_bit( T x ) noexcept {
return ::std::popcount( x ) == 1;
}
/** @copyright As the original source code was taken from [cppreference.com](https://cppreference.com/) site, source
* code of this function is distributed under [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) license.
* @see https://en.cppreference.com/w/cpp/numeric/bit_width
*/
template <class T>
inline constexpr T bit_width( T x ) noexcept {
return ::std::numeric_limits<T>::digits - ::std::countl_zero( x );
}
/** @copyright As the original source code was taken from [cppreference.com](https://cppreference.com/) site, source
* code of this function is distributed under [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) license.
* @see https://en.cppreference.com/w/cpp/numeric/bit_ceil
*/
template <class T>
inline constexpr T bit_ceil( T x ) noexcept {
if ( x <= 1U )
return T{ 1 };
if constexpr ( ::std::is_same_v< T, decltype(+x) > )
return T{ 1 } << ::cpp::bit_width( T{ x - 1 } );
else {
constexpr auto offset_for_ub
= ::std::numeric_limits<unsigned>::digits - ::std::numeric_limits<T>::digits;
return T{ 1U << ( ::cpp::bit_width( T{ x - 1 } ) + offset_for_ub ) >> offset_for_ub };
}
}
/** @copyright As the original source code was taken from [cppreference.com](https://cppreference.com/) site, source
* code of this function is distributed under [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) license.
* @see https://en.cppreference.com/w/cpp/numeric/bit_floor
*/
template <class T>
inline constexpr T bit_floor( T x ) noexcept {
if ( x == 0 )
return 0;
return T{ 1 } << ( ::cpp::bit_width( x ) - 1 );
}
} // namespace cpp
#endif // __cpp_lib_int_pow2
///////////////////////// (from|to)_(little|big)_endian //////////////////////////////////
namespace cpp {
template< class T >
inline constexpr T from_little_endian( T v ) noexcept {
return ::std::endian::native == ::std::endian::little
? v : byteswap( v );
}
template< class T >
inline constexpr T to_little_endian( T v ) noexcept {
return from_little_endian( v );
}
template< class T >
inline constexpr T from_big_endian( T v ) noexcept {
return ::std::endian::native == ::std::endian::big
? v : byteswap( v );
}
template< class T >
inline constexpr T to_big_endian( T v ) noexcept {
return from_big_endian( v );
}
} // namespace cpp
#endif // CPPLIB__cpp__lib_bit