using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace miew.ReadOnly
{
public static class Extensions
{
static public IReadOnlyDictionary<TKey, TValue> ToReadOnlyDictionary<TSrc, TKey, TValue>(
this IEnumerable<TSrc> ie,
Func<TSrc, TKey> key_selector,
Func<TSrc, TValue> value_selector)
{
return new ReadOnlyDictionary<TKey, TValue>(ie.ToDictionary(key_selector, value_selector));
}
static public IReadOnlyDictionary<TKey, TValue> ToReadOnlyDictionary<TKey, TValue>(this IDictionary<TKey, TValue> d)
{
return new ReadOnlyDictionary<TKey, TValue>(d);
}
static public IReadOnlyCollection<T> ToReadOnlyCollection<T>(this IEnumerable<T> seq)
{
return new ReadOnlyCollection<T>(seq);
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public struct DeferredCollection<T> : ICollection<T>
{
int c;
IEnumerable<T> ie;
public DeferredCollection(int c, IEnumerable<T> ie)
{
this.c = c;
this.ie = ie;
}
public bool Contains(T item) { return ie.Contains(item); }
public void CopyTo(T[] array, int arrayIndex)
{
foreach (T t in ie)
array[arrayIndex++] = t;
}
public void Add(T item) { throw new NotImplementedException(); }
public void Clear() { throw new NotImplementedException(); }
public int Count { get { return c; } }
public bool IsReadOnly { get { return true; } }
public bool Remove(T item) { throw new NotImplementedException(); }
public IEnumerator<T> GetEnumerator() { return ie.GetEnumerator(); }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ie.GetEnumerator();
}
};
public class ReadOnlyCollection<T> : IReadOnlyCollection<T>, ICollection<T>
{
T[] arr;
public ReadOnlyCollection(IEnumerable<T> seq)
{
this.arr = seq as T[] ?? seq.ToArray();
}
public int Count { get { return arr.Length; } }
public T this[int ix] { get { return arr[ix]; } }
public int IndexOf(T item) { return System.Array.IndexOf<T>(arr, item); }
public bool Contains(T item) { return System.Array.IndexOf<T>(arr, item) != -1; }
public void CopyTo(T[] array, int arrayIndex) { arr.CopyTo(array, arrayIndex); }
public IEnumerator<T> GetEnumerator() { return arr.AsEnumerable<T>().GetEnumerator(); }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return arr.AsEnumerable<T>().GetEnumerator();
}
public static explicit operator T[](ReadOnlyCollection<T> ro)
{
return ro.arr;
}
public static explicit operator ReadOnlyCollection<T>(T[] seq)
{
return new ReadOnlyCollection<T>(seq);
}
public bool IsReadOnly { get { return true; } }
public void Add(T item) { throw new InvalidOperationException(); }
public void Clear() { throw new InvalidOperationException(); }
public bool Remove(T item) { throw new InvalidOperationException(); }
};
public interface IReadOnlyCollection<T> : IEnumerable<T>
{
bool Contains(T item);
void CopyTo(T[] array, int arrayIndex);
int Count { get; }
T this[int ix] { get; }
int IndexOf(T item);
};
public interface IReadOnlyDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
{
bool ContainsKey(TKey key);
ICollection<TKey> Keys { get; }
ICollection<TValue> Values { get; }
int Count { get; }
bool IsReadOnly { get; }
bool TryGetValue(TKey key, out TValue value);
TValue this[TKey key] { get; }
}
public class ReadOnlyDictionary<TKey, TValue> : IReadOnlyDictionary<TKey, TValue>
{
static ReadOnlyDictionary<TKey, TValue> _e = null;
public static ReadOnlyDictionary<TKey, TValue> Empty { get { return _e = _e ?? new ReadOnlyDictionary<TKey, TValue>(); } }
private IDictionary<TKey, TValue> _dict;
public ReadOnlyDictionary()
{
_dict = new Dictionary<TKey, TValue>();
}
public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
{
_dict = dictionary;
}
public bool ContainsKey(TKey key)
{
return _dict.ContainsKey(key);
}
public ICollection<TKey> Keys
{
get { return _dict.Keys; }
}
public bool TryGetValue(TKey key, out TValue value)
{
return _dict.TryGetValue(key, out value);
}
public ICollection<TValue> Values
{
get { return _dict.Values; }
}
public TValue this[TKey key]
{
get { return _dict[key]; }
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return _dict.Contains(item);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
_dict.CopyTo(array, arrayIndex);
}
public int Count
{
get { return _dict.Count; }
}
public bool IsReadOnly
{
get { return true; }
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return _dict.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
};
public struct CovariantCollectionWrapper<TOut, TIn> : ICollection<TOut> where TIn : TOut
{
readonly ICollection<TIn> coll;
public CovariantCollectionWrapper(ICollection<TIn> coll)
{
this.coll = coll;
}
public bool Contains(TOut item)
{
return item is TIn && coll.Contains((TIn)item);
}
public void CopyTo(TOut[] array, int arrayIndex)
{
foreach (TOut t in this)
array[arrayIndex++] = t;
}
public int Count { get { return coll.Count; } }
public bool IsReadOnly { get { return true; } }
public IEnumerator<TOut> GetEnumerator()
{
foreach (TIn t in coll)
yield return t;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(TOut item) { throw new InvalidOperationException(); }
public void Clear() { throw new InvalidOperationException(); }
public bool Remove(TOut item) { throw new InvalidOperationException(); }
};
public struct CovariantListWrapper<TOut, TIn> : IList<TOut> where TIn : TOut
{
readonly IList<TIn> list;
public CovariantListWrapper(IList<TIn> list)
{
this.list = list;
}
public int IndexOf(TOut item)
{
// (not covariant but permitted)
return item is TIn ? list.IndexOf((TIn)item) : -1;
}
public TOut this[int index]
{
get { return list[index]; }
set { throw new InvalidOperationException(); }
}
public bool Contains(TOut item)
{
// (not covariant but permitted)
return item is TIn && list.Contains((TIn)item);
}
public void CopyTo(TOut[] array, int arrayIndex)
{
foreach (TOut t in this)
array[arrayIndex++] = t;
}
public int Count { get { return list.Count; } }
public bool IsReadOnly { get { return true; } }
public IEnumerator<TOut> GetEnumerator()
{
foreach (TIn t in list)
yield return t;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Insert(int index, TOut item) { throw new InvalidOperationException(); }
public void RemoveAt(int index) { throw new InvalidOperationException(); }
public void Add(TOut item) { throw new InvalidOperationException(); }
public void Clear() { throw new InvalidOperationException(); }
public bool Remove(TOut item) { throw new InvalidOperationException(); }
}
public class CovariantDictionaryWrapper<TKey, TOut, TIn> : IReadOnlyDictionary<TKey, TOut> where TIn : TOut
{
private IDictionary<TKey, TIn> _dict;
private ICollection<TOut> values = null;
public CovariantDictionaryWrapper(IDictionary<TKey, TIn> dictionary)
{
_dict = dictionary;
}
public bool ContainsKey(TKey key)
{
return _dict.ContainsKey(key);
}
public ICollection<TKey> Keys
{
get { return _dict.Keys; }
}
public bool TryGetValue(TKey key, out TOut value)
{
TIn v;
if (!_dict.TryGetValue(key, out v))
{
value = default(TOut);
return false;
}
value = v;
return true;
}
public ICollection<TOut> Values
{
get { return values = values ?? new CovariantCollectionWrapper<TOut, TIn>(_dict.Values); }
}
public TOut this[TKey key]
{
get { return _dict[key]; }
}
public bool Contains(KeyValuePair<TKey, TOut> item)
{
if (!(item.Value is TIn))
return false;
return _dict.Contains(new KeyValuePair<TKey, TIn>(item.Key, (TIn)item.Value));
}
public void CopyTo(KeyValuePair<TKey, TOut>[] array, int arrayIndex)
{
foreach (var kvp in this)
array[arrayIndex++] = kvp;
}
public int Count
{
get { return _dict.Count; }
}
public bool IsReadOnly
{
get { return true; }
}
public IEnumerator<KeyValuePair<TKey, TOut>> GetEnumerator()
{
foreach (var kvp in _dict)
yield return new KeyValuePair<TKey, TOut>(kvp.Key, kvp.Value);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
};
}