Result Cache<Result(Args...)>::operator()(Args... args) { argument_tuple tup{args...}; auto map_iter = map.find(tup); bool insert = map_iter == map.end(); log.push_back(nullptr); ScopeFailure guard([&] { log.pop_back(); }); if (insert) map_iter = map.insert({tup, {tuple_invoke(fun, tup), {}}}).first; log.back() = &map_iter->first; if (! insert) log.erase(map_iter->second.log_iter); map_iter->second.log_iter = std::prev(log.end()); if (insert && map.size() > cap) { map.erase(*log.front()); log.pop_front(); } return map_iter->second.result; }
// Purge the least-recently-used element in the cache void evict() { // Assert method is never called when cache is empty assert(!list_.empty()); if( list_.empty() ) return; // Identify least recently used key map_const_iterator it = map_.find(list_.front()); assert(it != map_.end()); if( it == map_.end() ) return; if( it->second.first.second != 0 ) it->second.first.second(list_.front(), it->second.first.first); // Erase both elements to completely purge record map_.erase(it); list_.pop_front(); }