using System; using System.Collections.Generic; namespace Semmle.Extraction.CIL { /// /// A factory and a cache for mapping source entities to target entities. /// Could be considered as a memoizer. /// /// The type of the source. /// The type of the generated object. public class CachedFunction where TSrc : notnull { private readonly Func generator; private readonly Dictionary cache; /// /// Initializes the factory with a given mapping. /// /// The mapping. public CachedFunction(Func g) { generator = g; cache = new Dictionary(); } /// /// Gets the target for a given source. /// Create it if it does not exist. /// /// The source object. /// The created object. public TTarget this[TSrc src] { get { if (!cache.TryGetValue(src, out var result)) { result = generator(src); cache[src] = result; } return result; } } } /// /// A factory for mapping a pair of source entities to a target entity. /// /// Source entity type 1. /// Source entity type 2. /// The target type. public class CachedFunction { private readonly CachedFunction<(TSrcEntity1, TSrcEntity2), TTarget> factory; /// /// Initializes the factory with a given mapping. /// /// The mapping. public CachedFunction(Func g) { factory = new CachedFunction<(TSrcEntity1, TSrcEntity2), TTarget>(p => g(p.Item1, p.Item2)); } public TTarget this[TSrcEntity1 s1, TSrcEntity2 s2] => factory[(s1, s2)]; } }