internal static void Clear(TList list) { if (list == null) { throw new ArgumentNullException("list"); } list.InvokeInMonitorLock(() => { if (list._firstNode == null) { return; } WithAll(list.GetInChange(() => { var r = list.Select((node, index) => { RaiseRemovingItem(list, node, index); return(new { Item = node, Index = index }); }).ToArray(); list._firstNode = list._lastNode = null; list.Count = 0L; foreach (var i in r) { i.Item._nextNode = null; i.Item._container = null; } return(r); }), a => RaiseItemRemoved(list, a.Item, a.Index)); }); }
internal static void RemoveAt(TList list, long index) { if (list == null) { throw new ArgumentNullException("list"); } if (index < 0) { throw new ArgumentOutOfRangeException("index"); } list.InvokeInMonitorLock(() => { if (index >= list.Count) { throw new ArgumentOutOfRangeException("index"); } TElement item = list._firstNode; TElement previousItem = null; for (long i = 0L; i < index; i++) { previousItem = item; if ((item = item._nextNode) == null) { throw new ArgumentOutOfRangeException("index"); } } list.InvokeInChange(() => { RaiseRemovingItem(list, item, index); if (index == 0) { if (list.Count == 1) { list._firstNode = list._lastNode = null; list.Count = 0; } else if ((list._firstNode = item._nextNode)._nextNode == null) { list._lastNode = list._firstNode; list.Count = 1; } else { list.Count--; } } else { if ((previousItem._nextNode = item._nextNode)._nextNode == null) { list._lastNode = previousItem; } list.Count--; } item._container = null; item._nextNode = null; }); RaiseItemRemoved(list, item, index); }); }
internal static void Add(TList list, TElement item) { if (list == null) { throw new ArgumentNullException("list"); } if (item == null) { throw new ArgumentNullException("item"); } list.InvokeInMonitorLock(() => RaiseItemAdded(list, item, item.GetInMonitorLock(() => { ValidateItemOrphaned(list, item); return(list.GetInChange(() => { long i = list.Count; RaiseAddingItem(list, item, i); if (list._firstNode == null) { list._firstNode = list._lastNode = item; list.Count = 1; } else { list._lastNode._nextNode = item; list._lastNode = item; list.Count++; } item._container = list; return i; })); }))); }
/// <summary> /// /// </summary> /// <param name="disposing"></param> protected virtual void Dispose(bool disposing) { TList list = _list; if (list != null && disposing) { list.InvokeInMonitorLock(() => _list = null); } }
internal static void CopyTo(TList list, Array array, int arrayIndex) { if (list == null) { throw new ArgumentNullException("list"); } if (array == null) { throw new ArgumentNullException("array"); } if (arrayIndex < 0) { throw new ArgumentOutOfRangeException("arrayIndex"); } list.InvokeInMonitorLock(() => { if (list.Count + (long)arrayIndex > array.LongLength) { throw new ArgumentException("Not enough room at end of array", "arrayIndex"); } long index = (long)arrayIndex - 1L; for (TElement node = list._firstNode; node != null; node = node._nextNode) { try { index++; array.SetValue(node, index); } catch (InvalidCastException exception) { throw new ArgumentException(exception.Message, "array", exception); } catch (ArgumentException exception) { if (list.Count + (long)arrayIndex > array.LongLength) { throw new ArgumentException("Not enough room at end of array", "arrayIndex", exception); } if (exception.ParamName != null && exception.ParamName == "index") { throw new ArgumentException(exception.Message, "arrayIndex", exception); } throw new ArgumentException(exception.Message, "array", exception); } catch (Exception exception) { if (list.Count + (long)arrayIndex > array.LongLength) { throw new ArgumentException("Not enough room at end of array", "arrayIndex"); } throw new ArgumentException(exception.Message, "array", exception); } } }); }
/// <summary> /// Initializes a new <see cref="Enumerator" /> to iterate over the elements of a <typeparamref name="TList" />. /// </summary> /// <param name="list">The <typeparamref name="TList" /> whose elements are to be iterated.</param> public Enumerator(TList list) { if (list == null) { throw new ArgumentNullException("list"); } Index = -1; _list = list; list.InvokeInMonitorLock(() => { _firstNode = list._firstNode; _lastNode = list._lastNode; _count = list.Count; }); }
/// <summary> /// Sets the enumerator to its initial position, which is before the first element in the <typeparamref name="TList" />. /// </summary> /// <exception cref="ObjectDisposedException">The current enumerator or the <typeparamref name="TList" /> being iterated has been <sealso cref="Dispose" />d.</exception> public void Reset() { TList list = _list; if (list == null) { throw new ObjectDisposedException(typeof(Enumerator).FullName); } list.InvokeInMonitorLock(() => { if (_list == null) { throw new ObjectDisposedException(typeof(Enumerator).FullName); } Current = null; Index = -1; _firstNode = _list._firstNode; _lastNode = _list._lastNode; _count = _list.Count; }); }
internal static void Set(TList list, long index, TElement value) { if (list == null) { throw new ArgumentNullException("list"); } if (index < 0L) { throw new IndexOutOfRangeException(); } if (value == null) { throw new ArgumentNullException(); } list.InvokeInMonitorLock(() => { if (index < list.Count) { TElement previousNode = null; TElement currentNode = list._firstNode; for (long i = 0; i < index; i++) { if (currentNode == null) { break; } previousNode = currentNode; currentNode = currentNode._nextNode; } if (currentNode != null) { value.InvokeInMonitorLock(() => { if (value._container != null) { if (ReferenceEquals(value._container, list)) { if (ReferenceEquals(value, currentNode)) { return; } throw new ArgumentOutOfRangeException("value", ErrorMessage_ItemExistsInCurrent); } throw new ArgumentOutOfRangeException("value", ErrorMessage_ItemExistsInCurrent); } list.InvokeInChange(() => { RaiseReplacingItem(list, currentNode, value, index); value._nextNode = currentNode._nextNode; if (previousNode == null) { list._firstNode = value; } else { previousNode._nextNode = value; } if (value._nextNode == null) { list._lastNode = value; } value._container = list; currentNode._container = null; }); }); RaiseItemReplaced(list, currentNode, value, index); return; } } throw new IndexOutOfRangeException(); }); }
internal static void Insert(TList list, long index, TElement item) { if (list == null) { throw new ArgumentNullException("list"); } if (index < 0L) { throw new ArgumentOutOfRangeException("index"); } if (item == null) { throw new ArgumentNullException("item"); } list.InvokeInMonitorLock(() => { if (index > list.Count) { throw new ArgumentOutOfRangeException("index"); } item.InvokeInMonitorLock(() => { ValidateItemOrphaned(list, item); list.InvokeInChange(() => { RaiseAddingItem(list, item, index); if (index == list.Count) { if (index == 0L) { list._firstNode = item; list.Count = 1L; } else { list._lastNode._nextNode = item; list.Count++; } list._lastNode = item; } else if (index == 0L) { item._nextNode = list._firstNode; list._firstNode = item; } else if (index == list.Count - 1) { list._lastNode._nextNode = item; list._lastNode = item; } else { TElement previousItem = list._firstNode; for (long i = 1L; i < index; i++) { if ((previousItem = previousItem._nextNode) == null) { throw new ArgumentOutOfRangeException("index"); } } item._nextNode = previousItem._nextNode; previousItem._nextNode = item; } item._container = list; }); }); RaiseItemAdded(list, item, index); }); }