1 // Tencent is pleased to support the open source community by making RapidJSON available. 2 // 3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. 4 // 5 // Licensed under the MIT License (the "License"); you may not use this file except 6 // in compliance with the License. You may obtain a copy of the License at 7 // 8 // http://opensource.org/licenses/MIT 9 // 10 // Unless required by applicable law or agreed to in writing, software distributed 11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 // specific language governing permissions and limitations under the License. 14 15 #ifndef RAPIDJSON_CLZLL_H_ 16 #define RAPIDJSON_CLZLL_H_ 17 18 #include "../rapidjson.h" 19 20 #if defined(_MSC_VER) && !defined(UNDER_CE) 21 #include <intrin.h> 22 #if defined(_WIN64) 23 #pragma intrinsic(_BitScanReverse64) 24 #else 25 #pragma intrinsic(_BitScanReverse) 26 #endif 27 #endif 28 29 RAPIDJSON_NAMESPACE_BEGIN 30 namespace internal { 31 clzll(uint64_t x)32inline uint32_t clzll(uint64_t x) { 33 // Passing 0 to __builtin_clzll is UB in GCC and results in an 34 // infinite loop in the software implementation. 35 RAPIDJSON_ASSERT(x != 0); 36 37 #if defined(_MSC_VER) && !defined(UNDER_CE) 38 unsigned long r = 0; 39 #if defined(_WIN64) 40 _BitScanReverse64(&r, x); 41 #else 42 // Scan the high 32 bits. 43 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32))) 44 return 63 - (r + 32); 45 46 // Scan the low 32 bits. 47 _BitScanReverse(&r, static_cast<uint32_t>(x & 0xFFFFFFFF)); 48 #endif // _WIN64 49 50 return 63 - r; 51 #elif (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll) 52 // __builtin_clzll wrapper 53 return static_cast<uint32_t>(__builtin_clzll(x)); 54 #else 55 // naive version 56 uint32_t r = 0; 57 while (!(x & (static_cast<uint64_t>(1) << 63))) { 58 x <<= 1; 59 ++r; 60 } 61 62 return r; 63 #endif // _MSC_VER 64 } 65 66 #define RAPIDJSON_CLZLL RAPIDJSON_NAMESPACE::internal::clzll 67 68 } // namespace internal 69 RAPIDJSON_NAMESPACE_END 70 71 #endif // RAPIDJSON_CLZLL_H_ 72