Skip to content

Commit 1e83529

Browse files
committed
Implemented IEnumerable and ICollection interfaces
1 parent e07cc47 commit 1e83529

File tree

2 files changed

+138
-5
lines changed

2 files changed

+138
-5
lines changed

DataStructures/Lists/CircularBuffer.cs

Lines changed: 108 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
25

36
namespace DataStructures.Lists
47
{
5-
public class CircularBuffer<T>
6-
{
8+
public class CircularBuffer<T> : IEnumerable<T> , ICollection<T> where T : IComparable<T> {
79
private T[] _circularBuffer;
810
private int _end;
911
private int _start;
12+
private int _length { get => _circularBuffer.Length - 1; }
13+
private readonly T _default;
1014
private static readonly int _defaultBufferLength = 10;
1115

1216
/// <summary>
1317
/// Controls whether data should be overridden when it is continously inserted without reading
1418
/// </summary>
1519
public bool CanOverride { get; }
1620
public bool IsEmpty { get => _end == _start; }
17-
public int Length { get => _circularBuffer.Length - 1; }
1821
public bool IsFilledUp { get => ((_end + 1) % _circularBuffer.Length == _start) && !_circularBuffer[_start].Equals(_circularBuffer[_end]); }
1922

23+
2024
/// <summary>
2125
/// Initializes a circular buffer with initial length of 10
2226
/// </summary>
@@ -35,6 +39,7 @@ public CircularBuffer(int length, bool canOverride=true)
3539
throw new ArgumentOutOfRangeException("length can not be zero or negative");
3640
}
3741
_circularBuffer = new T[length + 1];
42+
_default = _circularBuffer[length];
3843
_end = 0;
3944
_start = 0;
4045
CanOverride = canOverride;
@@ -81,6 +86,106 @@ public T Pop()
8186
_start = (_start + 1) % _circularBuffer.Length;
8287
return result;
8388
}
89+
90+
#region IEnumerable Implementation
91+
public IEnumerator<T> GetEnumerator()
92+
{
93+
for (int i = 0; i < Count; i++) {
94+
yield return _circularBuffer[i];
95+
}
96+
}
97+
98+
IEnumerator IEnumerable.GetEnumerator()
99+
{
100+
return GetEnumerator();
101+
}
102+
#endregion
103+
104+
#region ICollection Implementation
105+
/// <summary>
106+
/// Returns the number of elements.
107+
/// </summary>
108+
public int Count
109+
{
110+
get { return _length; }
111+
}
112+
/// <summary>
113+
/// Checks whether this collection is readonly
114+
/// </summary>
115+
public bool IsReadOnly
116+
{
117+
get { return false; }
118+
}
119+
/// <summary>
120+
/// Clears this instance
121+
/// </summary>
122+
public void Clear()
123+
{
124+
for (int i = 0; i < _circularBuffer.Length; i++)
125+
{
126+
_circularBuffer[i] = _default;
127+
}
128+
}
129+
/// <summary>
130+
/// Checks whether the buffer contains an item
131+
/// </summary>
132+
public bool Contains(T item)
133+
{
134+
return _circularBuffer.Contains(item);
135+
}
136+
/// <summary>
137+
/// Copies this buffer to an array
138+
/// </summary>
139+
public void CopyTo(T[] array, int arrayIndex)
140+
{
141+
if (array == null)
142+
{
143+
throw new ArgumentNullException("array can not be null");
144+
}
145+
146+
if (array.Length == 0 || arrayIndex >= array.Length || arrayIndex < 0) {
147+
throw new IndexOutOfRangeException();
148+
}
149+
150+
// Get enumerator
151+
var enumarator = GetEnumerator();
152+
153+
// Copy elements if there is any in the buffer and if the index is within the valid range
154+
while (arrayIndex < array.Length)
155+
{
156+
if (enumarator.MoveNext())
157+
{
158+
array[arrayIndex] = enumarator.Current;
159+
arrayIndex++;
160+
}
161+
else
162+
{
163+
break;
164+
}
165+
}
166+
}
167+
/// <summary>
168+
/// Removes an item from the buffer
169+
/// </summary>
170+
public bool Remove(T item)
171+
{
172+
if (Contains(item))
173+
{
174+
for (int i = 0; i < _circularBuffer.Length; i++)
175+
{
176+
if (item.Equals(_circularBuffer[i]))
177+
{
178+
_circularBuffer[i] = _default;
179+
}
180+
}
181+
return true;
182+
}
183+
else
184+
{
185+
return false;
186+
}
187+
}
188+
#endregion
84189
}
85190

86191
public class CircularBufferFullException: Exception

UnitTest/DataStructuresTests/CircularBufferTest.cs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class CircularBufferTest
1111
public static void SetsFixedLength()
1212
{
1313
var circularBuffer = new CircularBuffer<byte>(3);
14-
var length = circularBuffer.Length;
14+
var length = circularBuffer.Count;
1515
Assert.Equal(3, length);
1616
}
1717

@@ -37,7 +37,7 @@ public static void ChecksIsFilledProperty()
3737
public static void InitializesWithDefaultLengthOf10()
3838
{
3939
var circularBuffer = new CircularBuffer<byte>();
40-
var length = circularBuffer.Length;
40+
var length = circularBuffer.Count;
4141

4242
Assert.Equal(10, length);
4343
}
@@ -138,5 +138,33 @@ public static void TestingWritingAndReadingSimultenouslyWithoutOverriding()
138138
Assert.Equal(4, result4);
139139
Assert.Equal(14, result5);
140140
}
141+
142+
[Fact]
143+
public static void TestingICollectionImplementation()
144+
{
145+
var circularBuffer = new CircularBuffer<byte>(3, false);
146+
circularBuffer.Add(3);
147+
circularBuffer.Add(34);
148+
circularBuffer.Add(24);
149+
//Testing contains
150+
Assert.True(circularBuffer.Contains(3));
151+
152+
//Testing CopyTo
153+
var array = new byte[3];
154+
circularBuffer.CopyTo(array, 0);
155+
Assert.Equal(3, array[0]);
156+
Assert.Equal(34, array[1]);
157+
Assert.Equal(24, array[2]);
158+
159+
//Testing Remove
160+
Assert.True(circularBuffer.Remove(3));
161+
Assert.False(circularBuffer.Remove(14));
162+
163+
//Testing clear
164+
circularBuffer.Clear();
165+
Assert.Equal(0, circularBuffer.Pop());
166+
Assert.Equal(0, circularBuffer.Pop());
167+
Assert.Equal(0, circularBuffer.Pop());
168+
}
141169
}
142170
}

0 commit comments

Comments
 (0)