Advertisement
Guest User

Untitled

a guest
Sep 17th, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.32 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Runtime.InteropServices;
  5.  
  6. public class EnumKeyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
  7. {
  8. private Dictionary<int, TValue> data;
  9. private KeyCollection keys;
  10.  
  11. public TValue this[TKey key] { get { return data[ToIntKey(key)]; } set { data[ToIntKey(key)] = value; } }
  12.  
  13. public KeyCollection Keys
  14. {
  15. get
  16. {
  17. if (keys == null)
  18. {
  19. keys = new KeyCollection(this);
  20. }
  21. return keys;
  22. }
  23. }
  24.  
  25. ICollection<TKey> IDictionary<TKey, TValue>.Keys
  26. {
  27. get
  28. {
  29. if (keys == null)
  30. {
  31. keys = new KeyCollection(this);
  32. }
  33. return keys;
  34. }
  35. }
  36.  
  37. public Dictionary<int, TValue>.ValueCollection Values => data.Values;
  38. ICollection<TValue> IDictionary<TKey, TValue>.Values => data.Values;
  39.  
  40. public int Count => data.Count;
  41.  
  42. public bool IsReadOnly => false;
  43.  
  44. public EnumKeyDictionary()
  45. {
  46. data = new Dictionary<int, TValue>();
  47. }
  48.  
  49. public EnumKeyDictionary(int capacity)
  50. {
  51. data = new Dictionary<int, TValue>(capacity);
  52. }
  53.  
  54. public EnumKeyDictionary(IDictionary<TKey, TValue> dictionary)
  55. {
  56. var capacity = dictionary != null ? dictionary.Count : 0;
  57. data = new Dictionary<int, TValue>(capacity);
  58.  
  59. foreach (var pair in dictionary)
  60. {
  61. Add(pair.Key, pair.Value);
  62. }
  63. }
  64.  
  65. private static int ToIntKey(TKey key)
  66. {
  67. return EnumSupport.ToInt<TKey>(key);
  68. }
  69.  
  70. private static TKey ToEnumKey(int key)
  71. {
  72. return EnumSupport.ToEnum32<TKey>(key);
  73. }
  74.  
  75. private static KeyValuePair<TKey, TValue> GetKeyValuePair(int key, TValue value)
  76. {
  77. return new KeyValuePair<TKey, TValue>(ToEnumKey(key), value);
  78. }
  79.  
  80. private static KeyValuePair<TKey, TValue> GetKeyValuePair(KeyValuePair<int, TValue> pair)
  81. {
  82. return GetKeyValuePair(pair.Key, pair.Value);
  83. }
  84.  
  85. public void Add(TKey key, TValue value)
  86. {
  87. data.Add(ToIntKey(key), value);
  88. }
  89.  
  90. public void Clear()
  91. {
  92. data.Clear();
  93. }
  94.  
  95. public bool ContainsKey(TKey key)
  96. {
  97. return data.ContainsKey(ToIntKey(key));
  98. }
  99.  
  100. public bool Remove(TKey key)
  101. {
  102. return data.Remove(ToIntKey(key));
  103. }
  104.  
  105. public bool TryGetValue(TKey key, out TValue value)
  106. {
  107. return data.TryGetValue(ToIntKey(key), out value);
  108. }
  109.  
  110. public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
  111. {
  112. if (array == null)
  113. {
  114. throw new ArgumentNullException("array is null");
  115. }
  116. foreach (var pair in data)
  117. {
  118. array[arrayIndex++] = GetKeyValuePair(pair);
  119. }
  120. }
  121.  
  122. public TValue GetOrDefault(TKey key)
  123. {
  124. var value = default(TValue);
  125. if (TryGetValue(key, out value))
  126. {
  127. return value;
  128. }
  129. return default(TValue);
  130. }
  131.  
  132. public Enumerator GetEnumerator()
  133. {
  134. return new Enumerator(this);
  135. }
  136.  
  137. void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
  138. {
  139. Add(item.Key, item.Value);
  140. }
  141.  
  142. bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
  143. {
  144. var key = ToIntKey(item.Key);
  145. if (data.ContainsKey(key))
  146. {
  147. return EqualityComparer<TValue>.Default.Equals(data[key], item.Value);
  148. }
  149. return false;
  150. }
  151.  
  152. bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
  153. {
  154. var key = ToIntKey(item.Key);
  155. if (data.ContainsKey(key) && EqualityComparer<TValue>.Default.Equals(data[key], item.Value))
  156. {
  157. Remove(item.Key);
  158. return true;
  159. }
  160. return false;
  161. }
  162.  
  163. IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
  164. {
  165. return new Enumerator(this);
  166. }
  167.  
  168. IEnumerator IEnumerable.GetEnumerator()
  169. {
  170. return new Enumerator(this);
  171. }
  172.  
  173. public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>
  174. {
  175. private EnumKeyDictionary<TKey, TValue> dictionary;
  176. private Dictionary<int, TValue>.Enumerator enumerator;
  177.  
  178. public KeyValuePair<TKey, TValue> Current
  179. {
  180. get
  181. {
  182. return GetKeyValuePair(enumerator.Current);
  183. }
  184. }
  185.  
  186. object IEnumerator.Current
  187. {
  188. get
  189. {
  190. return GetKeyValuePair(enumerator.Current);
  191. }
  192. }
  193.  
  194. public Enumerator(EnumKeyDictionary<TKey, TValue> dictionary)
  195. {
  196. this.dictionary = dictionary;
  197. enumerator = dictionary.data.GetEnumerator();
  198. }
  199.  
  200. public void Dispose()
  201. {
  202. }
  203.  
  204. public bool MoveNext()
  205. {
  206. return enumerator.MoveNext();
  207. }
  208.  
  209. void IEnumerator.Reset()
  210. {
  211. enumerator = dictionary.data.GetEnumerator();
  212. }
  213. }
  214.  
  215. public sealed class KeyCollection : ICollection<TKey>
  216. {
  217. private EnumKeyDictionary<TKey, TValue> dictionary;
  218.  
  219. public int Count => dictionary.Count;
  220.  
  221. public bool IsReadOnly => true;
  222.  
  223. public KeyCollection(EnumKeyDictionary<TKey, TValue> dictionary)
  224. {
  225. this.dictionary = dictionary;
  226. }
  227.  
  228. public void CopyTo(TKey[] array, int arrayIndex)
  229. {
  230. if (array == null)
  231. {
  232. throw new ArgumentNullException("array is null");
  233. }
  234. foreach (var pair in dictionary)
  235. {
  236. array[arrayIndex++] = pair.Key;
  237. }
  238. }
  239.  
  240. bool ICollection<TKey>.Contains(TKey item)
  241. {
  242. return dictionary.ContainsKey(item);
  243. }
  244.  
  245. void ICollection<TKey>.Add(TKey item)
  246. {
  247. throw new NotSupportedException("Not Supprot KeyCollection Set");
  248. }
  249.  
  250. void ICollection<TKey>.Clear()
  251. {
  252. throw new NotSupportedException("Not Supprot KeyCollection Set");
  253. }
  254.  
  255. bool ICollection<TKey>.Remove(TKey item)
  256. {
  257. throw new NotSupportedException("Not Supprot KeyCollection Set");
  258. }
  259.  
  260. public Enumerator GetEnumerator()
  261. {
  262. return new Enumerator(dictionary);
  263. }
  264.  
  265. IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator()
  266. {
  267. return new Enumerator(dictionary);
  268. }
  269.  
  270. IEnumerator IEnumerable.GetEnumerator()
  271. {
  272. return new Enumerator(dictionary);
  273. }
  274.  
  275. public struct Enumerator : IEnumerator<TKey>
  276. {
  277. private EnumKeyDictionary<TKey, TValue> dictionary;
  278. private Dictionary<int, TValue>.Enumerator enumerator;
  279.  
  280. public TKey Current
  281. {
  282. get
  283. {
  284. return ToEnumKey(enumerator.Current.Key);
  285. }
  286. }
  287.  
  288. object IEnumerator.Current
  289. {
  290. get
  291. {
  292. return ToEnumKey(enumerator.Current.Key);
  293. }
  294. }
  295.  
  296. public Enumerator(EnumKeyDictionary<TKey, TValue> dictionary)
  297. {
  298. this.dictionary = dictionary;
  299. enumerator = dictionary.data.GetEnumerator();
  300. }
  301.  
  302. public void Dispose()
  303. {
  304. }
  305.  
  306. public bool MoveNext()
  307. {
  308. return enumerator.MoveNext();
  309. }
  310.  
  311. void IEnumerator.Reset()
  312. {
  313. enumerator = dictionary.data.GetEnumerator();
  314. }
  315. }
  316. }
  317.  
  318. public class EnumSupport
  319. {
  320. #if PLATFORM_SUPPORTS_MONO
  321. class ValueCastTo<TTo>
  322. {
  323. [StructLayout(LayoutKind.Explicit)]
  324. struct Reinterpret<TFrom>
  325. {
  326. [FieldOffset(0)] public TFrom From;
  327. [FieldOffset(0)] public TTo To;
  328. }
  329.  
  330. public static TTo From<TFrom>(TFrom from)
  331. {
  332. var r = default(Reinterpret<TFrom>);
  333. r.From = from;
  334. return r.To;
  335. }
  336. }
  337.  
  338. #elif false
  339. // C# 7.3 ~
  340. class EnumCaster<TEnum> where TEnum : unmanaged, Enum
  341. {
  342. public static TResult To<TResult>(TEnum value) where TResult : unmanaged
  343. {
  344. unsafe
  345. {
  346. TResult outVal = default;
  347. Buffer.MemoryCopy(&value, &outVal, sizeof(TResult), sizeof(TEnum));
  348. return outVal;
  349. }
  350. }
  351.  
  352. public static TEnum From<TSource>(TSource value) where TSource : unmanaged
  353. {
  354. unsafe
  355. {
  356. TEnum outVal = default;
  357. long size = sizeof(TEnum) < sizeof(TSource) ? sizeof(TEnum) : sizeof(TSource);
  358. Buffer.MemoryCopy(&value, &outVal, sizeof(TEnum), size);
  359. return outVal;
  360. }
  361. }
  362. }
  363.  
  364. class ValueCastTo<TTo>
  365. {
  366. static bool isEnum = typeof(TTo).IsEnum;
  367.  
  368. public static TTo From<TFrom>(TFrom from)
  369. {
  370. if (isEnum)
  371. {
  372. return EnumCaster<TTo>.From(from);
  373. }
  374. else
  375. {
  376. return EnumCaster<TFrom>.To(from);
  377. }
  378. }
  379. }
  380. #else
  381. // others (without AOT)
  382. class ValueCastTo<TTo>
  383. {
  384. class Cache<TFrom>
  385. {
  386. public static readonly Func<TFrom, TTo> Caster = Get();
  387.  
  388. static Func<TFrom, TTo> Get()
  389. {
  390. var p = Expression.Parameter(typeof(TFrom), "from");
  391. var c = Expression.ConvertChecked(p, typeof(TTo));
  392. return Expression.Lambda<Func<TFrom, TTo>>(c, p).Compile();
  393. }
  394. }
  395.  
  396. public static TTo From<TFrom>(TFrom from) where TFrom : struct
  397. {
  398. return Cache<TFrom>.Caster(from);
  399. }
  400. }
  401. #endif
  402.  
  403. public static int ToInt<T>(T e)
  404. {
  405. return ValueCastTo<int>.From(e);
  406. }
  407.  
  408. public static T ToEnum32<T>(int value)
  409. {
  410. return ValueCastTo<T>.From(value);
  411. }
  412. }
  413.  
  414. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement