379 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
		
		
			
		
	
	
			379 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
| 
								 | 
							
								 /*
							 | 
						|||
| 
								 | 
							
								 ----------------------------------------------------------------------------
							 | 
						|||
| 
								 | 
							
								 "THE BEER-WARE LICENSE" (Revision 42):
							 | 
						|||
| 
								 | 
							
								 Joao Portela wrote this file. As long as you retain this notice you
							 | 
						|||
| 
								 | 
							
								 can do whatever you want with this stuff. If we meet some day, and you think
							 | 
						|||
| 
								 | 
							
								 this stuff is worth it, you can buy me a beer in return.
							 | 
						|||
| 
								 | 
							
								 Joao Portela
							 | 
						|||
| 
								 | 
							
								 --------------------------------------------------------------------------
							 | 
						|||
| 
								 | 
							
								 * https://github.com/joaoportela/CircullarBuffer-CSharp
							 | 
						|||
| 
								 | 
							
								*/
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								namespace SRDebugger
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    using System;
							 | 
						|||
| 
								 | 
							
								    using System.Collections;
							 | 
						|||
| 
								 | 
							
								    using System.Collections.Generic;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public interface IReadOnlyList<T> : IEnumerable<T>
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        int Count { get; }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        T this[int index] { get; }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /// <summary>
							 | 
						|||
| 
								 | 
							
								    /// Circular buffer.
							 | 
						|||
| 
								 | 
							
								    /// When writting to a full buffer:
							 | 
						|||
| 
								 | 
							
								    /// PushBack -> removes this[0] / Front()
							 | 
						|||
| 
								 | 
							
								    /// PushFront -> removes this[Size-1] / Back()
							 | 
						|||
| 
								 | 
							
								    /// this implementation is inspired by
							 | 
						|||
| 
								 | 
							
								    /// http://www.boost.org/doc/libs/1_53_0/libs/circular_buffer/doc/circular_buffer.html
							 | 
						|||
| 
								 | 
							
								    /// because I liked their interface.
							 | 
						|||
| 
								 | 
							
								    /// </summary>
							 | 
						|||
| 
								 | 
							
								    public class CircularBuffer<T> : IEnumerable<T>, IReadOnlyList<T>
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        private readonly T[] _buffer;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// The _end. Index after the last element in the buffer.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        private int _end;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// The _size. Buffer size.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        private int _count;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// The _start. Index of the first element in buffer.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        private int _start;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public CircularBuffer(int capacity)
							 | 
						|||
| 
								 | 
							
								            : this(capacity, new T[] {}) {}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Initializes a new instance of the <see cref="CircularBuffer{T}" /> class.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name='capacity'>
							 | 
						|||
| 
								 | 
							
								        /// Buffer capacity. Must be positive.
							 | 
						|||
| 
								 | 
							
								        /// </param>
							 | 
						|||
| 
								 | 
							
								        /// <param name='items'>
							 | 
						|||
| 
								 | 
							
								        /// Items to fill buffer with. Items length must be less than capacity.
							 | 
						|||
| 
								 | 
							
								        /// Sugestion: use Skip(x).Take(y).ToArray() to build this argument from
							 | 
						|||
| 
								 | 
							
								        /// any enumerable.
							 | 
						|||
| 
								 | 
							
								        /// </param>
							 | 
						|||
| 
								 | 
							
								        public CircularBuffer(int capacity, T[] items)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (capacity < 1)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                throw new ArgumentException(
							 | 
						|||
| 
								 | 
							
								                    "Circular buffer cannot have negative or zero capacity.", "capacity");
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            if (items == null)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                throw new ArgumentNullException("items");
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            if (items.Length > capacity)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                throw new ArgumentException(
							 | 
						|||
| 
								 | 
							
								                    "Too many items to fit circular buffer", "items");
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            _buffer = new T[capacity];
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            Array.Copy(items, _buffer, items.Length);
							 | 
						|||
| 
								 | 
							
								            _count = items.Length;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            _start = 0;
							 | 
						|||
| 
								 | 
							
								            _end = _count == capacity ? 0 : _count;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Maximum capacity of the buffer. Elements pushed into the buffer after
							 | 
						|||
| 
								 | 
							
								        /// maximum capacity is reached (IsFull = true), will remove an element.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        public int Capacity
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            get { return _buffer.Length; }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public bool IsFull
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            get { return Count == Capacity; }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public bool IsEmpty
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            get { return Count == 0; }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Current buffer size (the number of elements that the buffer has).
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        public int Count
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            get { return _count; }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public T this[int index]
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            get
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                if (IsEmpty)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    throw new IndexOutOfRangeException(string.Format("Cannot access index {0}. Buffer is empty", index));
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								                if (index >= _count)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    throw new IndexOutOfRangeException(string.Format("Cannot access index {0}. Buffer size is {1}",
							 | 
						|||
| 
								 | 
							
								                        index, _count));
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								                var actualIndex = InternalIndex(index);
							 | 
						|||
| 
								 | 
							
								                return _buffer[actualIndex];
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            set
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                if (IsEmpty)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    throw new IndexOutOfRangeException(string.Format("Cannot access index {0}. Buffer is empty", index));
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								                if (index >= _count)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    throw new IndexOutOfRangeException(string.Format("Cannot access index {0}. Buffer size is {1}",
							 | 
						|||
| 
								 | 
							
								                        index, _count));
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								                var actualIndex = InternalIndex(index);
							 | 
						|||
| 
								 | 
							
								                _buffer[actualIndex] = value;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public void Clear()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            _count = 0;
							 | 
						|||
| 
								 | 
							
								            _start = 0;
							 | 
						|||
| 
								 | 
							
								            _end = 0;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #region IEnumerable<T> implementation
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public IEnumerator<T> GetEnumerator()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            var segments = new ArraySegment<T>[2] {ArrayOne(), ArrayTwo()};
							 | 
						|||
| 
								 | 
							
								            foreach (var segment in segments)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                for (var i = 0; i < segment.Count; i++)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    yield return segment.Array[segment.Offset + i];
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #endregion
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #region IEnumerable implementation
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        IEnumerator IEnumerable.GetEnumerator()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return GetEnumerator();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #endregion
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #region IList<T> implementation
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #endregion
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Element at the front of the buffer - this[0].
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <returns>The value of the element of type T at the front of the buffer.</returns>
							 | 
						|||
| 
								 | 
							
								        public T Front()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ThrowIfEmpty();
							 | 
						|||
| 
								 | 
							
								            return _buffer[_start];
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Element at the back of the buffer - this[Size - 1].
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <returns>The value of the element of type T at the back of the buffer.</returns>
							 | 
						|||
| 
								 | 
							
								        public T Back()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ThrowIfEmpty();
							 | 
						|||
| 
								 | 
							
								            return _buffer[(_end != 0 ? _end : _count) - 1];
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Pushes a new element to the back of the buffer. Back()/this[Size-1]
							 | 
						|||
| 
								 | 
							
								        /// will now return this element.
							 | 
						|||
| 
								 | 
							
								        /// When the buffer is full, the element at Front()/this[0] will be
							 | 
						|||
| 
								 | 
							
								        /// popped to allow for this new element to fit.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name="item">Item to push to the back of the buffer</param>
							 | 
						|||
| 
								 | 
							
								        public void PushBack(T item)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (IsFull)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                _buffer[_end] = item;
							 | 
						|||
| 
								 | 
							
								                Increment(ref _end);
							 | 
						|||
| 
								 | 
							
								                _start = _end;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            else
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                _buffer[_end] = item;
							 | 
						|||
| 
								 | 
							
								                Increment(ref _end);
							 | 
						|||
| 
								 | 
							
								                ++_count;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Pushes a new element to the front of the buffer. Front()/this[0]
							 | 
						|||
| 
								 | 
							
								        /// will now return this element.
							 | 
						|||
| 
								 | 
							
								        /// When the buffer is full, the element at Back()/this[Size-1] will be
							 | 
						|||
| 
								 | 
							
								        /// popped to allow for this new element to fit.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name="item">Item to push to the front of the buffer</param>
							 | 
						|||
| 
								 | 
							
								        public void PushFront(T item)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (IsFull)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                Decrement(ref _start);
							 | 
						|||
| 
								 | 
							
								                _end = _start;
							 | 
						|||
| 
								 | 
							
								                _buffer[_start] = item;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            else
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                Decrement(ref _start);
							 | 
						|||
| 
								 | 
							
								                _buffer[_start] = item;
							 | 
						|||
| 
								 | 
							
								                ++_count;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Removes the element at the back of the buffer. Decreassing the
							 | 
						|||
| 
								 | 
							
								        /// Buffer size by 1.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        public void PopBack()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ThrowIfEmpty("Cannot take elements from an empty buffer.");
							 | 
						|||
| 
								 | 
							
								            Decrement(ref _end);
							 | 
						|||
| 
								 | 
							
								            _buffer[_end] = default(T);
							 | 
						|||
| 
								 | 
							
								            --_count;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Removes the element at the front of the buffer. Decreassing the
							 | 
						|||
| 
								 | 
							
								        /// Buffer size by 1.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        public void PopFront()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ThrowIfEmpty("Cannot take elements from an empty buffer.");
							 | 
						|||
| 
								 | 
							
								            _buffer[_start] = default(T);
							 | 
						|||
| 
								 | 
							
								            Increment(ref _start);
							 | 
						|||
| 
								 | 
							
								            --_count;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Copies the buffer contents to an array, acording to the logical
							 | 
						|||
| 
								 | 
							
								        /// contents of the buffer (i.e. independent of the internal
							 | 
						|||
| 
								 | 
							
								        /// order/contents)
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <returns>A new array with a copy of the buffer contents.</returns>
							 | 
						|||
| 
								 | 
							
								        public T[] ToArray()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            var newArray = new T[Count];
							 | 
						|||
| 
								 | 
							
								            var newArrayOffset = 0;
							 | 
						|||
| 
								 | 
							
								            var segments = new ArraySegment<T>[2] {ArrayOne(), ArrayTwo()};
							 | 
						|||
| 
								 | 
							
								            foreach (var segment in segments)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                Array.Copy(segment.Array, segment.Offset, newArray, newArrayOffset, segment.Count);
							 | 
						|||
| 
								 | 
							
								                newArrayOffset += segment.Count;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            return newArray;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private void ThrowIfEmpty(string message = "Cannot access an empty buffer.")
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (IsEmpty)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                throw new InvalidOperationException(message);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Increments the provided index variable by one, wrapping
							 | 
						|||
| 
								 | 
							
								        /// around if necessary.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name="index"></param>
							 | 
						|||
| 
								 | 
							
								        private void Increment(ref int index)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (++index == Capacity)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                index = 0;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Decrements the provided index variable by one, wrapping
							 | 
						|||
| 
								 | 
							
								        /// around if necessary.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name="index"></param>
							 | 
						|||
| 
								 | 
							
								        private void Decrement(ref int index)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (index == 0)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                index = Capacity;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            index--;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Converts the index in the argument to an index in <code>_buffer</code>
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <returns>
							 | 
						|||
| 
								 | 
							
								        /// The transformed index.
							 | 
						|||
| 
								 | 
							
								        /// </returns>
							 | 
						|||
| 
								 | 
							
								        /// <param name='index'>
							 | 
						|||
| 
								 | 
							
								        /// External index.
							 | 
						|||
| 
								 | 
							
								        /// </param>
							 | 
						|||
| 
								 | 
							
								        private int InternalIndex(int index)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return _start + (index < (Capacity - _start) ? index : index - Capacity);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        // doing ArrayOne and ArrayTwo methods returning ArraySegment<T> as seen here: 
							 | 
						|||
| 
								 | 
							
								        // http://www.boost.org/doc/libs/1_37_0/libs/circular_buffer/doc/circular_buffer.html#classboost_1_1circular__buffer_1957cccdcb0c4ef7d80a34a990065818d
							 | 
						|||
| 
								 | 
							
								        // http://www.boost.org/doc/libs/1_37_0/libs/circular_buffer/doc/circular_buffer.html#classboost_1_1circular__buffer_1f5081a54afbc2dfc1a7fb20329df7d5b
							 | 
						|||
| 
								 | 
							
								        // should help a lot with the code.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #region Array items easy access.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        // The array is composed by at most two non-contiguous segments, 
							 | 
						|||
| 
								 | 
							
								        // the next two methods allow easy access to those.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private ArraySegment<T> ArrayOne()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (_start <= _end)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                return new ArraySegment<T>(_buffer, _start, _end - _start);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            return new ArraySegment<T>(_buffer, _start, _buffer.Length - _start);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private ArraySegment<T> ArrayTwo()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (_start < _end)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                return new ArraySegment<T>(_buffer, _end, 0);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            return new ArraySegment<T>(_buffer, 0, _end);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #endregion
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |