-
Notifications
You must be signed in to change notification settings - Fork 3
/
portability_builtins.hpp
77 lines (66 loc) · 2.19 KB
/
portability_builtins.hpp
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
// Copyright 2022 Laurynas Biveinis
#ifndef UNODB_DETAIL_PORTABILITY_BUILTINS_HPP
#define UNODB_DETAIL_PORTABILITY_BUILTINS_HPP
#include "global.hpp"
#include <cstdint>
#include <gsl/util>
#ifdef UNODB_DETAIL_MSVC
#include <intrin.h>
#endif
namespace unodb::detail {
[[nodiscard, gnu::pure]] UNODB_DETAIL_CONSTEXPR_NOT_MSVC std::uint64_t bswap(
std::uint64_t x) noexcept {
#ifndef UNODB_DETAIL_MSVC
return __builtin_bswap64(x);
#else
return _byteswap_uint64(x);
#endif
}
template <typename T>
[[nodiscard, gnu::pure]] UNODB_DETAIL_CONSTEXPR_NOT_MSVC std::uint8_t ctz(
T x) noexcept {
static_assert(std::is_same_v<unsigned, T> ||
// NOLINTNEXTLINE(google-runtime-int)
std::is_same_v<unsigned long, T> || // NOLINT(runtime/int)
// NOLINTNEXTLINE(google-runtime-int)
std::is_same_v<unsigned long long, T>); // NOLINT(runtime/int)
if constexpr (std::is_same_v<unsigned, T>) {
#ifndef UNODB_DETAIL_MSVC
return gsl::narrow_cast<std::uint8_t>(__builtin_ctz(x));
#else
unsigned long result; // NOLINT(runtime/int)
_BitScanForward(&result, x);
return gsl::narrow_cast<std::uint8_t>(result);
#endif
}
// NOLINTNEXTLINE(google-runtime-int)
if constexpr (std::is_same_v<unsigned long, T>) { // NOLINT(runtime/int)
#ifndef UNODB_DETAIL_MSVC
return gsl::narrow_cast<std::uint8_t>(__builtin_ctzl(x));
#else
unsigned long result; // NOLINT(runtime/int)
_BitScanForward(&result, x);
return gsl::narrow_cast<std::uint8_t>(result);
#endif
}
// NOLINTNEXTLINE(google-runtime-int)
if constexpr (std::is_same_v<unsigned long long, T>) { // NOLINT(runtime/int)
#ifndef UNODB_DETAIL_MSVC
return gsl::narrow_cast<std::uint8_t>(__builtin_ctzll(x));
#else
unsigned long result; // NOLINT(runtime/int)
_BitScanForward64(&result, x);
return gsl::narrow_cast<std::uint8_t>(result);
#endif
} // cppcheck-suppress missingReturn
}
[[nodiscard, gnu::pure]] UNODB_DETAIL_CONSTEXPR_NOT_MSVC unsigned popcount(
unsigned x) noexcept {
#ifndef UNODB_DETAIL_MSVC
return static_cast<unsigned>(__builtin_popcount(x));
#else
return static_cast<unsigned>(__popcnt(x));
#endif
}
} // namespace unodb::detail
#endif