PageRenderTime 50ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/mcs/class/Mono.C5/C5/Wrappers.cs

https://bitbucket.org/danipen/mono
C# | 2405 lines | 770 code | 484 blank | 1151 comment | 33 complexity | 9ac782af976065aa2abfdd264317fd29 MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  17. SOFTWARE.
  18. */
  19. using System;
  20. using System.Diagnostics;
  21. using SCG = System.Collections.Generic;
  22. namespace C5
  23. {
  24. /// <summary>
  25. /// A read-only wrapper class for a generic enumerator
  26. /// </summary>
  27. public class GuardedEnumerator<T> : SCG.IEnumerator<T>
  28. {
  29. #region Fields
  30. SCG.IEnumerator<T> enumerator;
  31. #endregion
  32. #region Constructor
  33. /// <summary>
  34. /// Create a wrapper around a generic enumerator
  35. /// </summary>
  36. /// <param name="enumerator">The enumerator to wrap</param>
  37. public GuardedEnumerator(SCG.IEnumerator<T> enumerator)
  38. { this.enumerator = enumerator; }
  39. #endregion
  40. #region IEnumerator<T> Members
  41. /// <summary>
  42. /// Move wrapped enumerator to next item, or the first item if
  43. /// this is the first call to MoveNext.
  44. /// </summary>
  45. /// <returns>True if enumerator is valid now</returns>
  46. public bool MoveNext() { return enumerator.MoveNext(); }
  47. /// <summary>
  48. /// Undefined if enumerator is not valid (MoveNext hash been called returning true)
  49. /// </summary>
  50. /// <value>The current item of the wrapped enumerator.</value>
  51. public T Current { get { return enumerator.Current; } }
  52. #endregion
  53. #region IDisposable Members
  54. //TODO: consider possible danger of calling through to Dispose.
  55. /// <summary>
  56. /// Dispose wrapped enumerator.
  57. /// </summary>
  58. public void Dispose() { enumerator.Dispose(); }
  59. #endregion
  60. #region IEnumerator Members
  61. object System.Collections.IEnumerator.Current
  62. {
  63. get { return enumerator.Current; }
  64. }
  65. void System.Collections.IEnumerator.Reset()
  66. {
  67. enumerator.Reset();
  68. }
  69. #endregion
  70. }
  71. /// <summary>
  72. /// A read-only wrapper class for a generic enumerable
  73. ///
  74. /// <i>This is mainly interesting as a base of other guard classes</i>
  75. /// </summary>
  76. public class GuardedEnumerable<T> : SCG.IEnumerable<T>
  77. {
  78. #region Fields
  79. SCG.IEnumerable<T> enumerable;
  80. #endregion
  81. #region Constructor
  82. /// <summary>
  83. /// Wrap an enumerable in a read-only wrapper
  84. /// </summary>
  85. /// <param name="enumerable">The enumerable to wrap</param>
  86. public GuardedEnumerable(SCG.IEnumerable<T> enumerable)
  87. { this.enumerable = enumerable; }
  88. #endregion
  89. #region SCG.IEnumerable<T> Members
  90. /// <summary>
  91. /// Get an enumerator from the wrapped enumerable
  92. /// </summary>
  93. /// <returns>The enumerator (itself wrapped)</returns>
  94. public SCG.IEnumerator<T> GetEnumerator()
  95. { return new GuardedEnumerator<T>(enumerable.GetEnumerator()); }
  96. #endregion
  97. #region IEnumerable Members
  98. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  99. {
  100. return GetEnumerator();
  101. }
  102. #endregion
  103. }
  104. /// <summary>
  105. /// A read-only wrapper for a generic directed enumerable
  106. ///
  107. /// <i>This is mainly interesting as a base of other guard classes</i>
  108. /// </summary>
  109. public class GuardedDirectedEnumerable<T> : GuardedEnumerable<T>, IDirectedEnumerable<T>
  110. {
  111. #region Fields
  112. IDirectedEnumerable<T> directedenumerable;
  113. #endregion
  114. #region Constructor
  115. /// <summary>
  116. /// Wrap a directed enumerable in a read-only wrapper
  117. /// </summary>
  118. /// <param name="directedenumerable">the collection to wrap</param>
  119. public GuardedDirectedEnumerable(IDirectedEnumerable<T> directedenumerable)
  120. : base(directedenumerable)
  121. { this.directedenumerable = directedenumerable; }
  122. #endregion
  123. #region IDirectedEnumerable<T> Members
  124. /// <summary>
  125. /// Get a enumerable that enumerates the wrapped collection in the opposite direction
  126. /// </summary>
  127. /// <returns>The mirrored enumerable</returns>
  128. public IDirectedEnumerable<T> Backwards()
  129. { return new GuardedDirectedEnumerable<T>(directedenumerable.Backwards()); }
  130. /// <summary>
  131. /// <code>Forwards</code> if same, else <code>Backwards</code>
  132. /// </summary>
  133. /// <value>The enumeration direction relative to the original collection.</value>
  134. public EnumerationDirection Direction
  135. { get { return directedenumerable.Direction; } }
  136. #endregion
  137. }
  138. /// <summary>
  139. /// A read-only wrapper for an ICollectionValue&lt;T&gt;
  140. ///
  141. /// <i>This is mainly interesting as a base of other guard classes</i>
  142. /// </summary>
  143. public class GuardedCollectionValue<T> : GuardedEnumerable<T>, ICollectionValue<T>
  144. {
  145. #region Events
  146. /// <summary>
  147. /// The ListenableEvents value of the wrapped collection
  148. /// </summary>
  149. /// <value></value>
  150. public virtual EventTypeEnum ListenableEvents { get { return collectionvalue.ListenableEvents; } }
  151. /// <summary>
  152. /// The ActiveEvents value of the wrapped collection
  153. /// </summary>
  154. /// <value></value>
  155. public virtual EventTypeEnum ActiveEvents { get { return collectionvalue.ActiveEvents; } }
  156. ProxyEventBlock<T> eventBlock;
  157. /// <summary>
  158. /// The change event. Will be raised for every change operation on the collection.
  159. /// </summary>
  160. public event CollectionChangedHandler<T> CollectionChanged
  161. {
  162. add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).CollectionChanged += value; }
  163. remove { if (eventBlock != null) eventBlock.CollectionChanged -= value; }
  164. }
  165. /// <summary>
  166. /// The change event. Will be raised for every change operation on the collection.
  167. /// </summary>
  168. public event CollectionClearedHandler<T> CollectionCleared
  169. {
  170. add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).CollectionCleared += value; }
  171. remove { if (eventBlock != null) eventBlock.CollectionCleared -= value; }
  172. }
  173. /// <summary>
  174. /// The item added event. Will be raised for every individual addition to the collection.
  175. /// </summary>
  176. public event ItemsAddedHandler<T> ItemsAdded
  177. {
  178. add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).ItemsAdded += value; }
  179. remove { if (eventBlock != null) eventBlock.ItemsAdded -= value; }
  180. }
  181. /// <summary>
  182. /// The item added event. Will be raised for every individual addition to the collection.
  183. /// </summary>
  184. public event ItemInsertedHandler<T> ItemInserted
  185. {
  186. add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).ItemInserted += value; }
  187. remove { if (eventBlock != null) eventBlock.ItemInserted -= value; }
  188. }
  189. /// <summary>
  190. /// The item removed event. Will be raised for every individual removal from the collection.
  191. /// </summary>
  192. public event ItemsRemovedHandler<T> ItemsRemoved
  193. {
  194. add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).ItemsRemoved += value; }
  195. remove { if (eventBlock != null) eventBlock.ItemsRemoved -= value; }
  196. }
  197. /// <summary>
  198. /// The item removed event. Will be raised for every individual removal from the collection.
  199. /// </summary>
  200. public event ItemRemovedAtHandler<T> ItemRemovedAt
  201. {
  202. add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).ItemRemovedAt += value; }
  203. remove { if (eventBlock != null) eventBlock.ItemRemovedAt -= value; }
  204. }
  205. #endregion
  206. #region Fields
  207. ICollectionValue<T> collectionvalue;
  208. #endregion
  209. #region Constructor
  210. /// <summary>
  211. /// Wrap a ICollectionValue&lt;T&gt; in a read-only wrapper
  212. /// </summary>
  213. /// <param name="collectionvalue">the collection to wrap</param>
  214. public GuardedCollectionValue(ICollectionValue<T> collectionvalue)
  215. : base(collectionvalue)
  216. { this.collectionvalue = collectionvalue; }
  217. #endregion
  218. #region ICollection<T> Members
  219. /// <summary>
  220. /// Get the size of the wrapped collection
  221. /// </summary>
  222. /// <value>The size</value>
  223. public virtual bool IsEmpty { get { return collectionvalue.IsEmpty; } }
  224. /// <summary>
  225. /// Get the size of the wrapped collection
  226. /// </summary>
  227. /// <value>The size</value>
  228. public virtual int Count { get { return collectionvalue.Count; } }
  229. /// <summary>
  230. /// The value is symbolic indicating the type of asymptotic complexity
  231. /// in terms of the size of this collection (worst-case or amortized as
  232. /// relevant).
  233. /// </summary>
  234. /// <value>A characterization of the speed of the
  235. /// <code>Count</code> property in this collection.</value>
  236. public virtual Speed CountSpeed { get { return collectionvalue.CountSpeed; } }
  237. /// <summary>
  238. /// Copy the items of the wrapped collection to an array
  239. /// </summary>
  240. /// <param name="a">The array</param>
  241. /// <param name="i">Starting offset</param>
  242. public virtual void CopyTo(T[] a, int i) { collectionvalue.CopyTo(a, i); }
  243. /// <summary>
  244. /// Create an array from the items of the wrapped collection
  245. /// </summary>
  246. /// <returns>The array</returns>
  247. public virtual T[] ToArray() { return collectionvalue.ToArray(); }
  248. /// <summary>
  249. /// Apply a delegate to all items of the wrapped enumerable.
  250. /// </summary>
  251. /// <param name="a">The delegate to apply</param>
  252. //TODO: change this to throw an exception?
  253. public virtual void Apply(Act<T> a) { collectionvalue.Apply(a); }
  254. /// <summary>
  255. /// Check if there exists an item that satisfies a
  256. /// specific predicate in the wrapped enumerable.
  257. /// </summary>
  258. /// <param name="filter">A filter delegate
  259. /// (<see cref="T:C5.Filter`1"/>) defining the predicate</param>
  260. /// <returns>True is such an item exists</returns>
  261. public virtual bool Exists(Fun<T, bool> filter) { return collectionvalue.Exists(filter); }
  262. /// <summary>
  263. ///
  264. /// </summary>
  265. /// <param name="filter"></param>
  266. /// <param name="item"></param>
  267. /// <returns></returns>
  268. public virtual bool Find(Fun<T, bool> filter, out T item) { return collectionvalue.Find(filter, out item); }
  269. /// <summary>
  270. /// Check if all items in the wrapped enumerable satisfies a specific predicate.
  271. /// </summary>
  272. /// <param name="filter">A filter delegate
  273. /// (<see cref="T:C5.Filter`1"/>) defining the predicate</param>
  274. /// <returns>True if all items satisfies the predicate</returns>
  275. public virtual bool All(Fun<T, bool> filter) { return collectionvalue.All(filter); }
  276. /// <summary>
  277. /// Create an enumerable, enumerating the items of this collection that satisfies
  278. /// a certain condition.
  279. /// </summary>
  280. /// <param name="filter">The T->bool filter delegate defining the condition</param>
  281. /// <returns>The filtered enumerable</returns>
  282. public virtual SCG.IEnumerable<T> Filter(Fun<T, bool> filter) { return collectionvalue.Filter(filter); }
  283. /// <summary>
  284. /// Choose some item of this collection.
  285. /// </summary>
  286. /// <exception cref="NoSuchItemException">if collection is empty.</exception>
  287. /// <returns></returns>
  288. public virtual T Choose() { return collectionvalue.Choose(); }
  289. #endregion
  290. #region IShowable Members
  291. /// <summary>
  292. ///
  293. /// </summary>
  294. /// <param name="stringbuilder"></param>
  295. /// <param name="formatProvider"></param>
  296. /// <param name="rest"></param>
  297. /// <returns></returns>
  298. public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
  299. {
  300. return collectionvalue.Show(stringbuilder, ref rest, formatProvider);
  301. }
  302. #endregion
  303. #region IFormattable Members
  304. /// <summary>
  305. ///
  306. /// </summary>
  307. /// <param name="format"></param>
  308. /// <param name="formatProvider"></param>
  309. /// <returns></returns>
  310. public string ToString(string format, IFormatProvider formatProvider)
  311. {
  312. return collectionvalue.ToString(format, formatProvider);
  313. }
  314. #endregion
  315. }
  316. /// <summary>
  317. /// A read-only wrapper for a directed collection
  318. ///
  319. /// <i>This is mainly interesting as a base of other guard classes</i>
  320. /// </summary>
  321. public class GuardedDirectedCollectionValue<T> : GuardedCollectionValue<T>, IDirectedCollectionValue<T>
  322. {
  323. #region Fields
  324. IDirectedCollectionValue<T> directedcollection;
  325. #endregion
  326. #region Constructor
  327. /// <summary>
  328. /// Wrap a directed collection in a read-only wrapper
  329. /// </summary>
  330. /// <param name="directedcollection">the collection to wrap</param>
  331. public GuardedDirectedCollectionValue(IDirectedCollectionValue<T> directedcollection)
  332. :
  333. base(directedcollection)
  334. { this.directedcollection = directedcollection; }
  335. #endregion
  336. #region IDirectedCollection<T> Members
  337. /// <summary>
  338. /// Get a collection that enumerates the wrapped collection in the opposite direction
  339. /// </summary>
  340. /// <returns>The mirrored collection</returns>
  341. public virtual IDirectedCollectionValue<T> Backwards()
  342. { return new GuardedDirectedCollectionValue<T>(directedcollection.Backwards()); }
  343. /// <summary>
  344. ///
  345. /// </summary>
  346. /// <param name="predicate"></param>
  347. /// <param name="item"></param>
  348. /// <returns></returns>
  349. public virtual bool FindLast(Fun<T, bool> predicate, out T item) { return directedcollection.FindLast(predicate, out item); }
  350. #endregion
  351. #region IDirectedEnumerable<T> Members
  352. IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()
  353. { return Backwards(); }
  354. /// <summary>
  355. /// <code>Forwards</code> if same, else <code>Backwards</code>
  356. /// </summary>
  357. /// <value>The enumeration direction relative to the original collection.</value>
  358. public EnumerationDirection Direction
  359. { get { return directedcollection.Direction; } }
  360. #endregion
  361. }
  362. /// <summary>
  363. /// A read-only wrapper for an <see cref="T:C5.ICollection`1"/>,
  364. /// <para>
  365. /// <i>Suitable for wrapping hash tables, <see cref="T:C5.HashSet`1"/>
  366. /// and <see cref="T:C5.HashBag`1"/> </i></para>
  367. /// </summary>
  368. public class GuardedCollection<T> : GuardedCollectionValue<T>, ICollection<T>
  369. {
  370. #region Fields
  371. ICollection<T> collection;
  372. #endregion
  373. #region Constructor
  374. /// <summary>
  375. /// Wrap an ICollection&lt;T&gt; in a read-only wrapper
  376. /// </summary>
  377. /// <param name="collection">the collection to wrap</param>
  378. public GuardedCollection(ICollection<T> collection)
  379. : base(collection)
  380. {
  381. this.collection = collection;
  382. }
  383. #endregion
  384. #region ICollection<T> Members
  385. /// <summary>
  386. /// (This is a read-only wrapper)
  387. /// </summary>
  388. /// <value>True</value>
  389. public virtual bool IsReadOnly { get { return true; } }
  390. /// <summary> </summary>
  391. /// <value>Speed of wrapped collection</value>
  392. public virtual Speed ContainsSpeed { get { return collection.ContainsSpeed; } }
  393. /// <summary>
  394. ///
  395. /// </summary>
  396. /// <returns></returns>
  397. public virtual int GetUnsequencedHashCode()
  398. { return collection.GetUnsequencedHashCode(); }
  399. /// <summary>
  400. ///
  401. /// </summary>
  402. /// <param name="that"></param>
  403. /// <returns></returns>
  404. public virtual bool UnsequencedEquals(ICollection<T> that)
  405. { return collection.UnsequencedEquals(that); }
  406. /// <summary>
  407. /// Check if an item is in the wrapped collection
  408. /// </summary>
  409. /// <param name="item">The item</param>
  410. /// <returns>True if found</returns>
  411. public virtual bool Contains(T item) { return collection.Contains(item); }
  412. /// <summary>
  413. /// Count the number of times an item appears in the wrapped collection
  414. /// </summary>
  415. /// <param name="item">The item</param>
  416. /// <returns>The number of copies</returns>
  417. public virtual int ContainsCount(T item) { return collection.ContainsCount(item); }
  418. /// <summary>
  419. ///
  420. /// </summary>
  421. /// <returns></returns>
  422. public virtual ICollectionValue<T> UniqueItems() { return new GuardedCollectionValue<T>(collection.UniqueItems()); }
  423. /// <summary>
  424. ///
  425. /// </summary>
  426. /// <returns></returns>
  427. public virtual ICollectionValue<KeyValuePair<T, int>> ItemMultiplicities() { return new GuardedCollectionValue<KeyValuePair<T, int>>(collection.ItemMultiplicities()); }
  428. /// <summary>
  429. /// Check if all items in the argument is in the wrapped collection
  430. /// </summary>
  431. /// <param name="items">The items</param>
  432. /// <typeparam name="U"></typeparam>
  433. /// <returns>True if so</returns>
  434. public virtual bool ContainsAll<U>(SCG.IEnumerable<U> items) where U : T { return collection.ContainsAll(items); }
  435. /// <summary>
  436. /// Search for an item in the wrapped collection
  437. /// </summary>
  438. /// <param name="item">On entry the item to look for, on exit the equivalent item found (if any)</param>
  439. /// <returns></returns>
  440. public virtual bool Find(ref T item) { return collection.Find(ref item); }
  441. /// <summary>
  442. /// </summary>
  443. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  444. /// <param name="item"></param>
  445. /// <returns></returns>
  446. public virtual bool FindOrAdd(ref T item)
  447. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  448. /// <summary>
  449. /// </summary>
  450. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  451. /// <param name="item"></param>
  452. /// <returns></returns>
  453. public virtual bool Update(T item)
  454. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  455. /// <summary>
  456. /// </summary>
  457. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  458. /// <param name="item"></param>
  459. /// <param name="olditem"></param>
  460. /// <returns></returns>
  461. public virtual bool Update(T item, out T olditem)
  462. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  463. /// <summary>
  464. /// </summary>
  465. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  466. /// <param name="item"></param>
  467. /// <returns></returns>
  468. public virtual bool UpdateOrAdd(T item)
  469. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  470. /// <summary>
  471. /// </summary>
  472. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  473. /// <param name="item"></param>
  474. /// <param name="olditem"></param>
  475. /// <returns></returns>
  476. public virtual bool UpdateOrAdd(T item, out T olditem)
  477. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  478. /// <summary>
  479. /// </summary>
  480. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  481. /// <param name="item"></param>
  482. /// <returns></returns>
  483. public virtual bool Remove(T item)
  484. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  485. /// <summary>
  486. /// </summary>
  487. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  488. /// <param name="item">The value to remove.</param>
  489. /// <param name="removeditem">The removed value.</param>
  490. /// <returns></returns>
  491. public virtual bool Remove(T item, out T removeditem)
  492. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  493. /// <summary>
  494. /// </summary>
  495. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  496. /// <param name="item"></param>
  497. public virtual void RemoveAllCopies(T item)
  498. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  499. /// <summary>
  500. /// </summary>
  501. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  502. /// <typeparam name="U"></typeparam>
  503. /// <param name="items"></param>
  504. public virtual void RemoveAll<U>(SCG.IEnumerable<U> items) where U : T
  505. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  506. /// <summary>
  507. /// </summary>
  508. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  509. public virtual void Clear()
  510. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  511. /// <summary>
  512. /// </summary>
  513. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  514. /// <typeparam name="U"></typeparam>
  515. /// <param name="items"></param>
  516. public virtual void RetainAll<U>(SCG.IEnumerable<U> items) where U : T
  517. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  518. /// <summary>
  519. /// Check wrapped collection for internal consistency
  520. /// </summary>
  521. /// <returns>True if check passed</returns>
  522. public virtual bool Check() { return collection.Check(); }
  523. #endregion
  524. #region IExtensible<T> Members
  525. /// <summary> </summary>
  526. /// <value>False if wrapped collection has set semantics</value>
  527. public virtual bool AllowsDuplicates { get { return collection.AllowsDuplicates; } }
  528. //TODO: the equalityComparer should be guarded
  529. /// <summary>
  530. ///
  531. /// </summary>
  532. /// <value></value>
  533. public virtual SCG.IEqualityComparer<T> EqualityComparer { get { return collection.EqualityComparer; } }
  534. /// <summary>
  535. /// By convention this is true for any collection with set semantics.
  536. /// </summary>
  537. /// <value>True if only one representative of a group of equal items
  538. /// is kept in the collection together with the total count.</value>
  539. public virtual bool DuplicatesByCounting { get { return collection.DuplicatesByCounting; } }
  540. /// <summary> </summary>
  541. /// <value>True if wrapped collection is empty</value>
  542. public override bool IsEmpty { get { return collection.IsEmpty; } }
  543. /// <summary>
  544. /// </summary>
  545. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  546. /// <param name="item"></param>
  547. /// <returns></returns>
  548. public virtual bool Add(T item)
  549. { throw new ReadOnlyCollectionException(); }
  550. /// <summary>
  551. /// </summary>
  552. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  553. /// <param name="item"></param>
  554. void SCG.ICollection<T>.Add(T item)
  555. { throw new ReadOnlyCollectionException(); }
  556. /// <summary>
  557. /// </summary>
  558. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  559. /// <typeparam name="U"></typeparam>
  560. /// <param name="items"></param>
  561. public virtual void AddAll<U>(SCG.IEnumerable<U> items) where U : T
  562. { throw new ReadOnlyCollectionException(); }
  563. #endregion
  564. #region ICloneable Members
  565. /// <summary>
  566. ///
  567. /// </summary>
  568. /// <returns></returns>
  569. public virtual object Clone()
  570. {
  571. return new GuardedCollection<T>((ICollection<T>)(collection.Clone()));
  572. }
  573. #endregion
  574. }
  575. /// <summary>
  576. /// A read-only wrapper for a sequenced collection
  577. ///
  578. /// <i>This is mainly interesting as a base of other guard classes</i>
  579. /// </summary>
  580. public class GuardedSequenced<T> : GuardedCollection<T>, ISequenced<T>
  581. {
  582. #region Fields
  583. ISequenced<T> sequenced;
  584. #endregion
  585. #region Constructor
  586. /// <summary>
  587. /// Wrap a sequenced collection in a read-only wrapper
  588. /// </summary>
  589. /// <param name="sorted"></param>
  590. public GuardedSequenced(ISequenced<T> sorted) : base(sorted) { this.sequenced = sorted; }
  591. #endregion
  592. /// <summary>
  593. /// Check if there exists an item that satisfies a
  594. /// specific predicate in this collection and return the index of the first one.
  595. /// </summary>
  596. /// <param name="predicate">A delegate
  597. /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>
  598. /// <returns>the index, if found, a negative value else</returns>
  599. public int FindIndex(Fun<T, bool> predicate)
  600. {
  601. IIndexed<T> indexed = sequenced as IIndexed<T>;
  602. if (indexed != null)
  603. return indexed.FindIndex(predicate);
  604. int index = 0;
  605. foreach (T item in this)
  606. {
  607. if (predicate(item))
  608. return index;
  609. index++;
  610. }
  611. return -1;
  612. }
  613. /// <summary>
  614. /// Check if there exists an item that satisfies a
  615. /// specific predicate in this collection and return the index of the last one.
  616. /// </summary>
  617. /// <param name="predicate">A delegate
  618. /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>
  619. /// <returns>the index, if found, a negative value else</returns>
  620. public int FindLastIndex(Fun<T, bool> predicate)
  621. {
  622. IIndexed<T> indexed = sequenced as IIndexed<T>;
  623. if (indexed != null)
  624. return indexed.FindLastIndex(predicate);
  625. int index = Count - 1;
  626. foreach (T item in Backwards())
  627. {
  628. if (predicate(item))
  629. return index;
  630. index--;
  631. }
  632. return -1;
  633. }
  634. #region ISequenced<T> Members
  635. /// <summary>
  636. ///
  637. /// </summary>
  638. /// <returns></returns>
  639. public int GetSequencedHashCode()
  640. { return sequenced.GetSequencedHashCode(); }
  641. /// <summary>
  642. ///
  643. /// </summary>
  644. /// <param name="that"></param>
  645. /// <returns></returns>
  646. public bool SequencedEquals(ISequenced<T> that)
  647. { return sequenced.SequencedEquals(that); }
  648. #endregion
  649. #region IDirectedCollection<T> Members
  650. /// <summary>
  651. /// Get a collection that enumerates the wrapped collection in the opposite direction
  652. /// </summary>
  653. /// <returns>The mirrored collection</returns>
  654. public virtual IDirectedCollectionValue<T> Backwards()
  655. { return new GuardedDirectedCollectionValue<T>(sequenced.Backwards()); }
  656. /// <summary>
  657. ///
  658. /// </summary>
  659. /// <param name="predicate"></param>
  660. /// <param name="item"></param>
  661. /// <returns></returns>
  662. public virtual bool FindLast(Fun<T, bool> predicate, out T item) { return sequenced.FindLast(predicate, out item); }
  663. #endregion
  664. #region IDirectedEnumerable<T> Members
  665. IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()
  666. { return Backwards(); }
  667. /// <summary>
  668. /// <code>Forwards</code> if same, else <code>Backwards</code>
  669. /// </summary>
  670. /// <value>The enumeration direction relative to the original collection.</value>
  671. public EnumerationDirection Direction
  672. { get { return EnumerationDirection.Forwards; } }
  673. #endregion
  674. #region ICloneable Members
  675. /// <summary>
  676. ///
  677. /// </summary>
  678. /// <returns></returns>
  679. public override object Clone()
  680. {
  681. return new GuardedCollection<T>((ISequenced<T>)(sequenced.Clone()));
  682. }
  683. #endregion
  684. }
  685. /// <summary>
  686. /// A read-only wrapper for a sorted collection
  687. ///
  688. /// <i>This is mainly interesting as a base of other guard classes</i>
  689. /// </summary>
  690. public class GuardedSorted<T> : GuardedSequenced<T>, ISorted<T>
  691. {
  692. #region Fields
  693. ISorted<T> sorted;
  694. #endregion
  695. #region Constructor
  696. /// <summary>
  697. /// Wrap a sorted collection in a read-only wrapper
  698. /// </summary>
  699. /// <param name="sorted"></param>
  700. public GuardedSorted(ISorted<T> sorted) : base(sorted) { this.sorted = sorted; }
  701. #endregion
  702. #region ISorted<T> Members
  703. /// <summary>
  704. /// Find the strict predecessor of item in the guarded sorted collection,
  705. /// that is, the greatest item in the collection smaller than the item.
  706. /// </summary>
  707. /// <param name="item">The item to find the predecessor for.</param>
  708. /// <param name="res">The predecessor, if any; otherwise the default value for T.</param>
  709. /// <returns>True if item has a predecessor; otherwise false.</returns>
  710. public bool TryPredecessor(T item, out T res) { return sorted.TryPredecessor(item, out res); }
  711. /// <summary>
  712. /// Find the strict successor of item in the guarded sorted collection,
  713. /// that is, the least item in the collection greater than the supplied value.
  714. /// </summary>
  715. /// <param name="item">The item to find the successor for.</param>
  716. /// <param name="res">The successor, if any; otherwise the default value for T.</param>
  717. /// <returns>True if item has a successor; otherwise false.</returns>
  718. public bool TrySuccessor(T item, out T res) { return sorted.TrySuccessor(item, out res); }
  719. /// <summary>
  720. /// Find the weak predecessor of item in the guarded sorted collection,
  721. /// that is, the greatest item in the collection smaller than or equal to the item.
  722. /// </summary>
  723. /// <param name="item">The item to find the weak predecessor for.</param>
  724. /// <param name="res">The weak predecessor, if any; otherwise the default value for T.</param>
  725. /// <returns>True if item has a weak predecessor; otherwise false.</returns>
  726. public bool TryWeakPredecessor(T item, out T res) { return sorted.TryWeakPredecessor(item, out res); }
  727. /// <summary>
  728. /// Find the weak successor of item in the sorted collection,
  729. /// that is, the least item in the collection greater than or equal to the supplied value.
  730. /// </summary>
  731. /// <param name="item">The item to find the weak successor for.</param>
  732. /// <param name="res">The weak successor, if any; otherwise the default value for T.</param>
  733. /// <returns>True if item has a weak successor; otherwise false.</returns>
  734. public bool TryWeakSuccessor(T item, out T res) { return sorted.TryWeakSuccessor(item, out res); }
  735. /// <summary>
  736. /// Find the predecessor of the item in the wrapped sorted collection
  737. /// </summary>
  738. /// <exception cref="NoSuchItemException"> if no such element exists </exception>
  739. /// <param name="item">The item</param>
  740. /// <returns>The predecessor</returns>
  741. public T Predecessor(T item) { return sorted.Predecessor(item); }
  742. /// <summary>
  743. /// Find the Successor of the item in the wrapped sorted collection
  744. /// </summary>
  745. /// <exception cref="NoSuchItemException"> if no such element exists </exception>
  746. /// <param name="item">The item</param>
  747. /// <returns>The Successor</returns>
  748. public T Successor(T item) { return sorted.Successor(item); }
  749. /// <summary>
  750. /// Find the weak predecessor of the item in the wrapped sorted collection
  751. /// </summary>
  752. /// <exception cref="NoSuchItemException"> if no such element exists </exception>
  753. /// <param name="item">The item</param>
  754. /// <returns>The weak predecessor</returns>
  755. public T WeakPredecessor(T item) { return sorted.WeakPredecessor(item); }
  756. /// <summary>
  757. /// Find the weak Successor of the item in the wrapped sorted collection
  758. /// </summary>
  759. /// <exception cref="NoSuchItemException"> if no such element exists </exception>
  760. /// <param name="item">The item</param>
  761. /// <returns>The weak Successor</returns>
  762. public T WeakSuccessor(T item) { return sorted.WeakSuccessor(item); }
  763. /// <summary>
  764. /// Run Cut on the wrapped sorted collection
  765. /// </summary>
  766. /// <param name="c"></param>
  767. /// <param name="low"></param>
  768. /// <param name="lval"></param>
  769. /// <param name="high"></param>
  770. /// <param name="hval"></param>
  771. /// <returns></returns>
  772. public bool Cut(IComparable<T> c, out T low, out bool lval, out T high, out bool hval)
  773. { return sorted.Cut(c, out low, out lval, out high, out hval); }
  774. /// <summary>
  775. /// Get the specified range from the wrapped collection.
  776. /// (The current implementation erroneously does not wrap the result.)
  777. /// </summary>
  778. /// <param name="bot"></param>
  779. /// <returns></returns>
  780. public IDirectedEnumerable<T> RangeFrom(T bot) { return sorted.RangeFrom(bot); }
  781. /// <summary>
  782. /// Get the specified range from the wrapped collection.
  783. /// (The current implementation erroneously does not wrap the result.)
  784. /// </summary>
  785. /// <param name="bot"></param>
  786. /// <param name="top"></param>
  787. /// <returns></returns>
  788. public IDirectedEnumerable<T> RangeFromTo(T bot, T top)
  789. { return sorted.RangeFromTo(bot, top); }
  790. /// <summary>
  791. /// Get the specified range from the wrapped collection.
  792. /// (The current implementation erroneously does not wrap the result.)
  793. /// </summary>
  794. /// <param name="top"></param>
  795. /// <returns></returns>
  796. public IDirectedEnumerable<T> RangeTo(T top) { return sorted.RangeTo(top); }
  797. /// <summary>
  798. /// Get the specified range from the wrapped collection.
  799. /// (The current implementation erroneously does not wrap the result.)
  800. /// </summary>
  801. /// <returns></returns>
  802. public IDirectedCollectionValue<T> RangeAll() { return sorted.RangeAll(); }
  803. /// <summary>
  804. /// </summary>
  805. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  806. /// <param name="items"></param>
  807. /// <typeparam name="U"></typeparam>
  808. public void AddSorted<U>(SCG.IEnumerable<U> items) where U : T
  809. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  810. /// <summary>
  811. /// </summary>
  812. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  813. /// <param name="low"></param>
  814. public void RemoveRangeFrom(T low)
  815. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  816. /// <summary>
  817. /// </summary>
  818. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  819. /// <param name="low"></param>
  820. /// <param name="hi"></param>
  821. public void RemoveRangeFromTo(T low, T hi)
  822. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  823. /// <summary>
  824. /// </summary>
  825. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  826. /// <param name="hi"></param>
  827. public void RemoveRangeTo(T hi)
  828. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  829. #endregion
  830. #region IPriorityQueue<T> Members
  831. /// <summary>
  832. /// Find the minimum of the wrapped collection
  833. /// </summary>
  834. /// <returns>The minimum</returns>
  835. public T FindMin() { return sorted.FindMin(); }
  836. /// <summary>
  837. /// </summary>
  838. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  839. /// <returns></returns>
  840. public T DeleteMin()
  841. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  842. /// <summary>
  843. /// Find the maximum of the wrapped collection
  844. /// </summary>
  845. /// <returns>The maximum</returns>
  846. public T FindMax() { return sorted.FindMax(); }
  847. /// <summary>
  848. /// </summary>
  849. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  850. /// <returns></returns>
  851. public T DeleteMax()
  852. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  853. //TODO: we should guard the comparer!
  854. /// <summary>
  855. /// The comparer object supplied at creation time for the underlying collection
  856. /// </summary>
  857. /// <value>The comparer</value>
  858. public SCG.IComparer<T> Comparer { get { return sorted.Comparer; } }
  859. #endregion
  860. #region IDirectedEnumerable<T> Members
  861. IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()
  862. { return Backwards(); }
  863. #endregion
  864. /// <summary>
  865. ///
  866. /// </summary>
  867. /// <returns></returns>
  868. public override object Clone()
  869. {
  870. return new GuardedSorted<T>((ISorted<T>)(sorted.Clone()));
  871. }
  872. }
  873. /// <summary>
  874. /// Read-only wrapper for indexed sorted collections
  875. ///
  876. /// <i>Suitable for wrapping TreeSet, TreeBag and SortedArray</i>
  877. /// </summary>
  878. public class GuardedIndexedSorted<T> : GuardedSorted<T>, IIndexedSorted<T>
  879. {
  880. #region Fields
  881. IIndexedSorted<T> indexedsorted;
  882. #endregion
  883. #region Constructor
  884. /// <summary>
  885. /// Wrap an indexed sorted collection in a read-only wrapper
  886. /// </summary>
  887. /// <param name="list">the indexed sorted collection</param>
  888. public GuardedIndexedSorted(IIndexedSorted<T> list)
  889. : base(list)
  890. { this.indexedsorted = list; }
  891. #endregion
  892. #region IIndexedSorted<T> Members
  893. /// <summary>
  894. /// Get the specified range from the wrapped collection.
  895. /// (The current implementation erroneously does not wrap the result.)
  896. /// </summary>
  897. /// <param name="bot"></param>
  898. /// <returns></returns>
  899. public new IDirectedCollectionValue<T> RangeFrom(T bot)
  900. { return indexedsorted.RangeFrom(bot); }
  901. /// <summary>
  902. /// Get the specified range from the wrapped collection.
  903. /// (The current implementation erroneously does not wrap the result.)
  904. /// </summary>
  905. /// <param name="bot"></param>
  906. /// <param name="top"></param>
  907. /// <returns></returns>
  908. public new IDirectedCollectionValue<T> RangeFromTo(T bot, T top)
  909. { return indexedsorted.RangeFromTo(bot, top); }
  910. /// <summary>
  911. /// Get the specified range from the wrapped collection.
  912. /// (The current implementation erroneously does not wrap the result.)
  913. /// </summary>
  914. /// <param name="top"></param>
  915. /// <returns></returns>
  916. public new IDirectedCollectionValue<T> RangeTo(T top)
  917. { return indexedsorted.RangeTo(top); }
  918. /// <summary>
  919. /// Report the number of items in the specified range of the wrapped collection
  920. /// </summary>
  921. /// <param name="bot"></param>
  922. /// <returns></returns>
  923. public int CountFrom(T bot) { return indexedsorted.CountFrom(bot); }
  924. /// <summary>
  925. /// Report the number of items in the specified range of the wrapped collection
  926. /// </summary>
  927. /// <param name="bot"></param>
  928. /// <param name="top"></param>
  929. /// <returns></returns>
  930. public int CountFromTo(T bot, T top) { return indexedsorted.CountFromTo(bot, top); }
  931. /// <summary>
  932. /// Report the number of items in the specified range of the wrapped collection
  933. /// </summary>
  934. /// <param name="top"></param>
  935. /// <returns></returns>
  936. public int CountTo(T top) { return indexedsorted.CountTo(top); }
  937. /// <summary>
  938. /// Run FindAll on the wrapped collection with the indicated filter.
  939. /// The result will <b>not</b> be read-only.
  940. /// </summary>
  941. /// <param name="f"></param>
  942. /// <returns></returns>
  943. public IIndexedSorted<T> FindAll(Fun<T, bool> f)
  944. { return indexedsorted.FindAll(f); }
  945. /// <summary>
  946. /// Run Map on the wrapped collection with the indicated mapper.
  947. /// The result will <b>not</b> be read-only.
  948. /// </summary>
  949. /// <param name="m"></param>
  950. /// <param name="c">The comparer to use in the result</param>
  951. /// <returns></returns>
  952. public IIndexedSorted<V> Map<V>(Fun<T, V> m, SCG.IComparer<V> c)
  953. { return indexedsorted.Map(m, c); }
  954. #endregion
  955. #region IIndexed<T> Members
  956. /// <summary>
  957. ///
  958. /// </summary>
  959. /// <value>The i'th item of the wrapped sorted collection</value>
  960. public T this[int i] { get { return indexedsorted[i]; } }
  961. /// <summary>
  962. ///
  963. /// </summary>
  964. /// <value></value>
  965. public virtual Speed IndexingSpeed { get { return indexedsorted.IndexingSpeed; } }
  966. /// <summary> </summary>
  967. /// <value>A directed collection of the items in the indicated interval of the wrapped collection</value>
  968. public IDirectedCollectionValue<T> this[int start, int end]
  969. { get { return new GuardedDirectedCollectionValue<T>(indexedsorted[start, end]); } }
  970. /// <summary>
  971. /// Find the (first) index of an item in the wrapped collection
  972. /// </summary>
  973. /// <param name="item"></param>
  974. /// <returns></returns>
  975. public int IndexOf(T item) { return indexedsorted.IndexOf(item); }
  976. /// <summary>
  977. /// Find the last index of an item in the wrapped collection
  978. /// </summary>
  979. /// <param name="item"></param>
  980. /// <returns></returns>
  981. public int LastIndexOf(T item) { return indexedsorted.LastIndexOf(item); }
  982. /// <summary>
  983. /// </summary>
  984. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  985. /// <param name="i"></param>
  986. /// <returns></returns>
  987. public T RemoveAt(int i)
  988. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  989. /// <summary>
  990. /// </summary>
  991. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  992. /// <param name="start"></param>
  993. /// <param name="count"></param>
  994. public void RemoveInterval(int start, int count)
  995. { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
  996. #endregion
  997. #region IDirectedEnumerable<T> Members
  998. IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()
  999. { return Backwards(); }
  1000. #endregion
  1001. /// <summary>
  1002. ///
  1003. /// </summary>
  1004. /// <returns></returns>
  1005. public override object Clone()
  1006. {
  1007. return new GuardedIndexedSorted<T>((IIndexedSorted<T>)(indexedsorted.Clone()));
  1008. }
  1009. }
  1010. /// <summary>
  1011. /// A read-only wrapper for a generic list collection
  1012. /// <i>Suitable as a wrapper for LinkedList, HashedLinkedList, ArrayList and HashedArray.
  1013. /// <see cref="T:C5.LinkedList`1"/>,
  1014. /// <see cref="T:C5.HashedLinkedList`1"/>,
  1015. /// <see cref="T:C5.ArrayList`1"/> or
  1016. /// <see cref="T:C5.HashedArray`1"/>.
  1017. /// </i>
  1018. /// </summary>
  1019. public class GuardedList<T> : GuardedSequenced<T>, IList<T>, SCG.IList<T>
  1020. {
  1021. #region Fields
  1022. IList<T> innerlist;
  1023. GuardedList<T> underlying;
  1024. bool slidableView = false;
  1025. #endregion
  1026. #region Constructor
  1027. /// <summary>
  1028. /// Wrap a list in a read-only wrapper. A list gets wrapped as read-only,
  1029. /// a list view gets wrapped as read-only and non-slidable.
  1030. /// </summary>
  1031. /// <param name="list">The list</param>
  1032. public GuardedList(IList<T> list)
  1033. : base(list)
  1034. {
  1035. this.innerlist = list;
  1036. // If wrapping a list view, make innerlist = the view, and make
  1037. // underlying = a guarded version of the view's underlying list
  1038. if (list.Underlying != null)
  1039. underlying = new GuardedList<T>(list.Underlying, null, false);
  1040. }
  1041. GuardedList(IList<T> list, GuardedList<T> underlying, bool slidableView)
  1042. : base(list)
  1043. {
  1044. this.innerlist = list; this.underlying = underlying; this.slidableView = slidableView;
  1045. }
  1046. #endregion
  1047. #region IList<T> Members
  1048. /// <summary>
  1049. ///
  1050. /// </summary>
  1051. /// <value>The first item of the wrapped list</value>
  1052. public T First { get { return innerlist.First; } }
  1053. /// <summary>
  1054. ///
  1055. /// </summary>
  1056. /// <value>The last item of the wrapped list</value>
  1057. public T Last { get { return innerlist.Last; } }
  1058. /// <summary>
  1059. /// </summary>
  1060. /// <exception cref="ReadOnlyCollectionException"> if used as setter</exception>
  1061. /// <value>True if wrapped list has FIFO semantics for the Add(T item) and Remove() methods</value>
  1062. public bool FIFO
  1063. {
  1064. get { return innerlist.FIFO; }
  1065. set { throw new ReadOnlyCollectionException("List is read only"); }
  1066. }
  1067. /// <summary>
  1068. ///
  1069. /// </summary>
  1070. public virtual bool IsFixedSize
  1071. {
  1072. get { return true; }
  1073. }
  1074. /// <summary>
  1075. /// </summary>
  1076. /// <exception cref="ReadOnlyCollectionException"> if used as setter</exception>
  1077. /// <value>The i'th item of the wrapped list</value>
  1078. public T this[int i]
  1079. {
  1080. get { return innerlist[i]; }
  1081. set { throw new ReadOnlyCollectionException("List is read only"); }
  1082. }
  1083. /// <summary>
  1084. ///
  1085. /// </summary>
  1086. /// <value></value>
  1087. public virtual Speed IndexingSpeed { get { return innerlist.IndexingSpeed; } }
  1088. /// <summary>
  1089. /// </summary>
  1090. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  1091. /// <param name="index"></param>
  1092. /// <param name="item"></param>
  1093. public void Insert(int index, T item)
  1094. { throw new ReadOnlyCollectionException(); }
  1095. /// <summary>
  1096. /// </summary>
  1097. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  1098. /// <param name="pointer"></param>
  1099. /// <param name="item"></param>
  1100. public void Insert(IList<T> pointer, T item)
  1101. { throw new ReadOnlyCollectionException(); }
  1102. /// <summary>
  1103. /// </summary>
  1104. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  1105. /// <param name="item"></param>
  1106. public void InsertFirst(T item)
  1107. { throw new ReadOnlyCollectionException("List is read only"); }
  1108. /// <summary>
  1109. /// </summary>
  1110. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  1111. /// <param name="item"></param>
  1112. public void InsertLast(T item)
  1113. { throw new ReadOnlyCollectionException("List is read only"); }
  1114. /// <summary>
  1115. /// </summary>
  1116. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  1117. /// <param name="item"></param>
  1118. /// <param name="target"></param>
  1119. public void InsertBefore(T item, T target)
  1120. { throw new ReadOnlyCollectionException("List is read only"); }
  1121. /// <summary>
  1122. /// </summary>
  1123. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  1124. /// <param name="item"></param>
  1125. /// <param name="target"></param>
  1126. public void InsertAfter(T item, T target)
  1127. { throw new ReadOnlyCollectionException("List is read only"); }
  1128. /// <summary>
  1129. /// </summary>
  1130. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  1131. /// <param name="i"></param>
  1132. /// <param name="items"></param>
  1133. public void InsertAll<U>(int i, SCG.IEnumerable<U> items) where U : T
  1134. { throw new ReadOnlyCollectionException("List is read only"); }
  1135. /// <summary>
  1136. /// Perform FindAll on the wrapped list. The result is <b>not</b> necessarily read-only.
  1137. /// </summary>
  1138. /// <param name="filter">The filter to use</param>
  1139. /// <returns></returns>
  1140. public IList<T> FindAll(Fun<T, bool> filter) { return innerlist.FindAll(filter); }
  1141. /// <summary>
  1142. /// Perform Map on the wrapped list. The result is <b>not</b> necessarily read-only.
  1143. /// </summary>
  1144. /// <typeparam name="V">The type of items of the new list</typeparam>
  1145. /// <param name="mapper">The mapper to use.</param>
  1146. /// <returns>The mapped list</returns>
  1147. public IList<V> Map<V>(Fun<T, V> mapper) { return innerlist.Map(mapper); }
  1148. /// <summary>
  1149. /// Perform Map on the wrapped list. The result is <b>not</b> necessarily read-only.
  1150. /// </summary>
  1151. /// <typeparam name="V">The type of items of the new list</typeparam>
  1152. /// <param name="mapper">The delegate defining the map.</param>
  1153. /// <param name="itemequalityComparer">The itemequalityComparer to use for the new list</param>
  1154. /// <returns>The new list.</returns>
  1155. public IList<V> Map<V>(Fun<T, V> mapper, SCG.IEqualityComparer<V> itemequalityComparer) { return innerlist.Map(mapper, itemequalityComparer); }
  1156. /// <summary>
  1157. /// </summary>
  1158. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  1159. /// <returns></returns>
  1160. public T Remove() { throw new ReadOnlyCollectionException("List is read only"); }
  1161. /// <summary>
  1162. /// </summary>
  1163. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  1164. /// <returns></returns>
  1165. public T RemoveFirst() { throw new ReadOnlyCollectionException("List is read only"); }
  1166. /// <summary>
  1167. /// </summary>
  1168. /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
  1169. /// <returns></returns>
  1170. public T RemoveLast() { throw new ReadOnlyCollectionException("List is read only"); }
  1171. /// <summary>
  1172. /// Create the indicated view on the wrapped list and wrap it read-only.
  1173. /// </summary>
  1174. /// <param name="start"></param>
  1175. /// <param name="count"></param>
  1176. /// <returns></returns>
  1177. public IList<T> View(int start, int count)
  1178. {
  1179. IList<T> view =

Large files files are truncated, but you can click here to view the full file