Advertisement
Guest User

Untitled

a guest
Mar 27th, 2017
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.35 KB | None | 0 0
  1. namespace System.Collections.Generic
  2. {
  3. using System.Linq;
  4.  
  5. public sealed class CircularBuffer<TItem> : IList<TItem>, ICollection<TItem>, IEnumerable<TItem>
  6. {
  7. private int count = 0;
  8. private int offset = 0;
  9.  
  10. private readonly TItem[] buffer;
  11. public CircularBuffer(int size)
  12. {
  13. buffer = new TItem[size];
  14. }
  15.  
  16. public TItem Add(TItem item)
  17. {
  18. var index = (count + offset) % buffer.Length;
  19. var old = buffer[index];
  20. buffer[index] = item;
  21. if (count < buffer.Length) { ++count; old = default(TItem); }
  22. else offset = (offset + 1) % buffer.Length;
  23. return old;
  24. }
  25.  
  26. public TItem Pop()
  27. {
  28. var item = Top();
  29. Drop();
  30. return item;
  31. }
  32.  
  33. public TItem Top()
  34. {
  35. if (count == 0) throw new InvalidOperationException("The collection is empty");
  36. var index = (count + offset - 1) % buffer.Length;
  37. return buffer[index];
  38. }
  39.  
  40. public void Drop()
  41. {
  42. if (count > 0) { --count; return; }
  43. throw new InvalidOperationException("The collection is empty");
  44. }
  45.  
  46. public int Count { get { return count; } }
  47.  
  48. public bool IsReadOnly { get { return false; } }
  49.  
  50. public TItem this[int index]
  51. {
  52. get
  53. {
  54. if (index < 0 || index >= buffer.Length)
  55. throw new IndexOutOfRangeException("Index is out of range");
  56. if (index >= count) return default(TItem);
  57. var pos = (offset + index) % buffer.Length;
  58. return buffer[pos];
  59. }
  60.  
  61. set
  62. {
  63. if (index < 0 || index >= buffer.Length)
  64. throw new IndexOutOfRangeException("Index is out of range");
  65. var pos = (offset + index) % buffer.Length;
  66. count = Math.Max(count, index + 1);
  67. buffer[pos] = value;
  68. }
  69. }
  70.  
  71. public IEnumerator<TItem> GetEnumerator()
  72. {
  73. for (int i = 0; i < count; ++i)
  74. {
  75. var index = (offset + i) % buffer.Length;
  76. if (index >= 0) yield return buffer[index];
  77. }
  78. }
  79.  
  80. IEnumerator IEnumerable.GetEnumerator()
  81. {
  82. return this.GetEnumerator();
  83. }
  84.  
  85. void ICollection<TItem>.Add(TItem item)
  86. {
  87. this.Add(item);
  88. }
  89.  
  90. public void Clear()
  91. {
  92. count = 0;
  93. offset = 0;
  94. }
  95.  
  96. public bool Contains(TItem item)
  97. {
  98. return IndexOf(item) >= 0;
  99. }
  100.  
  101. public void CopyTo(TItem[] array, int offset)
  102. {
  103. var index = 0;
  104. foreach (var item in this)
  105. {
  106. array[offset + index] = item;
  107. ++index;
  108. }
  109. }
  110.  
  111. public bool Remove(TItem item)
  112. {
  113. var index = IndexOf(item);
  114. if (index >= 0) RemoveAt(index);
  115. return index >= 0;
  116. }
  117.  
  118. public int IndexOf(TItem item)
  119. {
  120. var comparer = EqualityComparer<TItem>.Default;
  121. return this.Select((e, i) => comparer.Equals(e, item) ? i : -1)
  122. .Where(i => i > 0).Take(1).DefaultIfEmpty(-1).SingleOrDefault();
  123. }
  124.  
  125. public void Insert(int index, TItem item)
  126. {
  127. if (index < 0 || index >= buffer.Length)
  128. throw new IndexOutOfRangeException("Index is out of range");
  129.  
  130. var prev = item;
  131. for (int i = index + 1; i <= count; ++i)
  132. {
  133. var pos = (offset + i) % buffer.Length;
  134. if (pos >= buffer.Length) break;
  135. var tmp = buffer[pos];
  136. buffer[pos] = prev;
  137. prev = tmp;
  138. }
  139.  
  140. if (count < buffer.Length) ++count;
  141. else offset = (offset + 1) % buffer.Length;
  142. }
  143.  
  144. public void RemoveAt(int index)
  145. {
  146. if (index < 0 || index >= count)
  147. throw new IndexOutOfRangeException("Index is out of range");
  148.  
  149. --count;
  150. for (int i = index; i <= count; ++i)
  151. {
  152. var pos = (offset + i) % buffer.Length;
  153. buffer[pos] = buffer[pos + 1];
  154. }
  155. }
  156. }
  157. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement