DynamicQueue.cs

A FIFO Collection of Objects, Concurrent, Non-Concurrent

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
[DebuggerDisplay("Count = {Count}")]
[Serializable]
public class DynamicQueue<T> : MonitorActionFunc, IEnumerable<T>
{
    private volatile T[] _array;
    private volatile int _head;
    private volatile int _scope;
    private volatile int _tail;
    public DynamicQueue() : this(1048576)
    {
    }
    public DynamicQueue(int capacity)
    {
        _array = new T[capacity];
        _scope = 0;
        _head  = 0;
        _tail  = 0;
    }
    public DynamicQueue(ICollection col)
    {
        if (col != null)
        {
            _array = new T[col.Count];
            _scope = 0;
            _head  = 0;
            _tail  = 0;
            var en = col.GetEnumerator();
            while (en.MoveNext())
                Enqueue((T) en.Current);
        }
    }
    public DynamicQueue(IEnumerable<T> col)
    {
        if (col != null)
        {
            _array = new T[col.Count()];
            _scope = 0;
            _head  = 0;
            _tail  = 0;
            using (var en = col.GetEnumerator())
            {
                while (en.MoveNext())
                    Enqueue(en.Current);
            }
        }
    }
    public int Count
    {
        get
        {
            var tmpThis = this;
            return tmpThis.Lock(tmpThis, () =>
            {
                return _scope;
            });
        }
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return new Enumerator(this);
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return new Enumerator(this);
    }
    public void Clear()
    {
        var tmpThis = this;
        tmpThis.Lock(tmpThis, () =>
        {
            _array.Clear();
            _scope = 0;
            _head  = 0;
            _tail  = 0;
        });
    }
    public bool Contains(T item)
    {
        var tmpThis = this;
        return tmpThis.Lock(tmpThis, () =>
        {
            var size             = _scope;
            var equalityComparer = EqualityComparer<T>.Default;
            while (size-- > 0)
                if (_array[size] != null && equalityComparer.Equals(_array[size], item))
                    return true;
            return false;
        });
    }
    public T Peek()
    {
        var tmpThis = this;
        return tmpThis.Lock(tmpThis, () =>
        {
            if (_scope <= 0)
                throw new Exception("Queue is Empty.");
            return _array[_head];
        });
    }
    public T Dequeue()
    {
        var tmpThis = this;
        return tmpThis.Lock(tmpThis, () =>
        {
            if (_scope <= 0)
                throw new Exception("Queue is Empty.");
            var TVal = _array[_head];
            _array[_head] = default;
            _head++;
            _scope--;
            return TVal;
        });
    }
    public void Enqueue(T item)
    {
        var tmpThis = this;
        tmpThis.Lock(tmpThis, () =>
        {
            if (Count + 1 > _array.Length)
                EnsureSize();
            _array[_tail] = item;
            _tail++;
            _scope++;
        });
    }
    private void EnsureSize()
    {
        var array = _array;
        Array.Resize(ref array, _array.Length << 1);
        _array = array;
    }
    public T[] ToArray()
    {
        var tmpThis = this;
        return tmpThis.Lock(tmpThis, () =>
        {
            var ta  = new T[_scope];
            var ptr = 0L;
            for (var i = _head; i < _scope + _head; ++i)
                ta[ptr++] = _array[i];
            return ta;
        });
    }
    [Serializable]
    public class Enumerator : IEnumerator<T>
    {
        private readonly DynamicQueue<T> _q;
        private          T               _current;
        private          int             _index;
        internal Enumerator(DynamicQueue<T> q)
        {
            _q       = q;
            _index   = -1;
            _current = default;
        }
        public T Current
        {
            get
            {
                var tmpThis = _q;
                return tmpThis.Lock(tmpThis, () =>
                {
                    if (_index < 0)
                    {
                        if (_index == -1)
                            throw new Exception("Enumeration not started.");
                        throw new Exception("Enumeration ended.");
                    }
                    return _current;
                });
            }
        }
        object IEnumerator.Current
        {
            get
            {
                var tmpThis = _q;
                return tmpThis.Lock(tmpThis, () =>
                {
                    if (_index < 0)
                    {
                        if (_index == -1)
                            throw new Exception("Enumeration not started.");
                        throw new Exception("Enumeration ended.");
                    }
                    return _current;
                });
            }
        }
        public void Dispose()
        {
            _index = -2;
        }
        public bool MoveNext()
        {
            var tmpThis = _q;
            return tmpThis.Lock(tmpThis, () =>
            {
                if (_index == -2)
                    return false;
                ++_index;
                if (_index == _q._scope)
                {
                    _index   = -2;
                    _current = default;
                    return false;
                }
                _current = _q._array[_q._head + _index];
                return true;
            });
        }
        void IEnumerator.Reset()
        {
            _index   = -1;
            _current = default;
        }
    }
}