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.

656 lines
20KB

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