Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / class / corlib / System.Collections.Generic / List.cs
index 0517b2a4480d0c3374dd9af08585a552c4f4dad8..564e6b674a1910d922b8415e906cb3c5519717b1 100644 (file)
@@ -10,7 +10,7 @@
 //
 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
 // Copyright (C) 2005 David Waite
-// Copyright (C) 2011 Xamarin, Inc (http://www.xamarin.com)
+// 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
@@ -35,6 +35,7 @@
 using System.Collections.ObjectModel;
 using System.Runtime.InteropServices;
 using System.Diagnostics;
+using System.Runtime.CompilerServices;
 
 namespace System.Collections.Generic {
        [Serializable]
@@ -49,12 +50,11 @@ namespace System.Collections.Generic {
                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)
@@ -65,7 +65,7 @@ namespace System.Collections.Generic {
                        // 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;
@@ -93,7 +93,7 @@ namespace System.Collections.Generic {
                        // we can speed things up by 25%
                        if (_size == _items.Length)
                                GrowIfNeeded (1);
-                       _items [_size ++] = item;
+                       Array.UnsafeStore (_items, _size++, item);
                        _version++;
                }
                
@@ -635,16 +635,18 @@ namespace System.Collections.Generic {
                }
                
                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++;
                        }
                }
@@ -764,9 +766,9 @@ namespace System.Collections.Generic {
                                
                [Serializable]
                public struct Enumerator : IEnumerator <T>, IDisposable {
-                       List <T> l;
+                       readonly List<T> l;
                        int next;
-                       int ver;
+                       readonly int ver;
 
                        T current;
 
@@ -779,47 +781,41 @@ namespace System.Collections.Generic {
                        
                        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;