1- using System . Collections ;
1+ using System ;
2+ using System . Collections ;
23using System . Collections . Generic ;
34using System . Linq ;
5+ using System . Runtime . CompilerServices ;
46
57namespace Extended . Collections . Generic
68{
@@ -25,7 +27,44 @@ public class RingBuffer<T> : ICollection<T>, IReadOnlyCollection<T>
2527 public int Count { get ; private set ; }
2628
2729 /// <inheritdoc cref="ICollection"/>
28- public bool IsReadOnly { get ; }
30+ public bool IsReadOnly => false ;
31+
32+ /// <summary>
33+ /// Gets the element at the given index, if the index is negetive it will wrap around
34+ /// </summary>
35+ /// <param name="index">The index to get</param>
36+ /// <returns>The current value</returns>
37+ public T this [ int index ]
38+ {
39+ get
40+ {
41+ if ( Count == 0 )
42+ {
43+ throw new IndexOutOfRangeException ( $ "The collection currently contains no elements, you can't select") ;
44+ }
45+
46+ // Reduce the count
47+ if ( index > 0 )
48+ {
49+ if ( - index > Count )
50+ throw new IndexOutOfRangeException ( "Index out of range." ) ;
51+ index = ( m_tail + index ) % Capacity ;
52+ }
53+ else
54+ {
55+ if ( index >= Count )
56+ throw new IndexOutOfRangeException ( "Index out of range." ) ;
57+ index = ( m_head + index + Capacity ) % Capacity ;
58+ }
59+
60+ if ( index < 0 )
61+ {
62+ index = Capacity + index ;
63+ }
64+
65+ return m_items [ index ] ! ;
66+ }
67+ }
2968
3069 /// <summary>
3170 /// Creates a new ring buffer with a fix capacity
@@ -38,7 +77,6 @@ public RingBuffer(int capacity, IEqualityComparer<T>? equalityComparer = null)
3877 Count = 0 ;
3978 m_tail = 0 ;
4079 m_items = new T [ capacity ] ;
41- IsReadOnly = false ;
4280 m_equalityComparer = equalityComparer ?? EqualityComparer < T > . Default ;
4381 }
4482
@@ -56,6 +94,7 @@ public RingBuffer(IEnumerable<T> collection, IEqualityComparer<T>? equalityCompa
5694 m_equalityComparer = equalityComparer ?? EqualityComparer < T > . Default ;
5795 }
5896
97+
5998 /// <summary>
6099 /// Adds a new item to the buffer
61100 /// </summary>
@@ -105,16 +144,15 @@ public void Clear()
105144 }
106145
107146 /// <summary>
108- /// Returns back if a the biffer contains the item
147+ /// Returns back if a the buffer contains the item
109148 /// </summary>
110149 /// <param name="item">The item to check if it contains</param>
111150 /// <returns>True if it is within otherwise false</returns>
112151 public bool Contains ( T item )
113152 {
114- for ( int i = 0 ; i < Count ; i ++ )
153+ foreach ( T value in this )
115154 {
116- T ? current = m_items [ i ] ;
117- if ( current != null && m_equalityComparer . Equals ( current , item ) )
155+ if ( m_equalityComparer . Equals ( value , item ) )
118156 {
119157 return true ;
120158 }
@@ -125,18 +163,23 @@ public bool Contains(T item)
125163 /// <summary>
126164 /// Copies this buffer into another array
127165 /// </summary>
128- /// <param name="array">The array to copy into</param>
129- /// <param name="arrayIndex">The index to start the copying</param>
130- public void CopyTo ( T [ ] array , int arrayIndex )
131- {
132- IEnumerator < T > enumerator = GetEnumerator ( ) ;
166+ /// <param name="destination">The array to copy into</param>
167+ /// <param name="destinationIndex">The index to start the copying</param>
168+ public void CopyTo ( T [ ] destination , int destinationIndex )
169+ => CopyTo ( destination , destinationIndex , 0 , Count ) ;
133170
134- using ( enumerator )
171+ /// <summary>
172+ /// Copies this buffer into another array
173+ /// </summary>
174+ /// <param name="destination">The array to copy into</param>
175+ /// <param name="destinationIndex">The index to start the copying</param>
176+ /// <param name="count">The max number of items to copy</param>
177+ public void CopyTo ( T [ ] destination , int destinationIndex , int sourceIndex , int count )
178+ {
179+ for ( int i = 0 ; i < Count ; i ++ )
135180 {
136- while ( enumerator . MoveNext ( ) )
137- {
138- array [ arrayIndex ++ ] = enumerator . Current ;
139- }
181+ int index = ( i + m_tail + sourceIndex ) % Capacity ;
182+ destination [ destinationIndex + i ] = m_items [ index ] ! ;
140183 }
141184 }
142185
@@ -153,7 +196,8 @@ public bool Remove(T item)
153196
154197 for ( int i = 0 ; i < Count ; i ++ )
155198 {
156- T ? current = m_items [ i ] ;
199+ int idx = ( m_tail + i ) % Capacity ;
200+ T ? current = m_items [ idx ] ;
157201
158202 if ( current == null )
159203 {
0 commit comments