diff options
author | Marek Safar <marek.safar@gmail.com> | 2019-02-09 05:11:21 +0100 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2019-02-08 20:11:21 -0800 |
commit | b67ebc46b4ae51ddb5e7bfbc65643f9f8f389023 (patch) | |
tree | 6272dd142fb07e011d7c81640b6cf48f7cec8657 | |
parent | bf2fdbcf9992c42b781d44aa39921e05ceaa8b1e (diff) | |
download | coreclr-b67ebc46b4ae51ddb5e7bfbc65643f9f8f389023.tar.gz coreclr-b67ebc46b4ae51ddb5e7bfbc65643f9f8f389023.tar.bz2 coreclr-b67ebc46b4ae51ddb5e7bfbc65643f9f8f389023.zip |
Move Array's SZGenericArrayEnumerator to shared partition (#22480)
* Move Array's SZGenericArrayEnumerator to shared partition
* Remove legacy comment
* Move all array enumerators to a new file
4 files changed, 211 insertions, 203 deletions
diff --git a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems index 8ee292ba60..192c520ac0 100644 --- a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems +++ b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems @@ -38,6 +38,7 @@ <Compile Include="$(MSBuildThisFileDirectory)System\ArgumentOutOfRangeException.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\ArithmeticException.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Array.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)System\Array.Enumerators.cs" Condition="'$(TargetsCoreRT)' != 'true'" /> <Compile Include="$(MSBuildThisFileDirectory)System\ArraySegment.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\ArrayTypeMismatchException.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\AssemblyLoadEventArgs.cs" /> diff --git a/src/System.Private.CoreLib/shared/System/Array.Enumerators.cs b/src/System.Private.CoreLib/shared/System/Array.Enumerators.cs new file mode 100644 index 0000000000..b9974ecfca --- /dev/null +++ b/src/System.Private.CoreLib/shared/System/Array.Enumerators.cs @@ -0,0 +1,210 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; + +namespace System +{ + internal sealed class ArrayEnumerator : IEnumerator, ICloneable + { + private Array array; + private int index; + private int endIndex; + private int startIndex; // Save for Reset. + private int[] _indices; // The current position in a multidim array + private bool _complete; + + internal ArrayEnumerator(Array array, int index, int count) + { + this.array = array; + this.index = index - 1; + startIndex = index; + endIndex = index + count; + _indices = new int[array.Rank]; + int checkForZero = 1; // Check for dimensions of size 0. + for (int i = 0; i < array.Rank; i++) + { + _indices[i] = array.GetLowerBound(i); + checkForZero *= array.GetLength(i); + } + // To make MoveNext simpler, decrement least significant index. + _indices[_indices.Length - 1]--; + _complete = (checkForZero == 0); + } + + private void IncArray() + { + // This method advances us to the next valid array index, + // handling all the multiple dimension & bounds correctly. + // Think of it like an odometer in your car - we start with + // the last digit, increment it, and check for rollover. If + // it rolls over, we set all digits to the right and including + // the current to the appropriate lower bound. Do these overflow + // checks for each dimension, and if the most significant digit + // has rolled over it's upper bound, we're done. + // + int rank = array.Rank; + _indices[rank - 1]++; + for (int dim = rank - 1; dim >= 0; dim--) + { + if (_indices[dim] > array.GetUpperBound(dim)) + { + if (dim == 0) + { + _complete = true; + break; + } + for (int j = dim; j < rank; j++) + _indices[j] = array.GetLowerBound(j); + _indices[dim - 1]++; + } + } + } + + public object Clone() + { + return MemberwiseClone(); + } + + public bool MoveNext() + { + if (_complete) + { + index = endIndex; + return false; + } + index++; + IncArray(); + return !_complete; + } + + public object Current + { + get + { + if (index < startIndex) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted(); + if (_complete) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded(); + return array.GetValue(_indices); + } + } + + public void Reset() + { + index = startIndex - 1; + int checkForZero = 1; + for (int i = 0; i < array.Rank; i++) + { + _indices[i] = array.GetLowerBound(i); + checkForZero *= array.GetLength(i); + } + _complete = (checkForZero == 0); + // To make MoveNext simpler, decrement least significant index. + _indices[_indices.Length - 1]--; + } + } + + internal sealed class SZArrayEnumerator : IEnumerator, ICloneable + { + private readonly Array _array; + private int _index; + private int _endIndex; // Cache Array.Length, since it's a little slow. + + internal SZArrayEnumerator(Array array) + { + Debug.Assert(array.Rank == 1 && array.GetLowerBound(0) == 0, "SZArrayEnumerator only works on single dimension arrays w/ a lower bound of zero."); + + _array = array; + _index = -1; + _endIndex = array.Length; + } + + public object Clone() + { + return MemberwiseClone(); + } + + public bool MoveNext() + { + if (_index < _endIndex) + { + _index++; + return (_index < _endIndex); + } + return false; + } + + public object Current + { + get + { + if (_index < 0) + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted(); + if (_index >= _endIndex) + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded(); + return _array.GetValue(_index); + } + } + + public void Reset() + { + _index = -1; + } + } + + internal sealed class SZGenericArrayEnumerator<T> : IEnumerator<T> + { + private readonly T[] _array; + private int _index; + + // Array.Empty is intentionally omitted here, since we don't want to pay for generic instantiations that + // wouldn't have otherwise been used. + internal static readonly SZGenericArrayEnumerator<T> Empty = new SZGenericArrayEnumerator<T>(new T[0]); + + internal SZGenericArrayEnumerator(T[] array) + { + Debug.Assert(array != null); + + _array = array; + _index = -1; + } + + public bool MoveNext() + { + int index = _index + 1; + if ((uint)index >= (uint)_array.Length) + { + _index = _array.Length; + return false; + } + _index = index; + return true; + } + + public T Current + { + get + { + int index = _index; + T[] array = _array; + + if ((uint)index >= (uint)array.Length) + { + ThrowHelper.ThrowInvalidOperationException_EnumCurrent(index); + } + + return array[index]; + } + } + + object IEnumerator.Current => Current; + + void IEnumerator.Reset() => _index = -1; + + public void Dispose() + { + } + } +}
\ No newline at end of file diff --git a/src/System.Private.CoreLib/shared/System/Array.cs b/src/System.Private.CoreLib/shared/System/Array.cs index 0056c48736..f77186e583 100644 --- a/src/System.Private.CoreLib/shared/System/Array.cs +++ b/src/System.Private.CoreLib/shared/System/Array.cs @@ -2001,152 +2001,6 @@ namespace System else return new ArrayEnumerator(this, lowerBound, Length); } - - private sealed class SZArrayEnumerator : IEnumerator, ICloneable - { - private readonly Array _array; - private int _index; - private int _endIndex; // Cache Array.Length, since it's a little slow. - - internal SZArrayEnumerator(Array array) - { - Debug.Assert(array.Rank == 1 && array.GetLowerBound(0) == 0, "SZArrayEnumerator only works on single dimension arrays w/ a lower bound of zero."); - - _array = array; - _index = -1; - _endIndex = array.Length; - } - - public object Clone() - { - return MemberwiseClone(); - } - - public bool MoveNext() - { - if (_index < _endIndex) - { - _index++; - return (_index < _endIndex); - } - return false; - } - - public object Current - { - get - { - if (_index < 0) - ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted(); - if (_index >= _endIndex) - ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded(); - return _array.GetValue(_index); - } - } - - public void Reset() - { - _index = -1; - } - } - - private sealed class ArrayEnumerator : IEnumerator, ICloneable - { - private Array array; - private int index; - private int endIndex; - private int startIndex; // Save for Reset. - private int[] _indices; // The current position in a multidim array - private bool _complete; - - internal ArrayEnumerator(Array array, int index, int count) - { - this.array = array; - this.index = index - 1; - startIndex = index; - endIndex = index + count; - _indices = new int[array.Rank]; - int checkForZero = 1; // Check for dimensions of size 0. - for (int i = 0; i < array.Rank; i++) - { - _indices[i] = array.GetLowerBound(i); - checkForZero *= array.GetLength(i); - } - // To make MoveNext simpler, decrement least significant index. - _indices[_indices.Length - 1]--; - _complete = (checkForZero == 0); - } - - private void IncArray() - { - // This method advances us to the next valid array index, - // handling all the multiple dimension & bounds correctly. - // Think of it like an odometer in your car - we start with - // the last digit, increment it, and check for rollover. If - // it rolls over, we set all digits to the right and including - // the current to the appropriate lower bound. Do these overflow - // checks for each dimension, and if the most significant digit - // has rolled over it's upper bound, we're done. - // - int rank = array.Rank; - _indices[rank - 1]++; - for (int dim = rank - 1; dim >= 0; dim--) - { - if (_indices[dim] > array.GetUpperBound(dim)) - { - if (dim == 0) - { - _complete = true; - break; - } - for (int j = dim; j < rank; j++) - _indices[j] = array.GetLowerBound(j); - _indices[dim - 1]++; - } - } - } - - public object Clone() - { - return MemberwiseClone(); - } - - public bool MoveNext() - { - if (_complete) - { - index = endIndex; - return false; - } - index++; - IncArray(); - return !_complete; - } - - public object Current - { - get - { - if (index < startIndex) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted(); - if (_complete) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded(); - return array.GetValue(_indices); - } - } - - public void Reset() - { - index = startIndex - 1; - int checkForZero = 1; - for (int i = 0; i < array.Rank; i++) - { - _indices[i] = array.GetLowerBound(i); - checkForZero *= array.GetLength(i); - } - _complete = (checkForZero == 0); - // To make MoveNext simpler, decrement least significant index. - _indices[_indices.Length - 1]--; - } - } #endif // !CORERT } } diff --git a/src/System.Private.CoreLib/src/System/Array.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Array.CoreCLR.cs index de8c6e3063..6600c5dfe7 100644 --- a/src/System.Private.CoreLib/src/System/Array.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Array.CoreCLR.cs @@ -526,62 +526,5 @@ namespace System // Not meaningful for arrays ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_FixedSizeCollection); } - - // This is a normal generic Enumerator for SZ arrays. It doesn't have any of the "this" stuff - // that SZArrayHelper does. - // - private sealed class SZGenericArrayEnumerator<T> : IEnumerator<T> - { - private readonly T[] _array; - private int _index; - - // Array.Empty is intentionally omitted here, since we don't want to pay for generic instantiations that - // wouldn't have otherwise been used. - internal static readonly SZGenericArrayEnumerator<T> Empty = new SZGenericArrayEnumerator<T>(new T[0]); - - internal SZGenericArrayEnumerator(T[] array) - { - Debug.Assert(array != null); - - _array = array; - _index = -1; - } - - public bool MoveNext() - { - int index = _index + 1; - if ((uint)index >= (uint)_array.Length) - { - _index = _array.Length; - return false; - } - _index = index; - return true; - } - - public T Current - { - get - { - int index = _index; - T[] array = _array; - - if ((uint)index >= (uint)array.Length) - { - ThrowHelper.ThrowInvalidOperationException_EnumCurrent(index); - } - - return array[index]; - } - } - - object IEnumerator.Current => Current; - - void IEnumerator.Reset() => _index = -1; - - public void Dispose() - { - } - } } }
\ No newline at end of file |