PageRenderTime 59ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/System/System.Collections.Generic/LinkedList.cs

https://bitbucket.org/cosi2/dotnetanywhere-wb
C# | 713 lines | 579 code | 57 blank | 77 comment | 102 complexity | 7b58b09e41e4491ac4f502875716a1ad MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Collections;
  5. #if !LOCALTEST
  6. namespace System.Collections.Generic
  7. {
  8. public struct ListEnumerator<T> : IEnumerator<T>, IDisposable, IEnumerator
  9. {
  10. private LinkedList<T> list;
  11. private LinkedListNode<T> node;
  12. private int version;
  13. private T current;
  14. private int index;
  15. internal ListEnumerator(LinkedList<T> list)
  16. {
  17. this.list = list;
  18. this.version = list.version;
  19. this.node = list.head;
  20. this.current = default(T);
  21. this.index = 0;
  22. }
  23. public T Current
  24. {
  25. get
  26. {
  27. return this.current;
  28. }
  29. }
  30. object IEnumerator.Current
  31. {
  32. get
  33. {
  34. if ((this.index == 0) || (this.index == (this.list.Count + 1)))
  35. {
  36. throw new InvalidOperationException();
  37. // ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
  38. }
  39. return this.current;
  40. }
  41. }
  42. public bool MoveNext()
  43. {
  44. if (this.version != this.list.version)
  45. {
  46. throw new InvalidOperationException();
  47. // throw new InvalidOperationException(SR.GetString(0x43, new object[0]));
  48. }
  49. if (this.node == null)
  50. {
  51. this.index = this.list.Count + 1;
  52. return false;
  53. }
  54. this.index++;
  55. this.current = this.node.item;
  56. this.node = this.node.next;
  57. if (this.node == this.list.head)
  58. {
  59. this.node = null;
  60. }
  61. return true;
  62. }
  63. void IEnumerator.Reset()
  64. {
  65. if (this.version != this.list.version)
  66. {
  67. throw new InvalidOperationException();
  68. // throw new InvalidOperationException(SR.GetString(0x43, new object[0]));
  69. }
  70. this.current = default(T);
  71. this.node = this.list.head;
  72. this.index = 0;
  73. }
  74. public void Dispose()
  75. {
  76. }
  77. }
  78. public sealed class LinkedListNode<T>
  79. {
  80. internal T item;
  81. internal LinkedList<T> list;
  82. internal LinkedListNode<T> next;
  83. internal LinkedListNode<T> prev;
  84. public LinkedListNode(T value)
  85. {
  86. this.item = value;
  87. }
  88. internal LinkedListNode(LinkedList<T> list, T value)
  89. {
  90. this.list = list;
  91. this.item = value;
  92. }
  93. internal void Invalidate()
  94. {
  95. this.list = null;
  96. this.next = null;
  97. this.prev = null;
  98. }
  99. public LinkedList<T> List
  100. {
  101. get
  102. {
  103. return this.list;
  104. }
  105. }
  106. public LinkedListNode<T> Next
  107. {
  108. get
  109. {
  110. if ((this.next != null) && (this.next != this.list.head))
  111. {
  112. return this.next;
  113. }
  114. return null;
  115. }
  116. }
  117. public LinkedListNode<T> Previous
  118. {
  119. get
  120. {
  121. if ((this.prev != null) && (this != this.list.head))
  122. {
  123. return this.prev;
  124. }
  125. return null;
  126. }
  127. }
  128. public T Value
  129. {
  130. get
  131. {
  132. return this.item;
  133. }
  134. set
  135. {
  136. this.item = value;
  137. }
  138. }
  139. }
  140. public class LinkedList<T> : ICollection<T>, IEnumerable<T>, ICollection, IEnumerable
  141. {
  142. private object _syncRoot;
  143. internal int count;
  144. internal LinkedListNode<T> head;
  145. internal int version;
  146. public LinkedList()
  147. {
  148. }
  149. public LinkedList(IEnumerable<T> collection)
  150. {
  151. if (collection == null)
  152. {
  153. throw new ArgumentNullException("collection");
  154. }
  155. foreach (T local in collection)
  156. {
  157. this.AddLast(local);
  158. }
  159. }
  160. public void AddAfter(LinkedListNode<T> node, LinkedListNode<T> newNode)
  161. {
  162. this.ValidateNode(node);
  163. this.ValidateNewNode(newNode);
  164. this.InternalInsertNodeBefore(node.next, newNode);
  165. newNode.list = (LinkedList<T>)this;
  166. }
  167. public LinkedListNode<T> AddAfter(LinkedListNode<T> node, T value)
  168. {
  169. this.ValidateNode(node);
  170. LinkedListNode<T> newNode = new LinkedListNode<T>(node.list, value);
  171. this.InternalInsertNodeBefore(node.next, newNode);
  172. return newNode;
  173. }
  174. public void AddBefore(LinkedListNode<T> node, LinkedListNode<T> newNode)
  175. {
  176. this.ValidateNode(node);
  177. this.ValidateNewNode(newNode);
  178. this.InternalInsertNodeBefore(node, newNode);
  179. newNode.list = (LinkedList<T>)this;
  180. if (node == this.head)
  181. {
  182. this.head = newNode;
  183. }
  184. }
  185. public LinkedListNode<T> AddBefore(LinkedListNode<T> node, T value)
  186. {
  187. this.ValidateNode(node);
  188. LinkedListNode<T> newNode = new LinkedListNode<T>(node.list, value);
  189. this.InternalInsertNodeBefore(node, newNode);
  190. if (node == this.head)
  191. {
  192. this.head = newNode;
  193. }
  194. return newNode;
  195. }
  196. public void AddFirst(LinkedListNode<T> node)
  197. {
  198. this.ValidateNewNode(node);
  199. if (this.head == null)
  200. {
  201. this.InternalInsertNodeToEmptyList(node);
  202. }
  203. else
  204. {
  205. this.InternalInsertNodeBefore(this.head, node);
  206. this.head = node;
  207. }
  208. node.list = (LinkedList<T>)this;
  209. }
  210. public LinkedListNode<T> AddFirst(T value)
  211. {
  212. LinkedListNode<T> newNode = new LinkedListNode<T>((LinkedList<T>)this, value);
  213. if (this.head == null)
  214. {
  215. this.InternalInsertNodeToEmptyList(newNode);
  216. return newNode;
  217. }
  218. this.InternalInsertNodeBefore(this.head, newNode);
  219. this.head = newNode;
  220. return newNode;
  221. }
  222. public LinkedListNode<T> AddLast(T value)
  223. {
  224. LinkedListNode<T> newNode = new LinkedListNode<T>((LinkedList<T>)this, value);
  225. if (this.head == null)
  226. {
  227. this.InternalInsertNodeToEmptyList(newNode);
  228. return newNode;
  229. }
  230. this.InternalInsertNodeBefore(this.head, newNode);
  231. return newNode;
  232. }
  233. public void AddLast(LinkedListNode<T> node)
  234. {
  235. this.ValidateNewNode(node);
  236. if (this.head == null)
  237. {
  238. this.InternalInsertNodeToEmptyList(node);
  239. }
  240. else
  241. {
  242. this.InternalInsertNodeBefore(this.head, node);
  243. }
  244. node.list = (LinkedList<T>)this;
  245. }
  246. public void Clear()
  247. {
  248. LinkedListNode<T> head = this.head;
  249. while (head != null)
  250. {
  251. LinkedListNode<T> node2 = head;
  252. head = head.Next;
  253. node2.Invalidate();
  254. }
  255. this.head = null;
  256. this.count = 0;
  257. this.version++;
  258. }
  259. public bool Contains(T value)
  260. {
  261. return (this.Find(value) != null);
  262. }
  263. public void CopyTo(T[] array, int index)
  264. {
  265. if (array == null)
  266. {
  267. throw new ArgumentException();
  268. // throw new ArgumentNullException("array");
  269. }
  270. if ((index < 0) || (index > array.Length))
  271. {
  272. throw new ArgumentException();
  273. // throw new ArgumentOutOfRangeException("index", SR.GetString(0x8e, new object[] { index }));
  274. }
  275. if ((array.Length - index) < this.Count)
  276. {
  277. throw new ArgumentException();
  278. // throw new ArgumentException(SR.GetString(0x8f, new object[0]));
  279. }
  280. LinkedListNode<T> head = this.head;
  281. if (head != null)
  282. {
  283. do
  284. {
  285. array[index++] = head.item;
  286. head = head.next;
  287. }
  288. while (head != this.head);
  289. }
  290. }
  291. public LinkedListNode<T> Find(T value)
  292. {
  293. LinkedListNode<T> head = this.head;
  294. EqualityComparer<T> comparer = EqualityComparer<T>.Default;
  295. if (head != null)
  296. {
  297. if (value != null)
  298. {
  299. do
  300. {
  301. if (comparer.Equals(head.item, value))
  302. {
  303. return head;
  304. }
  305. head = head.next;
  306. }
  307. while (head != this.head);
  308. }
  309. else
  310. {
  311. do
  312. {
  313. if (head.item == null)
  314. {
  315. return head;
  316. }
  317. head = head.next;
  318. }
  319. while (head != this.head);
  320. }
  321. }
  322. return null;
  323. }
  324. public LinkedListNode<T> FindLast(T value)
  325. {
  326. if (this.head != null)
  327. {
  328. LinkedListNode<T> prev = this.head.prev;
  329. LinkedListNode<T> node2 = prev;
  330. EqualityComparer<T> comparer = EqualityComparer<T>.Default;
  331. if (node2 != null)
  332. {
  333. if (value != null)
  334. {
  335. do
  336. {
  337. if (comparer.Equals(node2.item, value))
  338. {
  339. return node2;
  340. }
  341. node2 = node2.prev;
  342. }
  343. while (node2 != prev);
  344. }
  345. else
  346. {
  347. do
  348. {
  349. if (node2.item == null)
  350. {
  351. return node2;
  352. }
  353. node2 = node2.prev;
  354. }
  355. while (node2 != prev);
  356. }
  357. }
  358. }
  359. return null;
  360. }
  361. public ListEnumerator<T> GetEnumerator()
  362. {
  363. return new ListEnumerator<T>((LinkedList<T>)this);
  364. }
  365. private void InternalInsertNodeBefore(LinkedListNode<T> node, LinkedListNode<T> newNode)
  366. {
  367. newNode.next = node;
  368. newNode.prev = node.prev;
  369. node.prev.next = newNode;
  370. node.prev = newNode;
  371. this.version++;
  372. this.count++;
  373. }
  374. private void InternalInsertNodeToEmptyList(LinkedListNode<T> newNode)
  375. {
  376. newNode.next = newNode;
  377. newNode.prev = newNode;
  378. this.head = newNode;
  379. this.version++;
  380. this.count++;
  381. }
  382. internal void InternalRemoveNode(LinkedListNode<T> node)
  383. {
  384. if (node.next == node)
  385. {
  386. this.head = null;
  387. }
  388. else
  389. {
  390. node.next.prev = node.prev;
  391. node.prev.next = node.next;
  392. if (this.head == node)
  393. {
  394. this.head = node.next;
  395. }
  396. }
  397. node.Invalidate();
  398. this.count--;
  399. this.version++;
  400. }
  401. public void Remove(LinkedListNode<T> node)
  402. {
  403. this.ValidateNode(node);
  404. this.InternalRemoveNode(node);
  405. }
  406. public bool Remove(T value)
  407. {
  408. LinkedListNode<T> node = this.Find(value);
  409. if (node != null)
  410. {
  411. this.InternalRemoveNode(node);
  412. return true;
  413. }
  414. return false;
  415. }
  416. public void RemoveFirst()
  417. {
  418. if (this.head == null)
  419. {
  420. throw new InvalidOperationException();
  421. }
  422. this.InternalRemoveNode(this.head);
  423. }
  424. public void RemoveLast()
  425. {
  426. if (this.head == null)
  427. {
  428. throw new InvalidOperationException();
  429. }
  430. this.InternalRemoveNode(this.head.prev);
  431. }
  432. void ICollection<T>.Add(T value)
  433. {
  434. this.AddLast(value);
  435. }
  436. IEnumerator<T> IEnumerable<T>.GetEnumerator()
  437. {
  438. return this.GetEnumerator();
  439. }
  440. void ICollection.CopyTo(Array array, int index)
  441. {
  442. throw new NotImplementedException();
  443. //if (array == null)
  444. //{
  445. // throw new ArgumentException();
  446. // //throw new ArgumentNullException("array");
  447. //}
  448. //if (array.Rank != 1)
  449. //{
  450. // throw new ArgumentException();
  451. // // throw new ArgumentException(SR.GetString(0x8d, new object[0]));
  452. //}
  453. //if (array.GetLowerBound(0) != 0)
  454. //{
  455. // throw new ArgumentException();
  456. // // throw new ArgumentException();
  457. //}
  458. //if (index < 0)
  459. //{
  460. // throw new ArgumentOutOfRangeException();//"index", SR.GetString(0x8e, new object[] { index }));
  461. //}
  462. //if ((array.Length - index) < this.Count)
  463. //{
  464. // throw new ArgumentException();//SR.GetString(0x8f, new object[0]));
  465. //}
  466. //T[] localArray = array as T[];
  467. //if (localArray != null)
  468. //{
  469. // this.CopyTo(localArray, index);
  470. //}
  471. //else
  472. //{
  473. // Type elementType = array.GetType().GetElementType();
  474. // Type c = typeof(T);
  475. // if (!elementType.IsAssignableFrom(c) && !c.IsAssignableFrom(elementType))
  476. // {
  477. // throw new ArgumentException();
  478. // }
  479. // object[] objArray = array as object[];
  480. // if (objArray == null)
  481. // {
  482. // throw new ArgumentException();
  483. // }
  484. // LinkedListNode<T> head = this.head;
  485. // try
  486. // {
  487. // if (head != null)
  488. // {
  489. // do
  490. // {
  491. // objArray[index++] = head.item;
  492. // head = head.next;
  493. // }
  494. // while (head != this.head);
  495. // }
  496. // }
  497. // catch (ArrayTypeMismatchException)
  498. // {
  499. // throw new ArgumentException();
  500. // }
  501. // catch (InvalidCastException)
  502. // {
  503. // throw new ArgumentException();
  504. // }
  505. //}
  506. }
  507. IEnumerator IEnumerable.GetEnumerator()
  508. {
  509. return this.GetEnumerator();
  510. }
  511. internal void ValidateNewNode(LinkedListNode<T> node)
  512. {
  513. if (node == null)
  514. {
  515. throw new ArgumentNullException("node");
  516. }
  517. if (node.list != null)
  518. {
  519. throw new InvalidOperationException();
  520. }
  521. }
  522. internal void ValidateNode(LinkedListNode<T> node)
  523. {
  524. if (node == null)
  525. {
  526. throw new ArgumentNullException("node");
  527. }
  528. if (node.list != this)
  529. {
  530. throw new InvalidOperationException();
  531. }
  532. }
  533. public int Count
  534. {
  535. get
  536. {
  537. return this.count;
  538. }
  539. }
  540. public LinkedListNode<T> First
  541. {
  542. get
  543. {
  544. return this.head;
  545. }
  546. }
  547. public LinkedListNode<T> Last
  548. {
  549. get
  550. {
  551. if (this.head != null)
  552. {
  553. return this.head.prev;
  554. }
  555. return null;
  556. }
  557. }
  558. bool ICollection<T>.IsReadOnly
  559. {
  560. get
  561. {
  562. return false;
  563. }
  564. }
  565. bool ICollection.IsSynchronized
  566. {
  567. get
  568. {
  569. return false;
  570. }
  571. }
  572. object ICollection.SyncRoot
  573. {
  574. get
  575. {
  576. throw new NotImplementedException();
  577. //if (this._syncRoot == null)
  578. //{
  579. // Interlocked.CompareExchange(ref this._syncRoot, new object(), null);
  580. //}
  581. //return this._syncRoot;
  582. }
  583. }
  584. // [StructLayout(LayoutKind.Sequential)]
  585. public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
  586. {
  587. private LinkedList<T> list;
  588. private LinkedListNode<T> node;
  589. private int version;
  590. private T current;
  591. private int index;
  592. internal Enumerator(LinkedList<T> list)
  593. {
  594. this.list = list;
  595. this.version = list.version;
  596. this.node = list.head;
  597. this.current = default(T);
  598. this.index = 0;
  599. }
  600. public T Current
  601. {
  602. get
  603. {
  604. return this.current;
  605. }
  606. }
  607. object IEnumerator.Current
  608. {
  609. get
  610. {
  611. if ((this.index == 0) || (this.index == (this.list.Count + 1)))
  612. {
  613. throw new InvalidOperationException();
  614. // ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
  615. }
  616. return this.current;
  617. }
  618. }
  619. public bool MoveNext()
  620. {
  621. if (this.version != this.list.version)
  622. {
  623. throw new InvalidOperationException();
  624. // throw new InvalidOperationException(SR.GetString(0x43, new object[0]));
  625. }
  626. if (this.node == null)
  627. {
  628. this.index = this.list.Count + 1;
  629. return false;
  630. }
  631. this.index++;
  632. this.current = this.node.item;
  633. this.node = this.node.next;
  634. if (this.node == this.list.head)
  635. {
  636. this.node = null;
  637. }
  638. return true;
  639. }
  640. void IEnumerator.Reset()
  641. {
  642. if (this.version != this.list.version)
  643. {
  644. throw new InvalidOperationException();//SR.GetString(0x43, new object[0]));
  645. }
  646. this.current = default(T);
  647. this.node = this.list.head;
  648. this.index = 0;
  649. }
  650. public void Dispose()
  651. {
  652. }
  653. }
  654. }
  655. }
  656. #endif