From 5e3423a3772827283193f997f221a138a310d1ac Mon Sep 17 00:00:00 2001 From: Charlie Barto Date: Wed, 1 Jul 2020 20:27:49 -0700 Subject: [PATCH] MSVC (#795) Adds MSVC support to the `` functions. --- stl/inc/bit | 135 ++++++++++++++++-- stl/inc/limits | 102 +++++++++++-- stl/inc/numeric | 31 +--- stl/inc/type_traits | 7 - stl/inc/xtr1common | 7 + stl/inc/yvals_core.h | 21 +-- tests/libcxx/expected_results.txt | 11 +- tests/libcxx/skipped_tests.txt | 11 +- .../test.cpp | 25 +++- .../test.cpp | 4 - .../VSO_0157762_feature_test_macros/test.cpp | 4 +- 11 files changed, 260 insertions(+), 98 deletions(-) diff --git a/stl/inc/bit b/stl/inc/bit index 2700af09d..0aa8f4451 100644 --- a/stl/inc/bit +++ b/stl/inc/bit @@ -12,6 +12,8 @@ #pragma message("The contents of are available only with C++20 or later.") #else // ^^^ !_HAS_CXX20 / _HAS_CXX20 vvv +#include +#include #include #include @@ -23,6 +25,7 @@ _STL_DISABLE_CLANG_WARNINGS #undef new _STD_BEGIN + template , is_trivially_copyable<_To>, is_trivially_copyable<_From>>, @@ -31,7 +34,6 @@ _NODISCARD constexpr _To bit_cast(const _From& _Val) noexcept { return __builtin_bit_cast(_To, _Val); } -#ifdef __cpp_lib_bitops // TRANSITION, VSO-1020212 template , int> = 0> _NODISCARD constexpr int countl_zero(_Ty _Val) noexcept; @@ -94,17 +96,126 @@ _NODISCARD constexpr _Ty rotr(const _Ty _Val, const int _Rotation) noexcept { } } -template , int> _Enabled> -_NODISCARD constexpr int countl_zero(const _Ty _Val) noexcept { +// Implementation of popcount without using specialized CPU instructions. +// Used at compile time and when said instructions are not supported. +template +_NODISCARD constexpr int _Popcount_fallback(_Ty _Val) noexcept { + constexpr int _Digits = numeric_limits<_Ty>::digits; + // we static_cast these bit patterns in order to truncate them to the correct size + _Val = static_cast<_Ty>(_Val - ((_Val >> 1) & static_cast<_Ty>(0x5555'5555'5555'5555ull))); + _Val = static_cast<_Ty>((_Val & static_cast<_Ty>(0x3333'3333'3333'3333ull)) + + ((_Val >> 2) & static_cast<_Ty>(0x3333'3333'3333'3333ull))); + _Val = static_cast<_Ty>((_Val + (_Val >> 4)) & static_cast<_Ty>(0x0F0F'0F0F'0F0F'0F0Full)); + for (int _Shift_digits = 8; _Shift_digits < _Digits; _Shift_digits <<= 1) { + _Val = static_cast<_Ty>(_Val + static_cast<_Ty>(_Val >> _Shift_digits)); + } + // we want the bottom "slot" that's big enough to store _Digits + return static_cast(_Val & static_cast<_Ty>(_Digits + _Digits - 1)); +} + +#if defined(_M_IX86) || defined(_M_X64) + +// TRANSITION, VS 2019 16.8 Preview 1, intrin0.h will declare __lzcnt* and __popcnt* +extern "C" { +__MACHINEX86_X64(unsigned int __lzcnt(unsigned int)) +__MACHINEX86_X64(unsigned short __lzcnt16(unsigned short)) +__MACHINEX64(unsigned __int64 __lzcnt64(unsigned __int64)) +__MACHINEX86_X64(unsigned int __popcnt(unsigned int)) +__MACHINEX86_X64(unsigned short __popcnt16(unsigned short)) +__MACHINEX64(unsigned __int64 __popcnt64(unsigned __int64)) +extern int __isa_available; +} + +template +_NODISCARD int _Checked_x86_x64_countl_zero(const _Ty _Val) noexcept { + constexpr int _Digits = numeric_limits<_Ty>::digits; + +#ifndef __AVX2__ + const bool _Have_lzcnt = __isa_available >= __ISA_AVAILABLE_AVX2; + // lzcnt (when it doesn't fall back to bsr) is defined correctly for zero + // bsr has undefined output for zero + if (!_Have_lzcnt && _Val == 0) { + return _Digits; + } +#endif // __AVX2__ + + // We use lzcnt (actually bsr if lzcnt is not supported) now that we know + // we're not zero. We can do this because lzcnt and bsr share the same instruction + // encoding. + if constexpr (_Digits <= 16) { + return static_cast(__lzcnt16(_Val) - (16 - _Digits)); + } else if constexpr (_Digits == 32) { + return static_cast(__lzcnt(_Val)); + } else { +#ifdef _M_IX86 + const unsigned int _High = _Val >> 32; + const auto _Low = static_cast(_Val); + if (_High == 0) { + return 32 + _Checked_x86_x64_countl_zero(_Low); + } else { + return _Checked_x86_x64_countl_zero(_High); + } +#else // ^^^ _M_IX86 / !_M_IX86 vvv + return static_cast(__lzcnt64(_Val)); +#endif // _M_IX86 + } + // note: we don't need to call a fallback here because + // all supported x86 processors at least have bsr/bsf +} + +template +_NODISCARD int _Checked_x86_x64_popcount(const _Ty _Val) noexcept { + constexpr int _Digits = numeric_limits<_Ty>::digits; +#ifndef __AVX__ + const bool _Have_popcnt = __isa_available >= __ISA_AVAILABLE_SSE42; + if (!_Have_popcnt) { + return _Popcount_fallback(_Val); + } +#endif // !defined(__AVX__) + + if constexpr (_Digits <= 16) { + return static_cast(__popcnt16(_Val)); + } else if constexpr (_Digits == 32) { + return static_cast(__popcnt(_Val)); + } else { +#ifdef _M_IX86 + return static_cast(__popcnt(_Val >> 32) + __popcnt(static_cast(_Val))); +#else // ^^^ _M_IX86 / !_M_IX86 vvv + return static_cast(__popcnt64(_Val)); +#endif // _M_IX86 + } +} +#endif // defined(_M_IX86) || defined(_M_X64) + + +#if defined(_M_ARM) || defined(_M_ARM64) +template +_NODISCARD int _Checked_arm_arm64_countl_zero(const _Ty _Val) noexcept { constexpr int _Digits = numeric_limits<_Ty>::digits; if (_Val == 0) { return _Digits; } - if constexpr (sizeof(_Ty) <= sizeof(unsigned int)) { - return __builtin_clz(_Val) - (numeric_limits::digits - _Digits); + if constexpr (_Digits <= 32) { + return _CountLeadingZeros(_Val); } else { - return __builtin_clzll(_Val) - (numeric_limits::digits - _Digits); + return _CountLeadingZeros64(_Val); + } +} +#endif // defined(_M_ARM) || defined(_M_ARM64) + +template , int> _Enabled> +_NODISCARD constexpr int countl_zero(const _Ty _Val) noexcept { + if (_STD is_constant_evaluated()) { + return _Countl_zero_fallback(_Val); + } else { +#if defined(_M_IX86) || defined(_M_X64) + return _Checked_x86_x64_countl_zero(_Val); +#elif defined(_M_ARM) || defined(_M_ARM64) + return _Checked_arm_arm64_countl_zero(_Val); +#else +#error Unsupported Hardware +#endif } } @@ -125,17 +236,17 @@ _NODISCARD constexpr int countr_one(const _Ty _Val) noexcept { template , int> _Enabled = 0> _NODISCARD constexpr int popcount(const _Ty _Val) noexcept { - if constexpr (sizeof(_Ty) <= sizeof(unsigned int)) { - return __builtin_popcount(_Val); - } else { - return __builtin_popcountll(_Val); +#if defined(_M_IX86) || defined(_M_X64) + if (!_STD is_constant_evaluated()) { + return _Checked_x86_x64_popcount(_Val); } +#endif // defined(_M_IX86) || defined(_M_X64) + return _Popcount_fallback(_Val); } -#endif // __cpp_lib_bitops enum class endian { little = 0, big = 1, native = little }; -_STD_END +_STD_END #pragma pop_macro("new") _STL_RESTORE_CLANG_WARNINGS #pragma warning(pop) diff --git a/stl/inc/limits b/stl/inc/limits index 6bfa75c2b..e1e8f9003 100644 --- a/stl/inc/limits +++ b/stl/inc/limits @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #pragma pack(push, _CRT_PACKING) @@ -1009,24 +1011,102 @@ public: static constexpr int min_exponent10 = LDBL_MIN_10_EXP; }; -#ifdef __cpp_lib_bitops // TRANSITION, VSO-1020212 +// Implementation of countl_zero without using specialized CPU instructions. +// Used at compile time and when said instructions are not supported. +// see "Hacker's Delight" section 5-3 template -inline constexpr bool _Is_standard_unsigned_integer = +_NODISCARD constexpr int _Countl_zero_fallback(_Ty _Val) noexcept { + _Ty _Yy = 0; + + unsigned int _Nn = numeric_limits<_Ty>::digits; + unsigned int _Cc = numeric_limits<_Ty>::digits / 2; + do { + _Yy = static_cast<_Ty>(_Val >> _Cc); + if (_Yy != 0) { + _Nn -= _Cc; + _Val = _Yy; + } + _Cc >>= 1; + } while (_Cc != 0); + return static_cast(_Nn) - static_cast(_Val); +} + +// Implementation of countr_zero without using specialized CPU instructions. +// Used at compile time and when said instructions are not supported. +// see "Hacker's Delight" section 5-4 +template +_NODISCARD constexpr int _Countr_zero_fallback(const _Ty _Val) noexcept { + constexpr int _Digits = std::numeric_limits<_Ty>::digits; + return _Digits - _Countl_zero_fallback(static_cast<_Ty>(static_cast<_Ty>(~_Val) & static_cast<_Ty>(_Val - 1))); +} + +#if defined(_M_IX86) || defined(_M_X64) + +// TRANSITION, VS 2019 16.8 Preview 1, intrin0.h will declare _tzcnt* +extern "C" { +extern int __isa_available; +#ifdef __clang__ +#define _TZCNT_U32 __builtin_ia32_tzcnt_u32 +#define _TZCNT_U64 __builtin_ia32_tzcnt_u64 +#else // ^^^ __clang__ / !__clang__ vvv +__MACHINEX86_X64(unsigned int _tzcnt_u32(unsigned int)) +__MACHINEX64(unsigned __int64 _tzcnt_u64(unsigned __int64)); +#define _TZCNT_U32 _tzcnt_u32 +#define _TZCNT_U64 _tzcnt_u64 +#endif // __clang__ +} + +template +_NODISCARD int _Checked_x86_x64_countr_zero(const _Ty _Val) noexcept { + constexpr int _Digits = numeric_limits<_Ty>::digits; + constexpr _Ty _Max = (numeric_limits<_Ty>::max)(); + +#ifndef __AVX2__ + const bool _Have_tzcnt = __isa_available >= __ISA_AVAILABLE_AVX2; + if (!_Have_tzcnt && _Val == 0) { + return _Digits; + } +#endif // __AVX2__ + + if constexpr (_Digits <= 32) { + // Intended widening to int. This operation means that a narrow 0 will widen + // to 0xFFFF....FFFF0... instead of 0. We need this to avoid counting all the zeros + // of the wider type. + return static_cast(_TZCNT_U32(static_cast(~_Max | _Val))); + } else { +#ifdef _M_IX86 + const unsigned int _High = _Val >> 32; + const unsigned int _Low = static_cast(_Val); + if (_Low == 0) { + return 32 + _Checked_x86_x64_countr_zero(_High); + } else { + return _Checked_x86_x64_countr_zero(_Low); + } +#else // ^^^ _M_IX86 / !_M_IX86 vvv + return static_cast(_TZCNT_U64(_Val)); +#endif // _M_IX86 + } +} +#undef _TZCNT_U32 +#undef _TZCNT_U64 +#endif // defined(_M_IX86) || defined(_M_X64) + +template +constexpr bool _Is_standard_unsigned_integer = _Is_any_of_v, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>; template , int> = 0> _NODISCARD constexpr int _Countr_zero(const _Ty _Val) noexcept { - if (_Val == 0) { - return numeric_limits<_Ty>::digits; - } - - if constexpr (sizeof(_Ty) <= sizeof(unsigned int)) { - return __builtin_ctz(_Val); - } else { - return __builtin_ctzll(_Val); +#if defined(_M_IX86) || defined(_M_X64) +#ifdef __cpp_lib_is_constant_evaluated + if (!_STD is_constant_evaluated()) { + return _Checked_x86_x64_countr_zero(_Val); } +#endif // defined(__cpp_lib_is_constant_evaluated) +#endif // defined(_M_IX86) || defined(_M_X64) + // C++17 constexpr gcd() calls this function, so it should be constexpr unless we detect runtime evaluation. + return _Countr_zero_fallback(_Val); } -#endif // __cpp_lib_bitops _STD_END #pragma pop_macro("new") diff --git a/stl/inc/numeric b/stl/inc/numeric index 2733891bc..bb22f2d3c 100644 --- a/stl/inc/numeric +++ b/stl/inc/numeric @@ -10,9 +10,9 @@ #if _STL_COMPILER_PREPROCESSOR #include -#if _HAS_CXX20 +#if _HAS_CXX17 #include -#endif // _HAS_CXX20 +#endif // _HAS_CXX17 #pragma pack(push, _CRT_PACKING) #pragma warning(push, _STL_WARNING_LEVEL) @@ -560,26 +560,6 @@ _NODISCARD constexpr auto _Abs_u(const _Arithmetic _Val) noexcept { } } -// FUNCTION TEMPLATE _Stl_bitscan_forward -template -_NODISCARD constexpr unsigned long _Stl_bitscan_forward(_Unsigned _Mask) noexcept { -#ifdef __cpp_lib_bitops // TRANSITION, VSO-1020212 - return static_cast(_Countr_zero(_Mask)); -#else // ^^^ __cpp_lib_bitops / !__cpp_lib_bitops vvv - // find the index of the least significant set bit (_BitScanForward isn't constexpr... yet :)) - static_assert(is_unsigned_v<_Unsigned>, "Bitscan only works on bits"); - unsigned long _Count = 0; - if (_Mask != 0) { - while ((_Mask & 1U) == 0) { - _Mask >>= 1; - ++_Count; - } - } - - return _Count; -#endif // !__cpp_lib_bitops -} - // FUNCTION TEMPLATE gcd template _NODISCARD constexpr common_type_t<_Mt, _Nt> gcd(const _Mt _Mx, const _Nt _Nx) noexcept /* strengthened */ { @@ -598,12 +578,13 @@ _NODISCARD constexpr common_type_t<_Mt, _Nt> gcd(const _Mt _Mx, const _Nt _Nx) n return static_cast<_Common>(_Mx_magnitude); } - const auto _Mx_trailing_zeroes = _Stl_bitscan_forward(_Mx_magnitude); - const auto _Common_factors_of_2 = (_STD min)(_Mx_trailing_zeroes, _Stl_bitscan_forward(_Nx_magnitude)); + const auto _Mx_trailing_zeroes = static_cast(_Countr_zero(_Mx_magnitude)); + const auto _Common_factors_of_2 = + (_STD min)(_Mx_trailing_zeroes, static_cast(_Countr_zero(_Nx_magnitude))); _Nx_magnitude >>= _Common_factors_of_2; _Mx_magnitude >>= _Mx_trailing_zeroes; do { - _Nx_magnitude >>= _Stl_bitscan_forward(_Nx_magnitude); + _Nx_magnitude >>= static_cast(_Countr_zero(_Nx_magnitude)); if (_Mx_magnitude > _Nx_magnitude) { _Common_unsigned _Temp = _Mx_magnitude; _Mx_magnitude = _Nx_magnitude; diff --git a/stl/inc/type_traits b/stl/inc/type_traits index a6916bda1..329f23808 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -1842,13 +1842,6 @@ inline constexpr bool is_nothrow_invocable_r_v = _Select_invoke_traits<_Callable, _Args...>::template _Is_nothrow_invocable_r<_Rx>::value; #endif // _HAS_CXX17 -#if _HAS_CXX20 -// FUNCTION is_constant_evaluated -_NODISCARD constexpr bool is_constant_evaluated() noexcept { - return __builtin_is_constant_evaluated(); -} -#endif // _HAS_CXX20 - // STRUCT TEMPLATE _Weak_types template struct _Weak_result_type {}; // default definition diff --git a/stl/inc/xtr1common b/stl/inc/xtr1common index 7b25ecedc..b7b3ef44e 100644 --- a/stl/inc/xtr1common +++ b/stl/inc/xtr1common @@ -175,6 +175,13 @@ template _INLINE_VAR constexpr bool _Is_any_of_v = // true if and only if _Ty is in _Types disjunction_v...>; +#if _HAS_CXX20 +// FUNCTION is_constant_evaluated +_NODISCARD constexpr bool is_constant_evaluated() noexcept { + return __builtin_is_constant_evaluated(); +} +#endif // _HAS_CXX20 + // STRUCT TEMPLATE is_integral template _INLINE_VAR constexpr bool is_integral_v = _Is_any_of_v, bool, char, signed char, unsigned char, diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index d4b3c4ed3..e07269fbe 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1140,13 +1140,8 @@ #define __cpp_lib_atomic_shared_ptr 201711L #define __cpp_lib_bind_front 201907L #define __cpp_lib_bit_cast 201806L - -#ifdef __clang__ // TRANSITION, VSO-1020212 -// a future MSVC update will embed CPU feature detection into intrinsics -#define __cpp_lib_bitops 201907L -#endif // __clang__ - -#define __cpp_lib_bounded_array_traits 201902L +#define __cpp_lib_bitops 201907L +#define __cpp_lib_bounded_array_traits 201902L #ifdef __cpp_char8_t #define __cpp_lib_char8_t 201907L @@ -1174,14 +1169,10 @@ #define __cpp_lib_destroying_delete 201806L #endif // __cpp_impl_destroying_delete -#define __cpp_lib_endian 201907L -#define __cpp_lib_erase_if 202002L -#define __cpp_lib_generic_unordered_lookup 201811L - -#ifdef __cpp_lib_bitops // TRANSITION, VSO-1020212 -#define __cpp_lib_int_pow2 202002L -#endif - +#define __cpp_lib_endian 201907L +#define __cpp_lib_erase_if 202002L +#define __cpp_lib_generic_unordered_lookup 201811L +#define __cpp_lib_int_pow2 202002L #define __cpp_lib_integer_comparison_functions 202002L #define __cpp_lib_is_constant_evaluated 201811L #define __cpp_lib_is_nothrow_convertible 201806L diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index aa095600e..a0bb54a84 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -62,6 +62,8 @@ std/numerics/bit/bit.pow.two/floor2.pass.cpp FAIL std/numerics/bit/bit.pow.two/ispow2.pass.cpp FAIL std/numerics/bit/bit.pow.two/log2p1.pass.cpp FAIL +# test emits warning C4310: cast truncates constant value +std/numerics/bit/bitops.rot/rotl.pass.cpp:0 FAIL # *** INTERACTIONS WITH CONTEST / C1XX THAT UPSTREAM LIKELY WON'T FIX *** # Tracked by VSO-593630 " Enable libcxx filesystem tests" @@ -454,15 +456,6 @@ std/utilities/time/time.hms/time.hms.members/subseconds.pass.cpp FAIL std/utilities/time/time.hms/time.hms.members/to_duration.pass.cpp FAIL std/utilities/time/time.hms/time.hms.members/width.pass.cpp FAIL -# C++20 P0553R4 " Rotating And Counting Functions" -std/numerics/bit/bitops.count/countl_one.pass.cpp:0 FAIL -std/numerics/bit/bitops.count/countl_zero.pass.cpp:0 FAIL -std/numerics/bit/bitops.count/countr_one.pass.cpp:0 FAIL -std/numerics/bit/bitops.count/countr_zero.pass.cpp:0 FAIL -std/numerics/bit/bitops.count/popcount.pass.cpp:0 FAIL -std/numerics/bit/bitops.rot/rotl.pass.cpp:0 FAIL -std/numerics/bit/bitops.rot/rotr.pass.cpp:0 FAIL - # C++20 P0608R3 "Improving variant's Converting Constructor/Assignment" std/utilities/variant/variant.variant/variant.assign/conv.pass.cpp FAIL std/utilities/variant/variant.variant/variant.assign/T.pass.cpp FAIL diff --git a/tests/libcxx/skipped_tests.txt b/tests/libcxx/skipped_tests.txt index 0e365989c..92764fd5b 100644 --- a/tests/libcxx/skipped_tests.txt +++ b/tests/libcxx/skipped_tests.txt @@ -62,6 +62,8 @@ numerics\bit\bit.pow.two\floor2.pass.cpp numerics\bit\bit.pow.two\ispow2.pass.cpp numerics\bit\bit.pow.two\log2p1.pass.cpp +# test emits warning C4310: cast truncates constant value +numerics\bit\bitops.rot\rotl.pass.cpp # *** INTERACTIONS WITH CONTEST / C1XX THAT UPSTREAM LIKELY WON'T FIX *** # Tracked by VSO-593630 " Enable libcxx filesystem tests" @@ -454,15 +456,6 @@ utilities\time\time.hms\time.hms.members\subseconds.pass.cpp utilities\time\time.hms\time.hms.members\to_duration.pass.cpp utilities\time\time.hms\time.hms.members\width.pass.cpp -# C++20 P0553R4 " Rotating And Counting Functions" -numerics\bit\bitops.count\countl_one.pass.cpp -numerics\bit\bitops.count\countl_zero.pass.cpp -numerics\bit\bitops.count\countr_one.pass.cpp -numerics\bit\bitops.count\countr_zero.pass.cpp -numerics\bit\bitops.count\popcount.pass.cpp -numerics\bit\bitops.rot\rotl.pass.cpp -numerics\bit\bitops.rot\rotr.pass.cpp - # C++20 P0608R3 "Improving variant's Converting Constructor/Assignment" utilities\variant\variant.variant\variant.assign\conv.pass.cpp utilities\variant\variant.variant\variant.assign\T.pass.cpp diff --git a/tests/std/tests/P0553R4_bit_rotating_and_counting_functions/test.cpp b/tests/std/tests/P0553R4_bit_rotating_and_counting_functions/test.cpp index c7e45f1f0..95eb50bd0 100644 --- a/tests/std/tests/P0553R4_bit_rotating_and_counting_functions/test.cpp +++ b/tests/std/tests/P0553R4_bit_rotating_and_counting_functions/test.cpp @@ -6,7 +6,6 @@ using namespace std; -#ifdef __cpp_lib_bitops // TRANSITION, VSO-1020212 template constexpr bool test_countl_zero() { constexpr int digits = numeric_limits::digits; @@ -105,6 +104,25 @@ constexpr bool test_rotr() { return true; } +// Tests functions for 64-bit operands that have either high or low halves as zero. +// These may be split into two operations on 32-bit platforms and we need to check +// if we handle the == zero or == ones case correctly. +constexpr bool test_64bit_split_ops() { + constexpr unsigned long long zero_one = 0x0000'0000'FFFF'FFFF; + constexpr unsigned long long one_zero = 0xFFFF'FFFF'0000'0000; + assert(popcount(zero_one) == 32); + assert(popcount(one_zero) == 32); + assert(countr_zero(zero_one) == 0); + assert(countr_zero(one_zero) == 32); + assert(countl_zero(zero_one) == 32); + assert(countl_zero(one_zero) == 0); + assert(countr_one(zero_one) == 32); + assert(countr_one(one_zero) == 0); + assert(countl_one(zero_one) == 0); + assert(countl_one(one_zero) == 32); + return true; +} + template constexpr bool test_popcount_specialcases() { constexpr int digits = numeric_limits::digits; @@ -153,17 +171,16 @@ void test_all() { test_rotl(); static_assert(test_rotr()); test_rotr(); + static_assert(test_64bit_split_ops()); + test_64bit_split_ops(); static_assert(test_popcount_specialcases()); test_popcount_specialcases(); } -#endif // __cpp_lib_bitops int main() { -#ifdef __cpp_lib_bitops // TRANSITION, VSO-1020212 test_all(); test_all(); test_all(); test_all(); test_all(); -#endif // __cpp_lib_bitops } diff --git a/tests/std/tests/P0556R3_bit_integral_power_of_two_operations/test.cpp b/tests/std/tests/P0556R3_bit_integral_power_of_two_operations/test.cpp index b6956d9a1..40bbfc0f0 100644 --- a/tests/std/tests/P0556R3_bit_integral_power_of_two_operations/test.cpp +++ b/tests/std/tests/P0556R3_bit_integral_power_of_two_operations/test.cpp @@ -7,7 +7,6 @@ using namespace std; -#ifdef __cpp_lib_bitops // TRANSITION, VSO-1020212 template constexpr bool test_has_single_bit() { assert(!has_single_bit(T{0})); @@ -97,10 +96,8 @@ void test_all() { static_assert(test_bit_width()); test_bit_width(); } -#endif // __cpp_lib_bitops int main() { -#ifdef __cpp_lib_bitops // TRANSITION, VSO-1020212 test_all(); test_all(); test_all(); @@ -108,5 +105,4 @@ int main() { test_all(); test_bit_floor_specialcases_unsigned(); test_bit_ceil_specialcases_unsigned(); -#endif // __cpp_lib_bitops } diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.cpp index df60d4514..6e6be315c 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.cpp @@ -189,7 +189,7 @@ STATIC_ASSERT(__cpp_lib_bit_cast == 201806L); #endif #endif -#if _HAS_CXX20 && defined(__clang__) // TRANSITION, VSO-1020212 +#if _HAS_CXX20 #ifndef __cpp_lib_bitops #error __cpp_lib_bitops is not defined #elif __cpp_lib_bitops != 201907L @@ -641,7 +641,7 @@ STATIC_ASSERT(__cpp_lib_hypot == 201603L); STATIC_ASSERT(__cpp_lib_incomplete_container_elements == 201505L); #endif -#if _HAS_CXX20 && defined(__clang__) // TRANSITION, VSO-1020212 +#if _HAS_CXX20 #ifndef __cpp_lib_int_pow2 #error __cpp_lib_int_pow2 is not defined #elif __cpp_lib_int_pow2 != 202002L