From 3cd16be08a589a6722df38f4d18e6b2f1b461b39 Mon Sep 17 00:00:00 2001 From: Kris van Rens Date: Thu, 3 Oct 2024 15:04:32 +0200 Subject: [PATCH] ADD: First implementation of find_or_try_insert_with. --- include/memo_cache.hpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/include/memo_cache.hpp b/include/memo_cache.hpp index a1b1f50..7b0ee27 100644 --- a/include/memo_cache.hpp +++ b/include/memo_cache.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -146,6 +147,43 @@ class memo_cache { return replace_and_shift(key, f(key)); } + /// Get a value, or, if it does not exist in the cache, insert it using the value computed by f. + /// Returns a result with a reference to the found, or newly inserted value associated with the given key. + /// If f fails, the error is returned. + /// If a value is inserted, the key is cloned. + /// + /// # Examples + /// + /// ``` + /// #include + /// #include + /// + /// mc::memo_cache c; + /// + /// assert(!c.contains(42)); + /// + /// auto v1 = c.find_or_try_insert_with(42, + /// [] -> std::expected { return "The Answer"; }); + /// + /// assert(v1 == "The Answer"); + /// assert(c.find(42).has_value()); + /// assert(c.find(42).value() == "The Answer"); + /// + /// auto v2 = c.find_or_try_insert_with(42, + /// [] -> std::expected { return std::unexpected{"Dunno"}; }); + /// + /// assert(!v2.has_value()); + /// assert(v2.error() == "Dunno"); + /// ``` + template + [[nodiscard]] std::expected, Error> find_or_try_insert_with(const Key& key, std::function(const Key&)> &&f) { + if (auto slot = find(key); slot) { + return *slot; + } + + return f(key).transform([&](auto v) { return replace_and_shift(key, std::move(v)); }); + } + /// Returns `true` if the cache contains a value for the specified key. /// /// # Examples