зеркало из https://github.com/microsoft/STL.git
P1272R4 `byteswap()` (#2235)
Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
This commit is contained in:
Родитель
89f7204662
Коммит
a6718c2b81
45
stl/inc/bit
45
stl/inc/bit
|
@ -233,6 +233,34 @@ _NODISCARD int _Checked_arm_arm64_countl_zero(const _Ty _Val) noexcept {
|
|||
}
|
||||
#endif // defined(_M_ARM) || defined(_M_ARM64)
|
||||
|
||||
#if _HAS_CXX23
|
||||
_NODISCARD constexpr unsigned short _Byteswap_ushort(const unsigned short _Val) noexcept {
|
||||
if (_STD is_constant_evaluated()) {
|
||||
return static_cast<unsigned short>((_Val << 8) | (_Val >> 8));
|
||||
} else {
|
||||
return _byteswap_ushort(_Val);
|
||||
}
|
||||
}
|
||||
|
||||
_NODISCARD constexpr unsigned long _Byteswap_ulong(const unsigned long _Val) noexcept {
|
||||
if (_STD is_constant_evaluated()) {
|
||||
return (_Val << 24) | ((_Val << 8) & 0x00FF'0000) | ((_Val >> 8) & 0x0000'FF00) | (_Val >> 24);
|
||||
} else {
|
||||
return _byteswap_ulong(_Val);
|
||||
}
|
||||
}
|
||||
|
||||
_NODISCARD constexpr unsigned long long _Byteswap_uint64(const unsigned long long _Val) noexcept {
|
||||
if (_STD is_constant_evaluated()) {
|
||||
return (_Val << 56) | ((_Val << 40) & 0x00FF'0000'0000'0000) | ((_Val << 24) & 0x0000'FF00'0000'0000)
|
||||
| ((_Val << 8) & 0x0000'00FF'0000'0000) | ((_Val >> 8) & 0x0000'0000'FF00'0000)
|
||||
| ((_Val >> 24) & 0x0000'0000'00FF'0000) | ((_Val >> 40) & 0x0000'0000'0000'FF00) | (_Val >> 56);
|
||||
} else {
|
||||
return _byteswap_uint64(_Val);
|
||||
}
|
||||
}
|
||||
#endif // _HAS_CXX23
|
||||
|
||||
template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> _Enabled>
|
||||
_NODISCARD constexpr int countl_zero(const _Ty _Val) noexcept {
|
||||
#if defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))
|
||||
|
@ -268,6 +296,23 @@ _NODISCARD constexpr int popcount(const _Ty _Val) noexcept {
|
|||
return _Popcount(_Val);
|
||||
}
|
||||
|
||||
#if _HAS_CXX23
|
||||
template <class _Ty, enable_if_t<is_integral_v<_Ty>, int> = 0>
|
||||
_NODISCARD constexpr _Ty byteswap(const _Ty _Val) noexcept {
|
||||
if constexpr (sizeof(_Ty) == 1) {
|
||||
return _Val;
|
||||
} else if constexpr (sizeof(_Ty) == 2) {
|
||||
return static_cast<_Ty>(_Byteswap_ushort(static_cast<unsigned short>(_Val)));
|
||||
} else if constexpr (sizeof(_Ty) == 4) {
|
||||
return static_cast<_Ty>(_Byteswap_ulong(static_cast<unsigned long>(_Val)));
|
||||
} else if constexpr (sizeof(_Ty) == 8) {
|
||||
return static_cast<_Ty>(_Byteswap_uint64(static_cast<unsigned long long>(_Val)));
|
||||
} else {
|
||||
static_assert(_Always_false<_Ty>, "Unexpected integer size");
|
||||
}
|
||||
}
|
||||
#endif // _HAS_CXX23
|
||||
|
||||
enum class endian { little = 0, big = 1, native = little };
|
||||
|
||||
_STD_END
|
||||
|
|
|
@ -275,6 +275,7 @@
|
|||
// P0943R6 Supporting C Atomics In C++
|
||||
// P1048R1 is_scoped_enum
|
||||
// P1132R7 out_ptr(), inout_ptr()
|
||||
// P1272R4 byteswap()
|
||||
// P1425R4 Iterator Pair Constructors For stack And queue
|
||||
// P1659R3 ranges::starts_with, ranges::ends_with
|
||||
// P1679R3 contains() For basic_string/basic_string_view
|
||||
|
@ -1363,6 +1364,7 @@
|
|||
#define __cpp_lib_allocate_at_least 202106L
|
||||
#endif // __cpp_lib_concepts
|
||||
|
||||
#define __cpp_lib_byteswap 202110L
|
||||
#define __cpp_lib_invoke_r 202106L
|
||||
#define __cpp_lib_is_scoped_enum 202011L
|
||||
|
||||
|
|
|
@ -435,6 +435,7 @@ tests\P1135R6_latch
|
|||
tests\P1135R6_semaphore
|
||||
tests\P1165R1_consistently_propagating_stateful_allocators
|
||||
tests\P1208R6_source_location
|
||||
tests\P1272R4_byteswap
|
||||
tests\P1423R3_char8_t_remediation
|
||||
tests\P1425R4_queue_stack_constructors
|
||||
tests\P1502R1_standard_library_header_units
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
RUNALL_INCLUDE ..\usual_latest_matrix.lst
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include <bit>
|
||||
#include <cassert>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
constexpr bool test_byteswap(const auto src, const auto result) {
|
||||
static_assert(noexcept(byteswap(T{})));
|
||||
return byteswap(static_cast<T>(src)) == static_cast<T>(result);
|
||||
}
|
||||
|
||||
constexpr bool test_byteswap_all_types() {
|
||||
assert(test_byteswap<bool>(true, true));
|
||||
|
||||
assert(test_byteswap<char>(0x13, 0x13));
|
||||
assert(test_byteswap<signed char>(0x13, 0x13));
|
||||
assert(test_byteswap<unsigned char>(0x13, 0x13));
|
||||
#ifdef __cpp_char8_t
|
||||
assert(test_byteswap<char8_t>(0x13, 0x13));
|
||||
#endif
|
||||
|
||||
assert(test_byteswap<short>(0xAC34, 0x34AC));
|
||||
assert(test_byteswap<unsigned short>(0xAC34, 0x34AC));
|
||||
assert(test_byteswap<char16_t>(0xAC34, 0x34AC));
|
||||
assert(test_byteswap<wchar_t>(0xAC34, 0x34AC));
|
||||
|
||||
assert(test_byteswap<int>(0x1234ABCD, 0xCDAB3412));
|
||||
assert(test_byteswap<unsigned int>(0x1234ABCD, 0xCDAB3412));
|
||||
assert(test_byteswap<long>(0x1234ABCD, 0xCDAB3412));
|
||||
assert(test_byteswap<unsigned long>(0x1234ABCD, 0xCDAB3412));
|
||||
assert(test_byteswap<char32_t>(0x1234ABCD, 0xCDAB3412));
|
||||
|
||||
assert(test_byteswap<long long>(0x1234567890ABCDEF, 0xEFCDAB9078563412));
|
||||
assert(test_byteswap<unsigned long long>(0x1234567890ABCDEF, 0xEFCDAB9078563412));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static_assert(test_byteswap_all_types());
|
||||
|
||||
int main() {
|
||||
test_byteswap_all_types();
|
||||
}
|
|
@ -336,6 +336,20 @@ STATIC_ASSERT(__cpp_lib_byte == 201603L);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if _HAS_CXX23
|
||||
#ifndef __cpp_lib_byteswap
|
||||
#error __cpp_lib_byteswap is not defined
|
||||
#elif __cpp_lib_byteswap != 202110L
|
||||
#error __cpp_lib_byteswap is not 202110L
|
||||
#else
|
||||
STATIC_ASSERT(__cpp_lib_byteswap == 202110L);
|
||||
#endif
|
||||
#else
|
||||
#ifdef __cpp_lib_byteswap
|
||||
#error __cpp_lib_byteswap is defined
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if _HAS_CXX20 && defined(__cpp_char8_t)
|
||||
#ifndef __cpp_lib_char8_t
|
||||
#error __cpp_lib_char8_t is not defined
|
||||
|
|
Загрузка…
Ссылка в новой задаче