Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <bit>
7 :
8 : #if defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L
9 : // std::bit_floor and std::has_single_bit are defined in <bit>
10 : #else
11 : // std::bit_floor and std::has_single_bit are not defined in <bit> and
12 : // therefore we provide the definitions
13 : #include <cstdint>
14 : #include <limits>
15 :
16 : #include "Utilities/Requires.hpp"
17 :
18 : // NOLINTNEXTLINE(cert-dcl58-cpp)
19 : namespace std {
20 : template <typename T,
21 : Requires<std::is_same_v<T, uint8_t> or std::is_same_v<T, uint16_t> or
22 : std::is_same_v<T, uint32_t> or std::is_same_v<T, uint64_t> or
23 : std::is_same_v<T, size_t> > = nullptr>
24 : // NOLINTNEXTLINE(cert-dcl58-cpp)
25 : constexpr T bit_floor(T x) noexcept {
26 : if (x != 0) {
27 : return T(1) << (std::numeric_limits<T>::digits - std::countl_zero(x) - 1);
28 : }
29 : return 0;
30 : }
31 :
32 : template <typename T,
33 : Requires<std::is_same_v<T, uint8_t> or std::is_same_v<T, uint16_t> or
34 : std::is_same_v<T, uint32_t> or std::is_same_v<T, uint64_t> or
35 : std::is_same_v<T, size_t> > = nullptr>
36 : // NOLINTNEXTLINE(cert-dcl58-cpp)
37 : constexpr bool has_single_bit(T x) noexcept {
38 : return std::popcount(x) == 1;
39 : }
40 : } // namespace std
41 : #endif
|