Loading include/ftl/fake_guard.h +1 −2 Original line number Diff line number Diff line Loading @@ -85,6 +85,5 @@ struct [[clang::scoped_lockable]] FakeGuard final { #define FTL_MAKE_FAKE_GUARD(arg1, arg2, guard, ...) guard // The void argument suppresses a warning about zero variadic macro arguments. #define FTL_FAKE_GUARD(...) \ FTL_MAKE_FAKE_GUARD(__VA_ARGS__, FTL_FAKE_GUARD2, FTL_FAKE_GUARD1, void)(__VA_ARGS__) FTL_MAKE_FAKE_GUARD(__VA_ARGS__, FTL_FAKE_GUARD2, FTL_FAKE_GUARD1, )(__VA_ARGS__) include/ftl/small_map.h +18 −4 Original line number Diff line number Diff line Loading @@ -107,12 +107,20 @@ class SmallMap final { template <typename Q, typename W, std::size_t M, typename E> SmallMap(SmallMap<Q, W, M, E> other) : map_(std::move(other.map_)) {} static constexpr size_type static_capacity() { return N; } size_type max_size() const { return map_.max_size(); } size_type size() const { return map_.size(); } bool empty() const { return map_.empty(); } // Returns whether the map is backed by static or dynamic storage. bool dynamic() const { return map_.dynamic(); } bool dynamic() const { if constexpr (static_capacity() > 0) { return map_.dynamic(); } else { return true; } } iterator begin() { return map_.begin(); } const_iterator begin() const { return cbegin(); } Loading Loading @@ -171,9 +179,15 @@ class SmallMap final { return {it, false}; } auto& ref = map_.emplace_back(std::piecewise_construct, std::forward_as_tuple(key), decltype(auto) ref_or_it = map_.emplace_back(std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(std::forward<Args>(args)...)); return {&ref, true}; if constexpr (static_capacity() > 0) { return {&ref_or_it, true}; } else { return {ref_or_it, true}; } } // Replaces a mapping if it exists, and returns an iterator to it. Returns the end() iterator Loading include/ftl/small_vector.h +9 −10 Original line number Diff line number Diff line Loading @@ -124,30 +124,29 @@ class SmallVector final : details::ArrayTraits<T>, details::ArrayComparators<Sma DISPATCH(size_type, size, const) DISPATCH(bool, empty, const) // noexcept to suppress warning about zero variadic macro arguments. DISPATCH(iterator, begin, noexcept) DISPATCH(iterator, begin, ) DISPATCH(const_iterator, begin, const) DISPATCH(const_iterator, cbegin, const) DISPATCH(iterator, end, noexcept) DISPATCH(iterator, end, ) DISPATCH(const_iterator, end, const) DISPATCH(const_iterator, cend, const) DISPATCH(reverse_iterator, rbegin, noexcept) DISPATCH(reverse_iterator, rbegin, ) DISPATCH(const_reverse_iterator, rbegin, const) DISPATCH(const_reverse_iterator, crbegin, const) DISPATCH(reverse_iterator, rend, noexcept) DISPATCH(reverse_iterator, rend, ) DISPATCH(const_reverse_iterator, rend, const) DISPATCH(const_reverse_iterator, crend, const) DISPATCH(iterator, last, noexcept) DISPATCH(iterator, last, ) DISPATCH(const_iterator, last, const) DISPATCH(reference, front, noexcept) DISPATCH(reference, front, ) DISPATCH(const_reference, front, const) DISPATCH(reference, back, noexcept) DISPATCH(reference, back, ) DISPATCH(const_reference, back, const) reference operator[](size_type i) { Loading Loading @@ -211,13 +210,13 @@ class SmallVector final : details::ArrayTraits<T>, details::ArrayComparators<Sma // // The last() and end() iterators are invalidated. // DISPATCH(void, pop_back, noexcept) DISPATCH(void, pop_back, ) // Removes all elements. // // All iterators are invalidated. // DISPATCH(void, clear, noexcept) DISPATCH(void, clear, ) #undef DISPATCH Loading libs/ftl/small_map_test.cpp +42 −13 Original line number Diff line number Diff line Loading @@ -189,9 +189,20 @@ TEST(SmallMap, Get) { } } TEST(SmallMap, TryEmplace) { SmallMap<int, std::string, 3> map; using Pair = decltype(map)::value_type; template <typename Capacity> struct SmallMapTest : testing::Test { static constexpr std::size_t kCapacity = Capacity{}(); }; template <std::size_t N> using Capacity = std::integral_constant<std::size_t, N>; using Capacities = testing::Types<Capacity<3>, Capacity<0>>; TYPED_TEST_SUITE(SmallMapTest, Capacities, ); TYPED_TEST(SmallMapTest, TryEmplace) { SmallMap<int, std::string, TestFixture::kCapacity> map; using Pair = typename decltype(map)::value_type; { const auto [it, ok] = map.try_emplace(123, "abc"); Loading @@ -207,14 +218,22 @@ TEST(SmallMap, TryEmplace) { const auto [it, ok] = map.try_emplace(-1); ASSERT_TRUE(ok); EXPECT_EQ(*it, Pair(-1, std::string())); if constexpr (map.static_capacity() > 0) { EXPECT_FALSE(map.dynamic()); } else { EXPECT_TRUE(map.dynamic()); } } { // Insertion fails if mapping exists. const auto [it, ok] = map.try_emplace(42, "!!!"); EXPECT_FALSE(ok); EXPECT_EQ(*it, Pair(42, "???")); if constexpr (map.static_capacity() > 0) { EXPECT_FALSE(map.dynamic()); } else { EXPECT_TRUE(map.dynamic()); } } { // Insertion at capacity promotes the map. Loading @@ -240,9 +259,9 @@ struct String { } // namespace TEST(SmallMap, TryReplace) { SmallMap<int, String, 3> map = ftl::init::map(1, "a")(2, "B"); using Pair = decltype(map)::value_type; TYPED_TEST(SmallMapTest, TryReplace) { SmallMap<int, String, TestFixture::kCapacity> map = ftl::init::map(1, "a")(2, "B"); using Pair = typename decltype(map)::value_type; { // Replacing fails unless mapping exists. Loading @@ -260,7 +279,12 @@ TEST(SmallMap, TryReplace) { EXPECT_EQ(*it, Pair(2, "b")); } if constexpr (map.static_capacity() > 0) { EXPECT_FALSE(map.dynamic()); } else { EXPECT_TRUE(map.dynamic()); } EXPECT_TRUE(map.try_emplace(3, "abc").second); EXPECT_TRUE(map.try_emplace(4, "d").second); EXPECT_TRUE(map.dynamic()); Loading @@ -284,9 +308,9 @@ TEST(SmallMap, TryReplace) { EXPECT_EQ(map, SmallMap(ftl::init::map(4, "d"s)(3, "c"s)(2, "b"s)(1, "a"s))); } TEST(SmallMap, EmplaceOrReplace) { SmallMap<int, String, 3> map = ftl::init::map(1, "a")(2, "B"); using Pair = decltype(map)::value_type; TYPED_TEST(SmallMapTest, EmplaceOrReplace) { SmallMap<int, String, TestFixture::kCapacity> map = ftl::init::map(1, "a")(2, "B"); using Pair = typename decltype(map)::value_type; { // New mapping is emplaced. Loading @@ -305,7 +329,12 @@ TEST(SmallMap, EmplaceOrReplace) { EXPECT_EQ(*it, Pair(2, "b")); } if constexpr (map.static_capacity() > 0) { EXPECT_FALSE(map.dynamic()); } else { EXPECT_TRUE(map.dynamic()); } EXPECT_FALSE(map.emplace_or_replace(3, "abc").second); // Replace. EXPECT_TRUE(map.emplace_or_replace(4, "d").second); // Emplace. EXPECT_TRUE(map.dynamic()); Loading Loading
include/ftl/fake_guard.h +1 −2 Original line number Diff line number Diff line Loading @@ -85,6 +85,5 @@ struct [[clang::scoped_lockable]] FakeGuard final { #define FTL_MAKE_FAKE_GUARD(arg1, arg2, guard, ...) guard // The void argument suppresses a warning about zero variadic macro arguments. #define FTL_FAKE_GUARD(...) \ FTL_MAKE_FAKE_GUARD(__VA_ARGS__, FTL_FAKE_GUARD2, FTL_FAKE_GUARD1, void)(__VA_ARGS__) FTL_MAKE_FAKE_GUARD(__VA_ARGS__, FTL_FAKE_GUARD2, FTL_FAKE_GUARD1, )(__VA_ARGS__)
include/ftl/small_map.h +18 −4 Original line number Diff line number Diff line Loading @@ -107,12 +107,20 @@ class SmallMap final { template <typename Q, typename W, std::size_t M, typename E> SmallMap(SmallMap<Q, W, M, E> other) : map_(std::move(other.map_)) {} static constexpr size_type static_capacity() { return N; } size_type max_size() const { return map_.max_size(); } size_type size() const { return map_.size(); } bool empty() const { return map_.empty(); } // Returns whether the map is backed by static or dynamic storage. bool dynamic() const { return map_.dynamic(); } bool dynamic() const { if constexpr (static_capacity() > 0) { return map_.dynamic(); } else { return true; } } iterator begin() { return map_.begin(); } const_iterator begin() const { return cbegin(); } Loading Loading @@ -171,9 +179,15 @@ class SmallMap final { return {it, false}; } auto& ref = map_.emplace_back(std::piecewise_construct, std::forward_as_tuple(key), decltype(auto) ref_or_it = map_.emplace_back(std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(std::forward<Args>(args)...)); return {&ref, true}; if constexpr (static_capacity() > 0) { return {&ref_or_it, true}; } else { return {ref_or_it, true}; } } // Replaces a mapping if it exists, and returns an iterator to it. Returns the end() iterator Loading
include/ftl/small_vector.h +9 −10 Original line number Diff line number Diff line Loading @@ -124,30 +124,29 @@ class SmallVector final : details::ArrayTraits<T>, details::ArrayComparators<Sma DISPATCH(size_type, size, const) DISPATCH(bool, empty, const) // noexcept to suppress warning about zero variadic macro arguments. DISPATCH(iterator, begin, noexcept) DISPATCH(iterator, begin, ) DISPATCH(const_iterator, begin, const) DISPATCH(const_iterator, cbegin, const) DISPATCH(iterator, end, noexcept) DISPATCH(iterator, end, ) DISPATCH(const_iterator, end, const) DISPATCH(const_iterator, cend, const) DISPATCH(reverse_iterator, rbegin, noexcept) DISPATCH(reverse_iterator, rbegin, ) DISPATCH(const_reverse_iterator, rbegin, const) DISPATCH(const_reverse_iterator, crbegin, const) DISPATCH(reverse_iterator, rend, noexcept) DISPATCH(reverse_iterator, rend, ) DISPATCH(const_reverse_iterator, rend, const) DISPATCH(const_reverse_iterator, crend, const) DISPATCH(iterator, last, noexcept) DISPATCH(iterator, last, ) DISPATCH(const_iterator, last, const) DISPATCH(reference, front, noexcept) DISPATCH(reference, front, ) DISPATCH(const_reference, front, const) DISPATCH(reference, back, noexcept) DISPATCH(reference, back, ) DISPATCH(const_reference, back, const) reference operator[](size_type i) { Loading Loading @@ -211,13 +210,13 @@ class SmallVector final : details::ArrayTraits<T>, details::ArrayComparators<Sma // // The last() and end() iterators are invalidated. // DISPATCH(void, pop_back, noexcept) DISPATCH(void, pop_back, ) // Removes all elements. // // All iterators are invalidated. // DISPATCH(void, clear, noexcept) DISPATCH(void, clear, ) #undef DISPATCH Loading
libs/ftl/small_map_test.cpp +42 −13 Original line number Diff line number Diff line Loading @@ -189,9 +189,20 @@ TEST(SmallMap, Get) { } } TEST(SmallMap, TryEmplace) { SmallMap<int, std::string, 3> map; using Pair = decltype(map)::value_type; template <typename Capacity> struct SmallMapTest : testing::Test { static constexpr std::size_t kCapacity = Capacity{}(); }; template <std::size_t N> using Capacity = std::integral_constant<std::size_t, N>; using Capacities = testing::Types<Capacity<3>, Capacity<0>>; TYPED_TEST_SUITE(SmallMapTest, Capacities, ); TYPED_TEST(SmallMapTest, TryEmplace) { SmallMap<int, std::string, TestFixture::kCapacity> map; using Pair = typename decltype(map)::value_type; { const auto [it, ok] = map.try_emplace(123, "abc"); Loading @@ -207,14 +218,22 @@ TEST(SmallMap, TryEmplace) { const auto [it, ok] = map.try_emplace(-1); ASSERT_TRUE(ok); EXPECT_EQ(*it, Pair(-1, std::string())); if constexpr (map.static_capacity() > 0) { EXPECT_FALSE(map.dynamic()); } else { EXPECT_TRUE(map.dynamic()); } } { // Insertion fails if mapping exists. const auto [it, ok] = map.try_emplace(42, "!!!"); EXPECT_FALSE(ok); EXPECT_EQ(*it, Pair(42, "???")); if constexpr (map.static_capacity() > 0) { EXPECT_FALSE(map.dynamic()); } else { EXPECT_TRUE(map.dynamic()); } } { // Insertion at capacity promotes the map. Loading @@ -240,9 +259,9 @@ struct String { } // namespace TEST(SmallMap, TryReplace) { SmallMap<int, String, 3> map = ftl::init::map(1, "a")(2, "B"); using Pair = decltype(map)::value_type; TYPED_TEST(SmallMapTest, TryReplace) { SmallMap<int, String, TestFixture::kCapacity> map = ftl::init::map(1, "a")(2, "B"); using Pair = typename decltype(map)::value_type; { // Replacing fails unless mapping exists. Loading @@ -260,7 +279,12 @@ TEST(SmallMap, TryReplace) { EXPECT_EQ(*it, Pair(2, "b")); } if constexpr (map.static_capacity() > 0) { EXPECT_FALSE(map.dynamic()); } else { EXPECT_TRUE(map.dynamic()); } EXPECT_TRUE(map.try_emplace(3, "abc").second); EXPECT_TRUE(map.try_emplace(4, "d").second); EXPECT_TRUE(map.dynamic()); Loading @@ -284,9 +308,9 @@ TEST(SmallMap, TryReplace) { EXPECT_EQ(map, SmallMap(ftl::init::map(4, "d"s)(3, "c"s)(2, "b"s)(1, "a"s))); } TEST(SmallMap, EmplaceOrReplace) { SmallMap<int, String, 3> map = ftl::init::map(1, "a")(2, "B"); using Pair = decltype(map)::value_type; TYPED_TEST(SmallMapTest, EmplaceOrReplace) { SmallMap<int, String, TestFixture::kCapacity> map = ftl::init::map(1, "a")(2, "B"); using Pair = typename decltype(map)::value_type; { // New mapping is emplaced. Loading @@ -305,7 +329,12 @@ TEST(SmallMap, EmplaceOrReplace) { EXPECT_EQ(*it, Pair(2, "b")); } if constexpr (map.static_capacity() > 0) { EXPECT_FALSE(map.dynamic()); } else { EXPECT_TRUE(map.dynamic()); } EXPECT_FALSE(map.emplace_or_replace(3, "abc").second); // Replace. EXPECT_TRUE(map.emplace_or_replace(4, "d").second); // Emplace. EXPECT_TRUE(map.dynamic()); Loading