Line data Source code
1 1 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : /// \file 5 : /// Defines class CachedFunction 6 : 7 : #pragma once 8 : 9 : #include <type_traits> 10 : #include <unordered_map> 11 : #include <utility> 12 : 13 : /// A function wrapper that caches function values. 14 : template <typename Function, typename Map> 15 1 : class CachedFunction { 16 : public: 17 0 : using input = typename Map::key_type; 18 0 : using output = typename Map::mapped_type; 19 : 20 : template <typename... MapArgs> 21 0 : explicit CachedFunction(Function function, MapArgs... map_args) 22 : : function_(std::move(function)), 23 : cache_(std::forward<MapArgs>(map_args)...) {} 24 : 25 : /// Obtain the function result 26 1 : const output& operator()(const input& x) { 27 : auto it = cache_.find(x); 28 : if (it == cache_.end()) { 29 : it = cache_.emplace(x, function_(x)).first; 30 : } 31 : return it->second; 32 : } 33 : 34 : /// Clear the cache entries 35 1 : void clear() { cache_.clear(); } 36 : 37 : private: 38 0 : Function function_; 39 0 : Map cache_; 40 : }; 41 : 42 : /// Construct a CachedFunction wrapping the given function 43 : /// 44 : /// \example 45 : /// \snippet Test_CachedFunction.cpp make_cached_function_example 46 : /// 47 : /// \tparam Input function argument type 48 : /// \tparam Map class template to use as the map holding the cache 49 : /// \param function the function 50 : /// \param map_args arguments to pass to the map constructor 51 : template <typename Input, template <typename...> class Map = std::unordered_map, 52 : typename... MapArgs, typename Function, typename... PassedMapArgs> 53 1 : auto make_cached_function(Function function, PassedMapArgs... map_args) { 54 : using output = std::invoke_result_t<Function&, const Input&>; 55 : return CachedFunction<Function, Map<std::decay_t<Input>, 56 : std::decay_t<output>, 57 : MapArgs...>>( 58 : std::move(function), std::forward<PassedMapArgs>(map_args)...); 59 : }