Skip to content

Commit d487265

Browse files
committed
[LLVM] Add helper class for working with caches
1 parent 315c904 commit d487265

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

llvm/include/llvm/ADT/STLExtras.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2610,6 +2610,30 @@ template <typename T> using has_sizeof = decltype(sizeof(T));
26102610
template <typename T>
26112611
constexpr bool is_incomplete_v = !is_detected<detail::has_sizeof, T>::value;
26122612

2613+
/// A utility for working with maps that allows concisely expressing "perform
2614+
/// and cache this expensive computation only if it isn't already cached".
2615+
/// Use it like so:
2616+
///
2617+
/// ```cpp
2618+
/// std::unordered_map<K, V> Cache;
2619+
/// auto& Value = Cache.try_emplace(
2620+
/// Key, llvm::defer {[] { /* heavy work */ }}).first->second;
2621+
/// ```
2622+
template <typename FnT> class defer {
2623+
public:
2624+
constexpr defer(FnT &&F LLVM_LIFETIME_BOUND) : Fn(std::forward<FnT>(F)) {}
2625+
2626+
template <typename T> constexpr operator T() {
2627+
return std::forward<FnT>(Fn)();
2628+
}
2629+
2630+
private:
2631+
FnT &&Fn;
2632+
};
2633+
2634+
// Silence -Wctad-maybe-unsupported.
2635+
template <typename FnT> defer(FnT &&) -> defer<FnT>;
2636+
26132637
} // end namespace llvm
26142638

26152639
namespace std {

llvm/unittests/ADT/STLExtrasTest.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,4 +1699,13 @@ struct Bar {};
16991699
static_assert(is_incomplete_v<Foo>, "Foo is incomplete");
17001700
static_assert(!is_incomplete_v<Bar>, "Bar is defined");
17011701

1702+
TEST(STLExtrasTest, Defer) {
1703+
std::unordered_map<int, int> Cache;
1704+
const auto [It, Inserted]{Cache.try_emplace(1, defer{[] { return 10; }})};
1705+
ASSERT_TRUE(Inserted);
1706+
ASSERT_EQ(It->second, 10);
1707+
Cache.try_emplace(
1708+
1, defer{[] { ASSERT_TRUE(false && "this should never be executed"); }});
1709+
}
1710+
17021711
} // namespace

0 commit comments

Comments
 (0)