Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

545 lines
18KB

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. namespace Svelto.DataStructures
  5. {
  6. public struct ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
  7. {
  8. public bool isInitialized { get { return _dictionary != null; } }
  9. /// <summary>
  10. /// Gets the element that has the specified key.
  11. /// </summary>
  12. /// <param name="key">The key of the element to get.</param>
  13. /// <returns>The element that has the specified key.</returns>
  14. /// <exception cref="ArgumentNullException">If <paramref name="key"/> is <see langword="null"/>.</exception>
  15. /// <exception cref="KeyNotFoundException">If property is retrieved and <paramref name="key"/> is not found.</exception>
  16. public TValue this[TKey key]
  17. {
  18. get
  19. {
  20. return _dictionary[key];
  21. }
  22. }
  23. /// <summary>
  24. /// Gets the number of items in the dictionary.
  25. /// </summary>
  26. /// <value>
  27. /// The number of items in the dictionary.
  28. /// </value>
  29. public int Count
  30. {
  31. get
  32. {
  33. return _dictionary.Count;
  34. }
  35. }
  36. /// <summary>
  37. /// Gets a key collection that contains the keys of the dictionary.
  38. /// </summary>
  39. /// <value>
  40. /// A key collection that contains the keys of the dictionary.
  41. /// </value>
  42. public KeyCollection Keys
  43. {
  44. get
  45. {
  46. return new KeyCollection(_dictionary.Keys);
  47. }
  48. }
  49. /// <summary>
  50. /// Gets a collection that contains the values in the dictionary.
  51. /// </summary>
  52. /// <value>
  53. /// A collection that contains the values in the object that implements <see cref="ReadOnlyDictionary{TKey, TValue}"/>.
  54. /// </value>
  55. public ValueCollection Values
  56. {
  57. get
  58. {
  59. return new ValueCollection(_dictionary.Values);
  60. }
  61. }
  62. /// <summary>
  63. /// Initializes a new instance of the <see cref="ReadOnlyDictionary{TKey, TValue}"/> class
  64. /// that is a wrapper around the specified dictionary.
  65. /// </summary>
  66. /// <param name="dictionary">The dictionary to wrap.</param>
  67. public ReadOnlyDictionary(Dictionary<TKey, TValue> dictionary)
  68. {
  69. if (dictionary == null)
  70. throw new ArgumentNullException("dictionary");
  71. _dictionary = dictionary;
  72. }
  73. /// <inheritdoc/>
  74. /// <summary>
  75. /// Gets the element that has the specified key.
  76. /// </summary>
  77. /// <exception cref="NotSupportedException">If the property is set.</exception>
  78. TValue IDictionary<TKey, TValue>.this[TKey key]
  79. {
  80. get
  81. {
  82. return this[key];
  83. }
  84. set
  85. {
  86. throw new NotSupportedException();
  87. }
  88. }
  89. /// <inheritdoc/>
  90. ICollection<TKey> IDictionary<TKey, TValue>.Keys
  91. {
  92. get
  93. {
  94. return Keys;
  95. }
  96. }
  97. /// <inheritdoc/>
  98. ICollection<TValue> IDictionary<TKey, TValue>.Values
  99. {
  100. get
  101. {
  102. return Values;
  103. }
  104. }
  105. /// <inheritdoc/>
  106. bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
  107. {
  108. get
  109. {
  110. return true;
  111. }
  112. }
  113. /// <inheritdoc/>
  114. IEnumerator IEnumerable.GetEnumerator()
  115. {
  116. return GetEnumerator();
  117. }
  118. /// <inheritdoc/>
  119. void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
  120. {
  121. throw new NotSupportedException();
  122. }
  123. /// <inheritdoc/>
  124. bool IDictionary<TKey, TValue>.Remove(TKey key)
  125. {
  126. throw new NotSupportedException();
  127. }
  128. /// <inheritdoc/>
  129. void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
  130. {
  131. throw new NotSupportedException();
  132. }
  133. /// <inheritdoc/>
  134. void ICollection<KeyValuePair<TKey, TValue>>.Clear()
  135. {
  136. throw new NotSupportedException();
  137. }
  138. /// <inheritdoc/>
  139. bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
  140. {
  141. throw new NotImplementedException();
  142. }
  143. /// <inheritdoc/>
  144. void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
  145. {
  146. throw new NotImplementedException();
  147. }
  148. /// <inheritdoc/>
  149. bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
  150. {
  151. throw new NotSupportedException();
  152. }
  153. bool IDictionary<TKey, TValue>.ContainsKey(TKey key)
  154. {
  155. return _dictionary.ContainsKey(key);
  156. }
  157. bool IDictionary<TKey, TValue>.TryGetValue(TKey key, out TValue value)
  158. {
  159. return _dictionary.TryGetValue(key, out value);
  160. }
  161. int ICollection<KeyValuePair<TKey, TValue>>.Count
  162. {
  163. get { return _dictionary.Count; }
  164. }
  165. IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
  166. {
  167. return _dictionary.GetEnumerator();
  168. }
  169. /// <summary>
  170. /// Determines whether the dictionary contains an element that has the specified key.
  171. /// </summary>
  172. /// <param name="key">The key to locate in the dictionary.</param>
  173. /// <returns><see langword="true"/> if the dictionary contains an element that has the specified key; otherwise, <see langword="false"/>.</returns>
  174. public bool ContainsKey(TKey key)
  175. {
  176. return _dictionary.ContainsKey(key);
  177. }
  178. public DictionaryEnumerator GetEnumerator()
  179. {
  180. return new DictionaryEnumerator(_dictionary);
  181. }
  182. /// <summary>
  183. /// Retrieves the value that is associated with the specified key.
  184. /// </summary>
  185. /// <param name="key">The key whose value will be retrieved.</param>
  186. /// <param name="value">When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the type of the <paramref name="value"/> parameter. This parameter is passed uninitialized.</param>
  187. /// <returns><see langword="true"/> if the object that implements <see cref="ReadOnlyDictionary{TKey, TValue}"/> contains an element with the specified key; otherwise, <see langword="false"/>.</returns>
  188. public bool TryGetValue(TKey key, out TValue value)
  189. {
  190. return _dictionary.TryGetValue(key, out value);
  191. }
  192. readonly Dictionary<TKey, TValue> _dictionary;
  193. /// <summary>
  194. /// Represents a read-only collection of the keys of a <see cref="ReadOnlyDictionary{TKey, TValue}"/> object.
  195. /// </summary>
  196. public struct KeyCollection : ICollection<TKey>, ICollection
  197. {
  198. /// <summary>
  199. /// Initializes a new instance of the <see cref="KeyCollection"/> class
  200. /// as a wrapper around the specified collection of keys.
  201. /// </summary>
  202. /// <param name="keys">The collection of keys to wrap.</param>
  203. /// <exception cref="ArgumentNullException">If <paramref name="keys"/> is <see langword="null"/>.</exception>
  204. internal KeyCollection(ICollection<TKey> keys)
  205. {
  206. if (keys == null)
  207. throw new ArgumentNullException("keys");
  208. _keys = keys;
  209. }
  210. /// <inheritdoc/>
  211. bool ICollection.IsSynchronized
  212. {
  213. get
  214. {
  215. return false;
  216. }
  217. }
  218. /// <inheritdoc/>
  219. object ICollection.SyncRoot
  220. {
  221. get
  222. {
  223. throw new NotImplementedException();
  224. }
  225. }
  226. /// <inheritdoc/>
  227. void ICollection.CopyTo(Array array, int index)
  228. {
  229. throw new NotImplementedException();
  230. }
  231. /// <summary>
  232. /// Gets the number of elements in the collection.
  233. /// </summary>
  234. /// <value>
  235. /// The number of elements in the collection.
  236. /// </value>
  237. public int Count
  238. {
  239. get
  240. {
  241. return _keys.Count;
  242. }
  243. }
  244. /// <inheritdoc/>
  245. bool ICollection<TKey>.IsReadOnly
  246. {
  247. get
  248. {
  249. return true;
  250. }
  251. }
  252. /// <summary>
  253. /// Copies the elements of the collection to an array, starting at a specific array index.
  254. /// </summary>
  255. /// <param name="array">The one-dimensional array that is the destination of the elements copied from the collection. The array must have zero-based indexing.</param>
  256. /// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
  257. /// <exception cref="ArgumentNullException">If <paramref name="array"/> is <see langword="null"/>.</exception>
  258. /// <exception cref="ArgumentOutOfRangeException">If <paramref name="arrayIndex"/> is less than 0.</exception>
  259. /// <exception cref="ArgumentException">
  260. /// If <paramref name="array"/> is multidimensional.
  261. /// <para>-or-</para>
  262. /// <para>If the number of elements in the source collection is greater than the available space from <paramref name="arrayIndex"/> to the end of the destination <paramref name="array"/>.</para>
  263. /// <para>-or-</para>
  264. /// <para>If the type <typeparamref name="TKey"/> cannot be cast automatically to the type of the destination <paramref name="array"/>.</para>
  265. /// </exception>
  266. public void CopyTo(TKey[] array, int arrayIndex)
  267. {
  268. _keys.CopyTo(array, arrayIndex);
  269. }
  270. /// <summary>
  271. /// Returns an enumerator that iterates through the collection.
  272. /// </summary>
  273. /// <returns>An enumerator that can be used to iterate through the collection.</returns>
  274. public IEnumerator<TKey> GetEnumerator()
  275. {
  276. return _keys.GetEnumerator();
  277. }
  278. /// <inheritdoc/>
  279. IEnumerator IEnumerable.GetEnumerator()
  280. {
  281. return GetEnumerator();
  282. }
  283. /// <inheritdoc/>
  284. bool ICollection<TKey>.Contains(TKey item)
  285. {
  286. return _keys.Contains(item);
  287. }
  288. /// <inheritdoc/>
  289. void ICollection<TKey>.Add(TKey item)
  290. {
  291. throw new NotSupportedException();
  292. }
  293. /// <inheritdoc/>
  294. bool ICollection<TKey>.Remove(TKey item)
  295. {
  296. throw new NotSupportedException();
  297. }
  298. /// <inheritdoc/>
  299. void ICollection<TKey>.Clear()
  300. {
  301. throw new NotSupportedException();
  302. }
  303. /// <summary>
  304. /// The wrapped collection of keys.
  305. /// </summary>
  306. readonly ICollection<TKey> _keys;
  307. }
  308. /// <summary>
  309. /// Represents a read-only collection of the values of a <see cref="ReadOnlyDictionary{TKey, TValue}"/> object.
  310. /// </summary>
  311. public struct ValueCollection : ICollection<TValue>, ICollection
  312. {
  313. /// <summary>
  314. /// Initializes a new instance of the <see cref="ValueCollection"/> class
  315. /// as a wrapper around the specified collection of values.
  316. /// </summary>
  317. /// <param name="values">The collection of values to wrap.</param>
  318. /// <exception cref="ArgumentNullException">If <paramref name="values"/> is <see langword="null"/>.</exception>
  319. internal ValueCollection(ICollection<TValue> values)
  320. {
  321. if (values == null)
  322. throw new ArgumentNullException("values");
  323. _values = values;
  324. }
  325. /// <inheritdoc/>
  326. bool ICollection.IsSynchronized
  327. {
  328. get
  329. {
  330. return false;
  331. }
  332. }
  333. /// <inheritdoc/>
  334. object ICollection.SyncRoot
  335. {
  336. get
  337. {
  338. throw new NotImplementedException();
  339. }
  340. }
  341. /// <inheritdoc/>
  342. void ICollection.CopyTo(Array array, int index)
  343. {
  344. throw new NotImplementedException();
  345. }
  346. /// <summary>
  347. /// Gets the number of elements in the collection.
  348. /// </summary>
  349. /// <value>
  350. /// The number of elements in the collection.
  351. /// </value>
  352. public int Count
  353. {
  354. get
  355. {
  356. return _values.Count;
  357. }
  358. }
  359. /// <inheritdoc/>
  360. bool ICollection<TValue>.IsReadOnly
  361. {
  362. get
  363. {
  364. return true;
  365. }
  366. }
  367. /// <summary>
  368. /// Copies the elements of the collection to an array, starting at a specific array index.
  369. /// </summary>
  370. /// <param name="array">The one-dimensional array that is the destination of the elements copied from the collection. The array must have zero-based indexing.</param>
  371. /// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
  372. /// <exception cref="ArgumentNullException">If <paramref name="array"/> is <see langword="null"/>.</exception>
  373. /// <exception cref="ArgumentOutOfRangeException">If <paramref name="arrayIndex"/> is less than 0.</exception>
  374. /// <exception cref="ArgumentException">
  375. /// If <paramref name="array"/> is multidimensional.
  376. /// <para>-or-</para>
  377. /// <para>If the number of elements in the source collection is greater than the available space from <paramref name="arrayIndex"/> to the end of the destination <paramref name="array"/>.</para>
  378. /// <para>-or-</para>
  379. /// <para>If the type <typeparamref name="TValue"/> cannot be cast automatically to the type of the destination <paramref name="array"/>.</para>
  380. /// </exception>
  381. public void CopyTo(TValue[] array, int arrayIndex)
  382. {
  383. _values.CopyTo(array, arrayIndex);
  384. }
  385. /// <summary>
  386. /// Returns an enumerator that iterates through the collection.
  387. /// </summary>
  388. /// <returns>An enumerator that can be used to iterate through the collection.</returns>
  389. public IEnumerator<TValue> GetEnumerator()
  390. {
  391. return _values.GetEnumerator();
  392. }
  393. /// <inheritdoc/>
  394. IEnumerator IEnumerable.GetEnumerator()
  395. {
  396. return GetEnumerator();
  397. }
  398. /// <inheritdoc/>
  399. bool ICollection<TValue>.Contains(TValue item)
  400. {
  401. return _values.Contains(item);
  402. }
  403. /// <inheritdoc/>
  404. void ICollection<TValue>.Add(TValue item)
  405. {
  406. throw new NotSupportedException();
  407. }
  408. /// <inheritdoc/>
  409. bool ICollection<TValue>.Remove(TValue item)
  410. {
  411. throw new NotSupportedException();
  412. }
  413. /// <inheritdoc/>
  414. void ICollection<TValue>.Clear()
  415. {
  416. throw new NotSupportedException();
  417. }
  418. /// <summary>
  419. /// The wrapped collection of values.
  420. /// </summary>
  421. readonly ICollection<TValue> _values;
  422. }
  423. public struct DictionaryEnumerator:IEnumerator<KeyValuePair<TKey,TValue>>
  424. {
  425. /// <inheritdoc/>
  426. public TKey Key
  427. {
  428. get
  429. {
  430. return _enumerator.Current.Key;
  431. }
  432. }
  433. /// <inheritdoc/>
  434. public TValue Value
  435. {
  436. get
  437. {
  438. return _enumerator.Current.Value;
  439. }
  440. }
  441. public DictionaryEnumerator(IDictionary<TKey, TValue> dictionary)
  442. {
  443. if (dictionary == null)
  444. throw new ArgumentNullException("dictionary");
  445. _enumerator = dictionary.GetEnumerator();
  446. }
  447. /// <inheritdoc/>
  448. public KeyValuePair<TKey, TValue> Current
  449. {
  450. get
  451. {
  452. return _enumerator.Current;
  453. }
  454. }
  455. /// <inheritdoc/>
  456. public bool MoveNext()
  457. {
  458. return _enumerator.MoveNext();
  459. }
  460. /// <inheritdoc/>
  461. public void Reset()
  462. {
  463. _enumerator.Reset();
  464. }
  465. object IEnumerator.Current
  466. {
  467. get { return _enumerator.Current; }
  468. }
  469. public void Dispose()
  470. {
  471. _enumerator.Dispose();
  472. }
  473. readonly IEnumerator<KeyValuePair<TKey, TValue>> _enumerator;
  474. }
  475. }
  476. }