Design a deterministic wrapper that accepts any function during construction. When the wrapper is invoked, it must transparently delegate to the underlying function but with a caching layer: if the wrapper has already been called with a particular set of arguments, it should return the previously computed result immediately, without re-executing the function.
The wrapper must be generic — it should work with arbitrary callables. Additionally, describe a strategy for bounding the cache to a fixed number of entries, for example by employing an LRU (least-recently-used) eviction policy.
Some argument types may not be hashable. Use SFINAE (Substitution Failure Is Not An Error) to constrain the wrapper so that it only participates in overload resolution when all argument types satisfy the hashability requirement.
Expected caching behavior: The first call with arguments (1, 1) computes the result and stores it. The second call with (2, 2) computes a new result and stores it. The third call repeats (1, 1); the wrapper recognizes the arguments, skips the function call, and returns the cached value.