Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,360 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
namespace System.Collections.ObjectModel
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime;
[Serializable]
[System.Runtime.InteropServices.ComVisible(false)]
[DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
[DebuggerDisplay("Count = {Count}")]
public class Collection<T>: IList<T>, IList, IReadOnlyList<T>
{
IList<T> items;
[NonSerialized]
private Object _syncRoot;
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
public Collection() {
items = new List<T>();
}
public Collection(IList<T> list) {
if (list == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.list);
}
items = list;
}
public int Count {
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
get { return items.Count; }
}
protected IList<T> Items {
get { return items; }
}
public T this[int index] {
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
get { return items[index]; }
set {
if( items.IsReadOnly) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
if (index < 0 || index >= items.Count) {
ThrowHelper.ThrowArgumentOutOfRangeException();
}
SetItem(index, value);
}
}
public void Add(T item) {
if( items.IsReadOnly) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
int index = items.Count;
InsertItem(index, item);
}
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
public void Clear() {
if( items.IsReadOnly) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
ClearItems();
}
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
public void CopyTo(T[] array, int index) {
items.CopyTo(array, index);
}
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
public bool Contains(T item) {
return items.Contains(item);
}
public IEnumerator<T> GetEnumerator() {
return items.GetEnumerator();
}
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
public int IndexOf(T item) {
return items.IndexOf(item);
}
public void Insert(int index, T item) {
if (items.IsReadOnly) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
if (index < 0 || index > items.Count) {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_ListInsert);
}
InsertItem(index, item);
}
public bool Remove(T item) {
if( items.IsReadOnly) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
int index = items.IndexOf(item);
if (index < 0) return false;
RemoveItem(index);
return true;
}
public void RemoveAt(int index) {
if( items.IsReadOnly) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
if (index < 0 || index >= items.Count) {
ThrowHelper.ThrowArgumentOutOfRangeException();
}
RemoveItem(index);
}
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
protected virtual void ClearItems() {
items.Clear();
}
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
protected virtual void InsertItem(int index, T item) {
items.Insert(index, item);
}
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
protected virtual void RemoveItem(int index) {
items.RemoveAt(index);
}
protected virtual void SetItem(int index, T item) {
items[index] = item;
}
bool ICollection<T>.IsReadOnly {
get {
return items.IsReadOnly;
}
}
IEnumerator IEnumerable.GetEnumerator() {
return ((IEnumerable)items).GetEnumerator();
}
bool ICollection.IsSynchronized {
get { return false; }
}
object ICollection.SyncRoot {
get {
if( _syncRoot == null) {
ICollection c = items as ICollection;
if( c != null) {
_syncRoot = c.SyncRoot;
}
else {
System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
}
return _syncRoot;
}
}
void ICollection.CopyTo(Array array, int index) {
if (array == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
if (array.Rank != 1) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
if( array.GetLowerBound(0) != 0 ) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
if (index < 0 ) {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
if (array.Length - index < Count) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
T[] tArray = array as T[];
if (tArray != null) {
items.CopyTo(tArray , index);
}
else {
//
// Catch the obvious case assignment will fail.
// We can found all possible problems by doing the check though.
// For example, if the element type of the Array is derived from T,
// we can't figure out if we can successfully copy the element beforehand.
//
Type targetType = array.GetType().GetElementType();
Type sourceType = typeof(T);
if(!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
}
//
// We can't cast array of value type to object[], so we don't support
// widening of primitive types here.
//
object[] objects = array as object[];
if( objects == null) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
}
int count = items.Count;
try {
for (int i = 0; i < count; i++) {
objects[index++] = items[i];
}
}
catch(ArrayTypeMismatchException) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
}
}
}
object IList.this[int index] {
get { return items[index]; }
set {
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(value, ExceptionArgument.value);
try {
this[index] = (T)value;
}
catch (InvalidCastException) {
ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
}
}
}
bool IList.IsReadOnly {
get {
return items.IsReadOnly;
}
}
bool IList.IsFixedSize {
get {
// There is no IList<T>.IsFixedSize, so we must assume that only
// readonly collections are fixed size, if our internal item
// collection does not implement IList. Note that Array implements
// IList, and therefore T[] and U[] will be fixed-size.
IList list = items as IList;
if(list != null)
{
return list.IsFixedSize;
}
return items.IsReadOnly;
}
}
int IList.Add(object value) {
if( items.IsReadOnly) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(value, ExceptionArgument.value);
try {
Add((T)value);
}
catch (InvalidCastException) {
ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
}
return this.Count - 1;
}
bool IList.Contains(object value) {
if(IsCompatibleObject(value)) {
return Contains((T) value);
}
return false;
}
int IList.IndexOf(object value) {
if(IsCompatibleObject(value)) {
return IndexOf((T)value);
}
return -1;
}
void IList.Insert(int index, object value) {
if( items.IsReadOnly) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(value, ExceptionArgument.value);
try {
Insert(index, (T)value);
}
catch (InvalidCastException) {
ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
}
}
void IList.Remove(object value) {
if( items.IsReadOnly) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
if(IsCompatibleObject(value)) {
Remove((T) value);
}
}
private static bool IsCompatibleObject(object value) {
// Non-null values are fine. Only accept nulls if T is a class or Nullable<U>.
// Note that default(T) is not equal to null for value types except when T is Nullable<U>.
return ((value is T) || (value == null && default(T) == null));
}
}
}

View File

@@ -0,0 +1,238 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
namespace System.Collections.ObjectModel
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
[System.Runtime.InteropServices.ComVisible(false)]
[DebuggerTypeProxy(typeof(Mscorlib_KeyedCollectionDebugView<,>))]
[DebuggerDisplay("Count = {Count}")]
public abstract class KeyedCollection<TKey,TItem>: Collection<TItem>
{
const int defaultThreshold = 0;
IEqualityComparer<TKey> comparer;
Dictionary<TKey,TItem> dict;
int keyCount;
int threshold;
protected KeyedCollection(): this(null, defaultThreshold) {}
protected KeyedCollection(IEqualityComparer<TKey> comparer): this(comparer, defaultThreshold) {}
protected KeyedCollection(IEqualityComparer<TKey> comparer, int dictionaryCreationThreshold) {
if (comparer == null) {
comparer = EqualityComparer<TKey>.Default;
}
if (dictionaryCreationThreshold == -1) {
dictionaryCreationThreshold = int.MaxValue;
}
if( dictionaryCreationThreshold < -1) {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.dictionaryCreationThreshold, ExceptionResource.ArgumentOutOfRange_InvalidThreshold);
}
this.comparer = comparer;
this.threshold = dictionaryCreationThreshold;
}
public IEqualityComparer<TKey> Comparer {
get {
return comparer;
}
}
public TItem this[TKey key] {
get {
if( key == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
if (dict != null) {
return dict[key];
}
foreach (TItem item in Items) {
if (comparer.Equals(GetKeyForItem(item), key)) return item;
}
ThrowHelper.ThrowKeyNotFoundException();
return default(TItem);
}
}
public bool Contains(TKey key) {
if( key == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
if (dict != null) {
return dict.ContainsKey(key);
}
if (key != null) {
foreach (TItem item in Items) {
if (comparer.Equals(GetKeyForItem(item), key)) return true;
}
}
return false;
}
private bool ContainsItem(TItem item) {
TKey key;
if( (dict == null) || ((key = GetKeyForItem(item)) == null)) {
return Items.Contains(item);
}
TItem itemInDict;
bool exist = dict.TryGetValue(key, out itemInDict);
if( exist) {
return EqualityComparer<TItem>.Default.Equals(itemInDict, item);
}
return false;
}
public bool Remove(TKey key) {
if( key == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
if (dict != null) {
if (dict.ContainsKey(key)) {
return Remove(dict[key]);
}
return false;
}
if (key != null) {
for (int i = 0; i < Items.Count; i++) {
if (comparer.Equals(GetKeyForItem(Items[i]), key)) {
RemoveItem(i);
return true;
}
}
}
return false;
}
protected IDictionary<TKey,TItem> Dictionary {
get { return dict; }
}
protected void ChangeItemKey(TItem item, TKey newKey) {
// check if the item exists in the collection
if( !ContainsItem(item)) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_ItemNotExist);
}
TKey oldKey = GetKeyForItem(item);
if (!comparer.Equals(oldKey, newKey)) {
if (newKey != null) {
AddKey(newKey, item);
}
if (oldKey != null) {
RemoveKey(oldKey);
}
}
}
protected override void ClearItems() {
base.ClearItems();
if (dict != null) {
dict.Clear();
}
keyCount = 0;
}
protected abstract TKey GetKeyForItem(TItem item);
protected override void InsertItem(int index, TItem item) {
TKey key = GetKeyForItem(item);
if (key != null) {
AddKey(key, item);
}
base.InsertItem(index, item);
}
protected override void RemoveItem(int index) {
TKey key = GetKeyForItem(Items[index]);
if (key != null) {
RemoveKey(key);
}
base.RemoveItem(index);
}
protected override void SetItem(int index, TItem item) {
TKey newKey = GetKeyForItem(item);
TKey oldKey = GetKeyForItem(Items[index]);
if (comparer.Equals(oldKey, newKey)) {
if (newKey != null && dict != null) {
dict[newKey] = item;
}
}
else {
if (newKey != null) {
AddKey(newKey, item);
}
if (oldKey != null) {
RemoveKey(oldKey);
}
}
base.SetItem(index, item);
}
private void AddKey(TKey key, TItem item) {
if (dict != null) {
dict.Add(key, item);
}
else if (keyCount == threshold) {
CreateDictionary();
dict.Add(key, item);
}
else {
if (Contains(key)) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
}
keyCount++;
}
}
private void CreateDictionary() {
dict = new Dictionary<TKey,TItem>(comparer);
foreach (TItem item in Items) {
TKey key = GetKeyForItem(item);
if (key != null) {
dict.Add(key, item);
}
}
}
private void RemoveKey(TKey key) {
Contract.Assert(key != null, "key shouldn't be null!");
if (dict != null) {
dict.Remove(key);
}
else {
keyCount--;
}
}
}
}

View File

@@ -0,0 +1,249 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
namespace System.Collections.ObjectModel
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime;
[Serializable]
[System.Runtime.InteropServices.ComVisible(false)]
[DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
[DebuggerDisplay("Count = {Count}")]
public class ReadOnlyCollection<T>: IList<T>, IList, IReadOnlyList<T>
{
IList<T> list;
[NonSerialized]
private Object _syncRoot;
public ReadOnlyCollection(IList<T> list) {
if (list == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.list);
}
this.list = list;
}
public int Count {
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
get { return list.Count; }
}
public T this[int index] {
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
get { return list[index]; }
}
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
public bool Contains(T value) {
return list.Contains(value);
}
public void CopyTo(T[] array, int index) {
list.CopyTo(array, index);
}
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
public IEnumerator<T> GetEnumerator() {
return list.GetEnumerator();
}
public int IndexOf(T value) {
return list.IndexOf(value);
}
protected IList<T> Items {
get {
return list;
}
}
bool ICollection<T>.IsReadOnly {
get { return true; }
}
T IList<T>.this[int index] {
get { return list[index]; }
set {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
}
void ICollection<T>.Add(T value) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
void ICollection<T>.Clear() {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
void IList<T>.Insert(int index, T value) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
bool ICollection<T>.Remove(T value) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
return false;
}
void IList<T>.RemoveAt(int index) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
IEnumerator IEnumerable.GetEnumerator() {
return ((IEnumerable)list).GetEnumerator();
}
bool ICollection.IsSynchronized {
get { return false; }
}
object ICollection.SyncRoot {
get {
if( _syncRoot == null) {
ICollection c = list as ICollection;
if( c != null) {
_syncRoot = c.SyncRoot;
}
else {
System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
}
return _syncRoot;
}
}
void ICollection.CopyTo(Array array, int index) {
if (array==null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
if (array.Rank != 1) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
if( array.GetLowerBound(0) != 0 ) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
if (index < 0) {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
if (array.Length - index < Count) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
T[] items = array as T[];
if (items != null) {
list.CopyTo(items, index);
}
else {
//
// Catch the obvious case assignment will fail.
// We can found all possible problems by doing the check though.
// For example, if the element type of the Array is derived from T,
// we can't figure out if we can successfully copy the element beforehand.
//
Type targetType = array.GetType().GetElementType();
Type sourceType = typeof(T);
if(!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
}
//
// We can't cast array of value type to object[], so we don't support
// widening of primitive types here.
//
object[] objects = array as object[];
if( objects == null) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
}
int count = list.Count;
try {
for (int i = 0; i < count; i++) {
objects[index++] = list[i];
}
}
catch(ArrayTypeMismatchException) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
}
}
}
bool IList.IsFixedSize {
get { return true; }
}
bool IList.IsReadOnly {
get { return true; }
}
object IList.this[int index] {
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
get { return list[index]; }
set {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
}
int IList.Add(object value) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
return -1;
}
void IList.Clear() {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
private static bool IsCompatibleObject(object value) {
// Non-null values are fine. Only accept nulls if T is a class or Nullable<U>.
// Note that default(T) is not equal to null for value types except when T is Nullable<U>.
return ((value is T) || (value == null && default(T) == null));
}
bool IList.Contains(object value) {
if(IsCompatibleObject(value)) {
return Contains((T) value);
}
return false;
}
int IList.IndexOf(object value) {
if(IsCompatibleObject(value)) {
return IndexOf((T)value);
}
return -1;
}
void IList.Insert(int index, object value) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
void IList.Remove(object value) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
void IList.RemoveAt(int index) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
}
}

File diff suppressed because it is too large Load Diff