Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Memoizer.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Cache_Memoizer_h_
5#define _Stroika_Foundation_Cache_Memoizer_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include <optional>
10#include <vector>
11
12#include "Stroika/Foundation/Cache/LRUCache.h"
14#include "Stroika/Foundation/Common/Common.h"
16#include "Stroika/Foundation/Containers/Mapping.h"
17
18/**
19 * \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
20 *
21 * TODO:
22 * @todo maybe allow passing in Cache object as CTOR parameter as a way to specify the hash function etc (for LRUCache with hash)
23 *
24 * @todo Investigate if better arg order for template or instantiation guide might reduce number of explicit
25 * args needed for template
26 */
27
29
30#if qCompilerAndStdLib_template_template_argument_as_different_template_paramters_Buggy
31 namespace MemoizerSupport {
32 template <typename T1, typename T2>
33 using DEFAULT_CACHE_BWA_ = LRUCache<T1, T2>;
34 }
35#endif
36
37 /**
38 * \brief Cache the results of expensive computations transparently
39 *
40 * @see https://en.wikipedia.org/wiki/Memoization
41 *
42 * TODO:
43 * o @todo Asked https://softwareengineering.stackexchange.com/questions/377020/c-templates-combining-deduction-with-default-template-arguments
44 * to see how to improve
45 *
46 * o @todo maybe update https://softwareengineering.stackexchange.com/questions/375257/how-can-i-aggregate-this-large-data-set-to-reduce-the-overhead-of-calculating-th/375303#375303 with this... if/when I get it working well...
47 *
48 * \note Memoizer works well wtih LRUCache, SynchronizedLRUCache, TimedCache, or SynchronizedTimeCache. But
49 * it does NOT work with CallerStalenessCache, because that cache requires the caller to specify an allowed staleness on each
50 * call.
51 *
52 * \note \em Thread-Safety <a href="Thread-Safety.md">Same as (worse case of) underlying CACHE template argument, and argument function. Since the function will typically be fully reentrant, this comes down to the re-entrancy of the argument Cache. Used with SynchronizedLRUCache and a typical function, for example, this is fully re-entrant</a>
53 */
54 template <typename RESULT, template <typename, typename> class CACHE = LRUCache, typename... ARGS>
55 class Memoizer {
56 public:
57 /**
58 * \note see Tests use of qCompilerAndStdLib_template_template_argument_as_different_template_paramters_Buggy if you get the message
59 * "template template argument has different template parameters than its corresponding template template parameter"
60 *
61 * \par Example Usage
62 * \code
63 * unsigned int totalCallsCount{};
64 * Memoizer<int, LRUCache, int, int> memoizer{[&totalCallsCount](int a, int b) { ++totalCallsCount; return a + b; }};
65 * EXPECT_TRUE (memoizer (1, 1) == 2 and totalCallsCount == 1);
66 * EXPECT_TRUE (memoizer (1, 1) == 2 and totalCallsCount == 1);
67 * \endcode
68 */
69 Memoizer (const function<RESULT (ARGS...)>& f, CACHE<tuple<ARGS...>, RESULT>&& cache = CACHE<tuple<ARGS...>, RESULT>{});
70 Memoizer (Memoizer&& from) noexcept = default;
71 Memoizer (const Memoizer& from) = default;
72
73 public:
74 nonvirtual Memoizer& operator= (Memoizer&& rhs) noexcept = default;
75 nonvirtual Memoizer& operator= (const Memoizer& rhs) = default;
76
77 public:
78 /**
79 * \note this function is not const, because it modifies the state of the object/cache.
80 */
81 nonvirtual RESULT operator() (ARGS... args);
82
83 private:
84 function<RESULT (ARGS...)> fFunction_;
85 CACHE<tuple<ARGS...>, RESULT> fCache_;
86 };
87
88}
89
90/*
91 ********************************************************************************
92 ***************************** Implementation Details ***************************
93 ********************************************************************************
94 */
95#include "Memoizer.inl"
96
97#endif /*_Stroika_Foundation_Cache_Memoizer_h_*/
LRUCache implements a simple least-recently-used caching strategy, with optional hashing (of keys) to...
Definition LRUCache.h:94
Cache the results of expensive computations transparently.
Definition Memoizer.h:55
nonvirtual RESULT operator()(ARGS... args)
Definition Memoizer.inl:20