Make MSVC version testable
This commit is contained in:
parent
04e4f7b63d
commit
c2540f0577
|
|
@ -13,6 +13,17 @@
|
|||
#include <string>
|
||||
// Other libraries' .h files.
|
||||
// Your project's .h files.
|
||||
#if defined(MSC_VER_) || defined(FORCE_MSC_VER_)
|
||||
# define USE_GCC_INTRINSIC 0
|
||||
// Note: we do not support MSVC intrinsic for now
|
||||
# define USE_MSVC_INTRINSIC 0
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
# define USE_GCC_INTRINSIC 1
|
||||
# define USE_MSVC_INTRINSIC 0
|
||||
#else
|
||||
# define USE_GCC_INTRINSIC 0
|
||||
# define USE_MSVC_INTRINSIC 0
|
||||
#endif
|
||||
|
||||
// Remove these when we upgrade to C++20
|
||||
#pragma GCC diagnostic ignored "-Wpragmas"
|
||||
|
|
|
|||
|
|
@ -102,16 +102,12 @@
|
|||
|
||||
// Compatibility layer for unreachable code hint
|
||||
#if defined(__cplusplus) && __cplusplus >= 202302L
|
||||
// Prefer the standard library version if available
|
||||
# include <utility>
|
||||
# define FST_UNREACHABLE std::unreachable()
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
// --- GCC / Clang ---
|
||||
#elif USE_GCC_INTRINSIC
|
||||
# define FST_UNREACHABLE __builtin_unreachable()
|
||||
#elif defined(_MSC_VER)
|
||||
// --- MSVC ---
|
||||
# define FST_UNREACHABLE __assume(0)
|
||||
// TODO: implement MSVC version
|
||||
// #elif USE_MSVC_INTRINSIC
|
||||
#else
|
||||
// --- Fallback ---
|
||||
# define FST_UNREACHABLE std::abort()
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@
|
|||
#pragma once
|
||||
// direct include
|
||||
// C system headers
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
// C++ standard library headers
|
||||
#if defined(__cplusplus) && __cplusplus >= 202302L
|
||||
# include <bit>
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
|
@ -28,22 +28,24 @@ namespace platform {
|
|||
// clang-format off
|
||||
template <typename U> U to_big_endian(U u) { return u; }
|
||||
#else
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#if defined(__cplusplus) && __cplusplus >= 202302L
|
||||
template <typename U, size_t S>
|
||||
U to_big_endian(U u, std::integral_constant<size_t, S>) {
|
||||
return std::byteswap(u);
|
||||
}
|
||||
#elif USE_GCC_INTRINSIC
|
||||
template<typename U> U to_big_endian(U u, std::integral_constant<size_t, 1>) { return u; }
|
||||
template<typename U> U to_big_endian(U u, std::integral_constant<size_t, 2>) { return __builtin_bswap16(u); }
|
||||
template<typename U> U to_big_endian(U u, std::integral_constant<size_t, 4>) { return __builtin_bswap32(u); }
|
||||
template<typename U> U to_big_endian(U u, std::integral_constant<size_t, 8>) { return __builtin_bswap64(u); }
|
||||
#elif defined(_MSC_VER) // MSVC
|
||||
template<typename U> U to_big_endian(U u, std::integral_constant<size_t, 1>) { return u; }
|
||||
template<typename U> U to_big_endian(U u, std::integral_constant<size_t, 2>) { return _byteswap_ushort(u); }
|
||||
template<typename U> U to_big_endian(U u, std::integral_constant<size_t, 4>) { return _byteswap_ulong(u); }
|
||||
template<typename U> U to_big_endian(U u, std::integral_constant<size_t, 8>) { return _byteswap_uint64(u); }
|
||||
// TODO: implement MSVC version
|
||||
// #elif USE_MSVC_INTRINSIC
|
||||
#else
|
||||
template<typename U, size_t S> U to_big_endian(U u, std::integral_constant<size_t, S>) {
|
||||
U ret{ 0 };
|
||||
template <typename U, size_t S>
|
||||
U to_big_endian(U u, std::integral_constant<size_t, S>) {
|
||||
U ret{0};
|
||||
for (size_t i = 0; i < S; ++i) {
|
||||
ret |= u & 0xff;
|
||||
ret <<= 8;
|
||||
ret = (ret << 8) | (u & 0xff);
|
||||
u >>= 8;
|
||||
}
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@
|
|||
// direct include
|
||||
#include "fstcpp/fstcpp.h"
|
||||
// C system headers
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
// C++ standard library headers
|
||||
#if defined(__cplusplus) && __cplusplus >= 202002L
|
||||
# include <bit>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
|
@ -26,19 +26,29 @@ namespace platform {
|
|||
|
||||
// Can be replaced with std::bit_width when C++20 is available
|
||||
inline uint64_t clog2(uint64_t x) {
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
return 64 - __builtin_clzll(x - 1);
|
||||
#elif defined(_MSC_VER) // MSVC
|
||||
if (x <= 1) return 0;
|
||||
unsigned long index;
|
||||
_BitScanReverse64(&index, x - 1);
|
||||
return static_cast<uint64_t>(index + 1);
|
||||
#if defined(__cplusplus) && __cplusplus >= 202002L
|
||||
return std::bit_width(x - 1);
|
||||
#elif USE_GCC_INTRINSIC
|
||||
return 64 - __builtin_clzll(x - 1);
|
||||
// TODO: implement MSVC version
|
||||
// #elif USE_MSVC_INTRINSIC
|
||||
#else
|
||||
uint64_t r = 0;
|
||||
while (x > 1) {
|
||||
x >>= 1;
|
||||
r++;
|
||||
}
|
||||
x -= 1;
|
||||
auto CheckAndShift = [&](uint64_t shift) {
|
||||
if (x >> shift) {
|
||||
r += shift;
|
||||
x >>= shift;
|
||||
}
|
||||
};
|
||||
CheckAndShift(32);
|
||||
CheckAndShift(16);
|
||||
CheckAndShift(8);
|
||||
CheckAndShift(4);
|
||||
CheckAndShift(2);
|
||||
CheckAndShift(1);
|
||||
r += x;
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue