diff options
author | 2022-02-16 10:44:28 -0800 | |
---|---|---|
committer | 2022-03-23 15:44:03 -0700 | |
commit | a7fe7eb75957872935b934633ca3e614ed0944c5 (patch) | |
tree | 5a7fddd078b910b646ec0f66f4840edd5c2492b6 | |
parent | af5fa6bf7519e780e017cd1af87ed0a4b3dcb5b8 (diff) |
FTL: Remove libutils dependency of Flags
Also, fix the __builtin type suffix in flag_string to avoid truncation
of upper bits for 64-bit flags on platforms with 32-bit unsigned long.
Bug: 185536303
Test: ftl_test
Change-Id: I1719255cc4dd60ec3203e111c37d6851471c631d
-rw-r--r-- | include/ftl/Flags.h | 26 | ||||
-rw-r--r-- | include/ftl/enum.h | 4 | ||||
-rw-r--r-- | libs/ftl/Android.bp | 8 | ||||
-rw-r--r-- | libs/ftl/enum_test.cpp | 10 |
4 files changed, 25 insertions, 23 deletions
diff --git a/include/ftl/Flags.h b/include/ftl/Flags.h index 708eaf5dde..db3d9ea5b9 100644 --- a/include/ftl/Flags.h +++ b/include/ftl/Flags.h @@ -19,13 +19,12 @@ #include <ftl/enum.h> #include <ftl/string.h> +#include <bitset> #include <cstdint> #include <iterator> #include <string> #include <type_traits> -#include "utils/BitSet.h" - // TODO(b/185536303): Align with FTL style and namespace. namespace android { @@ -56,21 +55,22 @@ public: : mFlags(t) {} class Iterator { - // The type can't be larger than 64-bits otherwise it won't fit in BitSet64. - static_assert(sizeof(U) <= sizeof(uint64_t)); + using Bits = std::uint64_t; + static_assert(sizeof(U) <= sizeof(Bits)); public: + constexpr Iterator() = default; Iterator(Flags<F> flags) : mRemainingFlags(flags.mFlags) { (*this)++; } - Iterator() : mRemainingFlags(0), mCurrFlag(static_cast<F>(0)) {} // Pre-fix ++ Iterator& operator++() { - if (mRemainingFlags.isEmpty()) { - mCurrFlag = static_cast<F>(0); + if (mRemainingFlags.none()) { + mCurrFlag = 0; } else { - uint64_t bit = mRemainingFlags.clearLastMarkedBit(); // counts from left - const U flag = 1 << (64 - bit - 1); - mCurrFlag = static_cast<F>(flag); + // TODO: Replace with std::countr_zero in C++20. + const Bits bit = static_cast<Bits>(__builtin_ctzll(mRemainingFlags.to_ullong())); + mRemainingFlags.reset(static_cast<std::size_t>(bit)); + mCurrFlag = static_cast<U>(static_cast<Bits>(1) << bit); } return *this; } @@ -88,7 +88,7 @@ public: bool operator!=(Iterator other) const { return !(*this == other); } - F operator*() { return mCurrFlag; } + F operator*() const { return F{mCurrFlag}; } // iterator traits @@ -107,8 +107,8 @@ public: using pointer = void; private: - BitSet64 mRemainingFlags; - F mCurrFlag; + std::bitset<sizeof(Bits) * 8> mRemainingFlags; + U mCurrFlag = 0; }; /* diff --git a/include/ftl/enum.h b/include/ftl/enum.h index 5234c051b1..82af1d6cf8 100644 --- a/include/ftl/enum.h +++ b/include/ftl/enum.h @@ -261,10 +261,10 @@ constexpr std::optional<std::string_view> flag_name(E v) { const auto value = to_underlying(v); // TODO: Replace with std::popcount and std::countr_zero in C++20. - if (__builtin_popcountl(value) != 1) return {}; + if (__builtin_popcountll(value) != 1) return {}; constexpr auto kRange = details::EnumRange<E, details::FlagName>{}; - return kRange.values[__builtin_ctzl(value)]; + return kRange.values[__builtin_ctzll(value)]; } // Returns a stringified enumerator, or its integral value if not named. diff --git a/libs/ftl/Android.bp b/libs/ftl/Android.bp index bc2eb23677..7175f0705b 100644 --- a/libs/ftl/Android.bp +++ b/libs/ftl/Android.bp @@ -30,12 +30,4 @@ cc_test { "-Wextra", "-Wpedantic", ], - - header_libs: [ - "libbase_headers", - ], - - shared_libs: [ - "libbase", - ], } diff --git a/libs/ftl/enum_test.cpp b/libs/ftl/enum_test.cpp index d8ce7a5e7b..5592a01fde 100644 --- a/libs/ftl/enum_test.cpp +++ b/libs/ftl/enum_test.cpp @@ -143,6 +143,16 @@ TEST(Enum, String) { EXPECT_EQ(ftl::flag_string(Flags::kNone), "0b0"); EXPECT_EQ(ftl::flag_string(Flags::kMask), "0b10010010"); EXPECT_EQ(ftl::flag_string(Flags::kAll), "0b11111111"); + + enum class Flags64 : std::uint64_t { + kFlag0 = 0b1ull, + kFlag63 = 0x8000'0000'0000'0000ull, + kMask = kFlag0 | kFlag63 + }; + + EXPECT_EQ(ftl::flag_string(Flags64::kFlag0), "kFlag0"); + EXPECT_EQ(ftl::flag_string(Flags64::kFlag63), "kFlag63"); + EXPECT_EQ(ftl::flag_string(Flags64::kMask), "0x8000000000000001"); } { EXPECT_EQ(ftl::enum_string(Planet::kEarth), "kEarth"); |