using System;
using System.Collections.Concurrent;

namespace LeafWeb.Core.Utility
{
	public static class Memoizer
	{
		public static Func<A, R> ThreadsafeMemoize<A, R>(Func<A, R> f)
		{
			var cache = new ConcurrentDictionary<A, R>();

			return argument => cache.GetOrAdd(argument, f);
		}

		public static Func<A1, A2, R> ThreadsafeMemoize<A1, A2, R>(Func<A1, A2, R> f)
		{
			var cache = new ConcurrentDictionary<Tuple<A1, A2>, R>();

			return (a1, a2) => cache.GetOrAdd(Tuple.Create(a1, a2), t => f(t.Item1, t.Item2));
		}
	}
}
