// Martin Baulig (martin@ximian.com)
// Carlos Alberto Cortez (calberto.cortez@gmail.com)
// David Waite (mass@akuma.org)
+// Marek Safar (marek.safar@gmail.com)
//
// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
// Copyright (C) 2005 David Waite
+// Copyright (C) 2011,2012 Xamarin, Inc (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using System.Diagnostics;
+using System.Runtime.CompilerServices;
namespace System.Collections.Generic {
[Serializable]
[DebuggerDisplay ("Count={Count}")]
[DebuggerTypeProxy (typeof (CollectionDebuggerView<>))]
- public class List <T> : IList <T>, IList, ICollection {
+ public class List<T> : IList<T>, IList
+#if NET_4_5
+ , IReadOnlyList<T>
+#endif
+ {
T [] _items;
int _size;
int _version;
- static readonly T [] EmptyArray = new T [0];
const int DefaultCapacity = 4;
public List ()
{
- _items = EmptyArray;
+ _items = EmptyArray<T>.Value;
}
public List (IEnumerable <T> collection)
// initialize to needed size (if determinable)
ICollection <T> c = collection as ICollection <T>;
if (c == null) {
- _items = EmptyArray;
+ _items = EmptyArray<T>.Value;;
AddEnumerable (collection);
} else {
_size = c.Count;
// we can speed things up by 25%
if (_size == _items.Length)
GrowIfNeeded (1);
- _items [_size ++] = item;
+ Array.UnsafeStore (_items, _size++, item);
_version++;
}
public int LastIndexOf (T item)
{
+ if (_size == 0)
+ return -1;
return Array.LastIndexOf<T> (_items, item, _size - 1, _size);
}
}
public T this [int index] {
+ [MethodImpl ((MethodImplOptions)256)]
get {
if ((uint) index >= (uint) _size)
throw new ArgumentOutOfRangeException ("index");
- return _items [index];
+ return Array.UnsafeLoad (_items, index);
}
+
+ [MethodImpl ((MethodImplOptions)256)]
set {
- CheckIndex (index);
- if ((uint) index == (uint) _size)
+ if ((uint) index >= (uint) _size)
throw new ArgumentOutOfRangeException ("index");
- _items [index] = value;
+ Array.UnsafeStore (_items, index, value);
+ _version++;
}
}
[Serializable]
public struct Enumerator : IEnumerator <T>, IDisposable {
- List <T> l;
+ readonly List<T> l;
int next;
- int ver;
+ readonly int ver;
T current;
public void Dispose ()
{
- l = null;
}
- void VerifyState ()
- {
- if (l == null)
- throw new ObjectDisposedException (GetType ().FullName);
- if (ver != l._version)
- throw new InvalidOperationException (
- "Collection was modified; enumeration operation may not execute.");
- }
-
public bool MoveNext ()
{
- VerifyState ();
-
- if (next < 0)
- return false;
+ var list = l;
- if (next < l._size) {
- current = l._items [next++];
+ if ((uint)next < (uint)list._size && ver == list._version) {
+ current = list._items [next++];
return true;
}
+ if (ver != l._version)
+ throw new InvalidOperationException ("Collection was modified; enumeration operation may not execute.");
+
next = -1;
return false;
}
-
+
public T Current {
get { return current; }
}
void IEnumerator.Reset ()
{
- VerifyState ();
+ if (ver != l._version)
+ throw new InvalidOperationException ("Collection was modified; enumeration operation may not execute.");
+
next = 0;
}
object IEnumerator.Current {
get {
- VerifyState ();
+ if (ver != l._version)
+ throw new InvalidOperationException ("Collection was modified; enumeration operation may not execute.");
+
if (next <= 0)
throw new InvalidOperationException ();
return current;