diff options
| author | 2020-11-27 14:13:18 -0800 | |
|---|---|---|
| committer | 2020-12-06 00:03:24 -0800 | |
| commit | 8dbfa4e1a4af2cda4500304ba8fe1a1b09bbb814 (patch) | |
| tree | 98331155b0fbe7c5fcdabde69d4b0419b84cda65 /src | |
| parent | hle: kernel: Port KAffinityMask from Mesosphere. (diff) | |
| download | yuzu-8dbfa4e1a4af2cda4500304ba8fe1a1b09bbb814.tar.gz yuzu-8dbfa4e1a4af2cda4500304ba8fe1a1b09bbb814.tar.xz yuzu-8dbfa4e1a4af2cda4500304ba8fe1a1b09bbb814.zip | |
common: Port BitSet from Mesosphere.
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/common/bit_set.h | 100 |
2 files changed, 101 insertions, 0 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 56c7e21f5..fc2ed9999 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -104,6 +104,7 @@ add_library(common STATIC | |||
| 104 | detached_tasks.h | 104 | detached_tasks.h |
| 105 | bit_cast.h | 105 | bit_cast.h |
| 106 | bit_field.h | 106 | bit_field.h |
| 107 | bit_set.h | ||
| 107 | bit_util.h | 108 | bit_util.h |
| 108 | cityhash.cpp | 109 | cityhash.cpp |
| 109 | cityhash.h | 110 | cityhash.h |
diff --git a/src/common/bit_set.h b/src/common/bit_set.h new file mode 100644 index 000000000..4f966de40 --- /dev/null +++ b/src/common/bit_set.h | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2020 Atmosphère-NX | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #pragma once | ||
| 18 | |||
| 19 | #include "common/alignment.h" | ||
| 20 | #include "common/bit_util.h" | ||
| 21 | #include "common/common_types.h" | ||
| 22 | |||
| 23 | namespace Common { | ||
| 24 | |||
| 25 | namespace impl { | ||
| 26 | |||
| 27 | #define BITSIZEOF(x) (sizeof(x) * CHAR_BIT) | ||
| 28 | |||
| 29 | template <typename Storage, size_t N> | ||
| 30 | class BitSet { | ||
| 31 | private: | ||
| 32 | static_assert(std::is_integral<Storage>::value); | ||
| 33 | static_assert(std::is_unsigned<Storage>::value); | ||
| 34 | static_assert(sizeof(Storage) <= sizeof(u64)); | ||
| 35 | |||
| 36 | static constexpr size_t FlagsPerWord = BITSIZEOF(Storage); | ||
| 37 | static constexpr size_t NumWords = AlignUp(N, FlagsPerWord) / FlagsPerWord; | ||
| 38 | |||
| 39 | static constexpr auto CountLeadingZeroImpl(Storage word) { | ||
| 40 | return CountLeadingZeroes64(static_cast<unsigned long long>(word)) - | ||
| 41 | (BITSIZEOF(unsigned long long) - FlagsPerWord); | ||
| 42 | } | ||
| 43 | |||
| 44 | static constexpr Storage GetBitMask(size_t bit) { | ||
| 45 | return Storage(1) << (FlagsPerWord - 1 - bit); | ||
| 46 | } | ||
| 47 | |||
| 48 | private: | ||
| 49 | Storage words[NumWords]; | ||
| 50 | |||
| 51 | public: | ||
| 52 | constexpr BitSet() : words() { /* ... */ | ||
| 53 | } | ||
| 54 | |||
| 55 | constexpr void SetBit(size_t i) { | ||
| 56 | this->words[i / FlagsPerWord] |= GetBitMask(i % FlagsPerWord); | ||
| 57 | } | ||
| 58 | |||
| 59 | constexpr void ClearBit(size_t i) { | ||
| 60 | this->words[i / FlagsPerWord] &= ~GetBitMask(i % FlagsPerWord); | ||
| 61 | } | ||
| 62 | |||
| 63 | constexpr size_t CountLeadingZero() const { | ||
| 64 | for (size_t i = 0; i < NumWords; i++) { | ||
| 65 | if (this->words[i]) { | ||
| 66 | return FlagsPerWord * i + CountLeadingZeroImpl(this->words[i]); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | return FlagsPerWord * NumWords; | ||
| 70 | } | ||
| 71 | |||
| 72 | constexpr size_t GetNextSet(size_t n) const { | ||
| 73 | for (size_t i = (n + 1) / FlagsPerWord; i < NumWords; i++) { | ||
| 74 | Storage word = this->words[i]; | ||
| 75 | if (!IsAligned(n + 1, FlagsPerWord)) { | ||
| 76 | word &= GetBitMask(n % FlagsPerWord) - 1; | ||
| 77 | } | ||
| 78 | if (word) { | ||
| 79 | return FlagsPerWord * i + CountLeadingZeroImpl(word); | ||
| 80 | } | ||
| 81 | } | ||
| 82 | return FlagsPerWord * NumWords; | ||
| 83 | } | ||
| 84 | }; | ||
| 85 | |||
| 86 | } // namespace impl | ||
| 87 | |||
| 88 | template <size_t N> | ||
| 89 | using BitSet8 = impl::BitSet<u8, N>; | ||
| 90 | |||
| 91 | template <size_t N> | ||
| 92 | using BitSet16 = impl::BitSet<u16, N>; | ||
| 93 | |||
| 94 | template <size_t N> | ||
| 95 | using BitSet32 = impl::BitSet<u32, N>; | ||
| 96 | |||
| 97 | template <size_t N> | ||
| 98 | using BitSet64 = impl::BitSet<u64, N>; | ||
| 99 | |||
| 100 | } // namespace Common | ||