24
24
#include < stdlib.h>
25
25
#endif
26
26
27
+ #if defined(_MSC_VER) && (defined(__cplusplus) && (__cplusplus >= 202002L)) || \
28
+ (defined(_MSVC_LANG) && (_MSVC_LANG >= 202002L ))
29
+ #include < limits.h>
30
+ #include < type_traits>
31
+ #define LIBDIVIDE_VC_CXX20
32
+ #endif
33
+
27
34
#if defined(LIBDIVIDE_SSE2)
28
35
#include < emmintrin.h>
29
36
#endif
126
133
#endif
127
134
128
135
#ifdef __cplusplus
136
+
137
+ // For constexpr zero initialization, c++11 might handle things ok,
138
+ // but just limit to at least c++14 to ensure we don't break anyone's code:
139
+
140
+ // for gcc and clang, use https://en.cppreference.com/w/cpp/feature_test#cpp_constexpr
141
+ #if (defined(__GNUC__) || defined(__clang__)) && (__cpp_constexpr >= 201304L)
142
+ #define LIBDIVIDE_CONSTEXPR constexpr LIBDIVIDE_INLINE
143
+
144
+ // Supposedly, MSVC might not implement feature test macros right (https://stackoverflow.com/questions/49316752/feature-test-macros-not-working-properly-in-visual-c)
145
+ // so check that _MSVC_LANG corresponds to at least c++14, and _MSC_VER corresponds to at least VS 2017 15.0 (for extended constexpr support https://learn.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=msvc-170)
146
+ #elif defined(_MSC_VER) && _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >=201402L
147
+ #define LIBDIVIDE_CONSTEXPR constexpr LIBDIVIDE_INLINE
148
+
149
+ // in case some other obscure compiler has the right __cpp_constexpr :
150
+ #elif defined(__cpp_constexpr) && __cpp_constexpr >= 201304L
151
+ #define LIBDIVIDE_CONSTEXPR constexpr LIBDIVIDE_INLINE
152
+
153
+ #else
154
+ #define LIBDIVIDE_CONSTEXPR LIBDIVIDE_INLINE
155
+ #endif
156
+
129
157
namespace libdivide {
130
158
#endif
131
159
132
160
#if defined(_MSC_VER) && !defined(__clang__)
161
+ #if defined(LIBDIVIDE_VC_CXX20)
162
+ static LIBDIVIDE_CONSTEXPR int __builtin_clz (unsigned x) {
163
+ if (std::is_constant_evaluated ()) {
164
+ for (int i = 0 ; i < sizeof (x) * CHAR_BIT; ++i) {
165
+ if (x >> (sizeof (x) * CHAR_BIT - 1 - i)) return i;
166
+ }
167
+ return sizeof (x) * CHAR_BIT;
168
+ }
169
+ #else
133
170
static LIBDIVIDE_INLINE int __builtin_clz (unsigned x) {
171
+ #endif
134
172
#if defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC)
135
173
return (int )_CountLeadingZeros (x);
136
174
#elif defined(__AVX2__) || defined(__LZCNT__)
@@ -142,7 +180,17 @@ static LIBDIVIDE_INLINE int __builtin_clz(unsigned x) {
142
180
#endif
143
181
}
144
182
183
+ #if defined(LIBDIVIDE_VC_CXX20)
184
+ static LIBDIVIDE_CONSTEXPR int __builtin_clzll (unsigned long long x) {
185
+ if (std::is_constant_evaluated ()) {
186
+ for (int i = 0 ; i < sizeof (x) * CHAR_BIT; ++i) {
187
+ if (x >> (sizeof (x) * CHAR_BIT - 1 - i)) return i;
188
+ }
189
+ return sizeof (x) * CHAR_BIT;
190
+ }
191
+ #else
145
192
static LIBDIVIDE_INLINE int __builtin_clzll (unsigned long long x) {
193
+ #endif
146
194
#if defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC)
147
195
return (int )_CountLeadingZeros64 (x);
148
196
#elif defined(_WIN64)
@@ -3018,28 +3066,6 @@ __m128i libdivide_s64_branchfree_do_vec128(
3018
3066
3019
3067
#ifdef __cplusplus
3020
3068
3021
- // for constexpr zero initialization,
3022
- // c++11 might handle things ok,
3023
- // but just limit to at least c++14 to ensure
3024
- // we don't break anyone's code:
3025
-
3026
- // for gcc and clang, use https://en.cppreference.com/w/cpp/feature_test#cpp_constexpr
3027
- #if (defined(__GNUC__) || defined(__clang__)) && (__cpp_constexpr >= 201304L)
3028
- #define LIBDIVIDE_CONSTEXPR constexpr
3029
-
3030
- // supposedly, MSVC might not implement feature test macros right (https://stackoverflow.com/questions/49316752/feature-test-macros-not-working-properly-in-visual-c)
3031
- // so check that _MSVC_LANG corresponds to at least c++14, and _MSC_VER corresponds to at least VS 2017 15.0 (for extended constexpr support https://learn.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=msvc-170)
3032
- #elif defined(_MSC_VER) && _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >=201402L
3033
- #define LIBDIVIDE_CONSTEXPR constexpr
3034
-
3035
- // in case some other obscure compiler has the right __cpp_constexpr :
3036
- #elif defined(__cpp_constexpr) && __cpp_constexpr >= 201304L
3037
- #define LIBDIVIDE_CONSTEXPR constexpr
3038
-
3039
- #else
3040
- #define LIBDIVIDE_CONSTEXPR LIBDIVIDE_INLINE
3041
- #endif
3042
-
3043
3069
enum Branching {
3044
3070
BRANCHFULL, // use branching algorithms
3045
3071
BRANCHFREE // use branchfree algorithms
0 commit comments