ReadOnlyCollectionBuilder.cs :  » Script » IronRuby » System » Runtime » CompilerServices » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Script » IronRuby 
IronRuby » System » Runtime » CompilerServices » ReadOnlyCollectionBuilder.cs
/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 *
 * ***************************************************************************/

#if CLR2
using Microsoft.Scripting.Ast;
#else
using System.Linq.Expressions;
#endif
#if SILVERLIGHT
using System.Core;
#endif

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Dynamic.Utils;

namespace System.Runtime.CompilerServices{
    /// <summary>
    /// The builder for read only collection.
    /// </summary>
    /// <typeparam name="T">The type of the collection element.</typeparam>
#if !SILVERLIGHT
    [Serializable]
#endif
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
    public sealed class ReadOnlyCollectionBuilder<T> : IList<T>, System.Collections.IList {
        private const int DefaultCapacity = 4;

        private T[] _items;
        private int _size;
        private int _version;

#if !SILVERLIGHT
        [NonSerialized]
#endif
        private Object _syncRoot;

        static readonly T[] _emptyArray = new T[0];

        /// <summary>
        /// Constructs a ReadOnlyCollectionBuilder.
        /// </summary>
        public ReadOnlyCollectionBuilder() {
            _items = _emptyArray;
        }

        /// <summary>
        /// Constructs a ReadOnlyCollectionBuilder with a given initial capacity.
        /// The contents are empty but builder will have reserved room for the given
        /// number of elements before any reallocations are required.
        /// </summary> 
        public ReadOnlyCollectionBuilder(int capacity) {
            ContractUtils.Requires(capacity >= 0, "capacity");
            _items = new T[capacity];
        }

        /// <summary>
        /// Constructs a ReadOnlyCollectionBuilder, copying contents of the given collection.
        /// </summary>
        /// <param name="collection"></param>
        public ReadOnlyCollectionBuilder(IEnumerable<T> collection) {
            ContractUtils.Requires(collection != null, "collection");

            ICollection<T> c = collection as ICollection<T>;
            if (c != null) {
                int count = c.Count;
                _items = new T[count];
                c.CopyTo(_items, 0);
                _size = count;
            } else {
                _size = 0;
                _items = new T[DefaultCapacity];

                using (IEnumerator<T> en = collection.GetEnumerator()) {
                    while (en.MoveNext()) {
                        Add(en.Current);
                    }
                }
            }
        }

        /// <summary>
        /// Gets and sets the capacity of this ReadOnlyCollectionBuilder
        /// </summary>
        public int Capacity {
            get { return _items.Length; }
            set {
                ContractUtils.Requires(value >= _size, "value");

                if (value != _items.Length) {
                    if (value > 0) {
                        T[] newItems = new T[value];
                        if (_size > 0) {
                            Array.Copy(_items, 0, newItems, 0, _size);
                        }
                        _items = newItems;
                    } else {
                        _items = _emptyArray;
                    }
                }
            }
        }

        /// <summary>
        /// Returns number of elements in the ReadOnlyCollectionBuilder.
        /// </summary>
        public int Count {
            get { return _size; }
        }

        #region IList<T> Members

        /// <summary>
        /// Returns the index of the first occurrence of a given value in the builder.
        /// </summary>
        /// <param name="item">An item to search for.</param>
        /// <returns>The index of the first occurrence of an item.</returns>
        public int IndexOf(T item) {
            return Array.IndexOf(_items, item, 0, _size);
        }

        /// <summary>
        /// Inserts an item to the <see cref="ReadOnlyCollectionBuilder{T}"/> at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index at which item should be inserted.</param>
        /// <param name="item">The object to insert into the <see cref="ReadOnlyCollectionBuilder{T}"/>.</param>
        public void Insert(int index, T item) {
            ContractUtils.Requires(index <= _size, "index");
            
            if (_size == _items.Length) {
                EnsureCapacity(_size + 1);
            }
            if (index < _size) {
                Array.Copy(_items, index, _items, index + 1, _size - index);
            }
            _items[index] = item;
            _size++;
            _version++;
        }

        /// <summary>
        /// Removes the <see cref="ReadOnlyCollectionBuilder{T}"/> item at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index of the item to remove.</param>
        public void RemoveAt(int index) {
            ContractUtils.Requires(index >= 0 && index < _size, "index");

            _size--;
            if (index < _size) {
                Array.Copy(_items, index + 1, _items, index, _size - index);
            }
            _items[_size] = default(T);
            _version++;
        }

        /// <summary>
        ///  Gets or sets the element at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index of the element to get or set.</param>
        /// <returns>The element at the specified index.</returns>
        public T this[int index] {
            get {
                ContractUtils.Requires(index < _size, "index");
                return _items[index];
            }
            set {
                ContractUtils.Requires(index < _size, "index");
                _items[index] = value;
                _version++;
            }
        }

        #endregion

        #region ICollection<T> Members

        /// <summary>
        /// Adds an item to the <see cref="ReadOnlyCollectionBuilder{T}"/>.
        /// </summary>
        /// <param name="item">The object to add to the <see cref="ReadOnlyCollectionBuilder{T}"/>.</param>
        public void Add(T item) {
            if (_size == _items.Length) {
                EnsureCapacity(_size + 1);
            }
            _items[_size++] = item;
            _version++;
        }

        /// <summary>
        /// Removes all items from the <see cref="ReadOnlyCollectionBuilder{T}"/>.
        /// </summary>
        public void Clear() {
            if (_size > 0) {
                Array.Clear(_items, 0, _size);
                _size = 0;
            }
            _version++;
        }

        /// <summary>
        /// Determines whether the <see cref="ReadOnlyCollectionBuilder{T}"/> contains a specific value
        /// </summary>
        /// <param name="item">the object to locate in the <see cref="ReadOnlyCollectionBuilder{T}"/>.</param>
        /// <returns>true if item is found in the <see cref="ReadOnlyCollectionBuilder{T}"/>; otherwise, false.</returns>
        public bool Contains(T item) {
            if ((Object)item == null) {
                for (int i = 0; i < _size; i++) {
                    if ((Object)_items[i] == null) {
                        return true;
                    }
                }
                return false;
            } else {
                EqualityComparer<T> c = EqualityComparer<T>.Default;
                for (int i = 0; i < _size; i++) {
                    if (c.Equals(_items[i], item)) {
                        return true;
                    }
                }
                return false;
            }
        }

        /// <summary>
        /// Copies the elements of the <see cref="ReadOnlyCollectionBuilder{T}"/> to an <see cref="Array"/>,
        /// starting at particular <see cref="Array"/> index.
        /// </summary>
        /// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="ReadOnlyCollectionBuilder{T}"/>.</param>
        /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
        public void CopyTo(T[] array, int arrayIndex) {
            Array.Copy(_items, 0, array, arrayIndex, _size);
        }

        bool ICollection<T>.IsReadOnly {
            get { return false; }
        }

        /// <summary>
        /// Removes the first occurrence of a specific object from the <see cref="ReadOnlyCollectionBuilder{T}"/>.
        /// </summary>
        /// <param name="item">The object to remove from the <see cref="ReadOnlyCollectionBuilder{T}"/>.</param>
        /// <returns>true if item was successfully removed from the <see cref="ReadOnlyCollectionBuilder{T}"/>;
        /// otherwise, false. This method also returns false if item is not found in the original <see cref="ReadOnlyCollectionBuilder{T}"/>.
        /// </returns>
        public bool Remove(T item) {
            int index = IndexOf(item);
            if (index >= 0) {
                RemoveAt(index);
                return true;
            }

            return false;
        }

        #endregion

        #region IEnumerable<T> Members

        /// <summary>
        /// Returns an enumerator that iterates through the collection.
        /// </summary>
        /// <returns>A <see cref="IEnumerator{T}"/> that can be used to iterate through the collection.</returns>
        public IEnumerator<T> GetEnumerator() {
            return new Enumerator(this);
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }

        #endregion

        #region IList Members

        bool System.Collections.IList.IsReadOnly {
            get { return false; }
        }

        int System.Collections.IList.Add(object value) {
            ValidateNullValue(value, "value");
            try {
                Add((T)value);
            } catch (InvalidCastException) {
                ThrowInvalidTypeException(value, "value");
            }
            return Count - 1;
        }

        bool System.Collections.IList.Contains(object value) {
            if (IsCompatibleObject(value)) {
                return Contains((T)value);
            } else return false;
        }

        int System.Collections.IList.IndexOf(object value) {
            if (IsCompatibleObject(value)) {
                return IndexOf((T)value);
            }
            return -1;
        }

        void System.Collections.IList.Insert(int index, object value) {
            ValidateNullValue(value, "value");
            try {
                Insert(index, (T)value);
            } catch (InvalidCastException) {
                ThrowInvalidTypeException(value, "value");
            }
        }

        bool System.Collections.IList.IsFixedSize {
            get { return false; }
        }

        void System.Collections.IList.Remove(object value) {
            if (IsCompatibleObject(value)) {
                Remove((T)value);
            }
        }

        object System.Collections.IList.this[int index] {
            get {
                return this[index];
            }
            set {
                ValidateNullValue(value, "value");

                try {
                    this[index] = (T)value;
                } catch (InvalidCastException) {
                    ThrowInvalidTypeException(value, "value");
                }
            }
        }

        #endregion

        #region ICollection Members

        void System.Collections.ICollection.CopyTo(Array array, int index) {
            ContractUtils.RequiresNotNull(array, "array");
            ContractUtils.Requires(array.Rank == 1, "array");
            Array.Copy(_items, 0, array, index, _size);
        }

        bool System.Collections.ICollection.IsSynchronized {
            get { return false; }
        }

        object System.Collections.ICollection.SyncRoot {
            get {
                if (_syncRoot == null) {
                    System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
                }
                return _syncRoot;
            }
        }

        #endregion

        /// <summary>
        /// Reverses the order of the elements in the entire <see cref="ReadOnlyCollectionBuilder{T}"/>.
        /// </summary>
        public void Reverse() {
            Reverse(0, Count);
        }

        /// <summary>
        /// Reverses the order of the elements in the specified range.
        /// </summary>
        /// <param name="index">The zero-based starting index of the range to reverse.</param>
        /// <param name="count">The number of elements in the range to reverse.</param>
        public void Reverse(int index, int count) {
            ContractUtils.Requires(index >= 0, "index");
            ContractUtils.Requires(count >= 0, "count");

            Array.Reverse(_items, index, count);
            _version++;
        }

        /// <summary>
        /// Copies the elements of the <see cref="ReadOnlyCollectionBuilder{T}"/> to a new array.
        /// </summary>
        /// <returns>An array containing copies of the elements of the <see cref="ReadOnlyCollectionBuilder{T}"/>.</returns>
        public T[] ToArray() {
            T[] array = new T[_size];
            Array.Copy(_items, 0, array, 0, _size);
            return array;
        }

        /// <summary>
        /// Creates a <see cref="ReadOnlyCollection{T}"/> containing all of the the elements of the <see cref="ReadOnlyCollectionBuilder{T}"/>,
        /// avoiding copying the elements to the new array if possible. Resets the <see cref="ReadOnlyCollectionBuilder{T}"/> after the
        /// <see cref="ReadOnlyCollection{T}"/> has been created.
        /// </summary>
        /// <returns>A new instance of <see cref="ReadOnlyCollection{T}"/>.</returns>
        public ReadOnlyCollection<T> ToReadOnlyCollection() {
            // Can we use the stored array?
            T[] items;
            if (_size == _items.Length) {
                items = _items;
            } else {
                items = ToArray();
            }
            _items = _emptyArray;
            _size = 0;
            _version++;

            return new TrueReadOnlyCollection<T>(items);
        }

        private void EnsureCapacity(int min) {
            if (_items.Length < min) {
                int newCapacity = DefaultCapacity;
                if (_items.Length > 0) {
                    newCapacity = _items.Length * 2;
                }
                if (newCapacity < min) {
                    newCapacity = min;
                }
                Capacity = newCapacity;
            }
        }

        private static bool IsCompatibleObject(object value) {
            return ((value is T) || (value == null && default(T) == null));
        }

        private static void ValidateNullValue(object value, string argument) {
            if (value == null && !(default(T) == null)) {
                throw new ArgumentException(Strings.InvalidNullValue(typeof(T)), argument);
            }
        }

        private static void ThrowInvalidTypeException(object value, string argument) {
            throw new ArgumentException(Strings.InvalidObjectType(value != null ? value.GetType() : (object)"null", typeof(T)), argument);
        }

#if !SILVERLIGHT
        [Serializable]
#endif
        private class Enumerator : IEnumerator<T>, System.Collections.IEnumerator {
            private readonly ReadOnlyCollectionBuilder<T> _builder;
            private readonly int _version;

            private int _index;
            private T _current;

            internal Enumerator(ReadOnlyCollectionBuilder<T> builder) {
                _builder = builder;
                _version = builder._version;
                _index = 0;
                _current = default(T);
            }

            #region IEnumerator<T> Members

            public T Current {
                get { return _current; }
            }

            #endregion

            #region IDisposable Members

            public void Dispose() {
                GC.SuppressFinalize(this);
            }

            #endregion

            #region IEnumerator Members

            object System.Collections.IEnumerator.Current {
                get {
                    if (_index == 0 || _index > _builder._size) {
                        throw Error.EnumerationIsDone();
                    }
                    return _current;
                }
            }

            public bool MoveNext() {
                if (_version == _builder._version) {
                    if (_index < _builder._size) {
                        _current = _builder._items[_index++];
                        return true;
                    } else {
                        _index = _builder._size + 1;
                        _current = default(T);
                        return false;
                    }
                } else {
                    throw Error.CollectionModifiedWhileEnumerating();
                }
            }

            #endregion

            #region IEnumerator Members

            void System.Collections.IEnumerator.Reset() {
                if (_version != _builder._version) {
                    throw Error.CollectionModifiedWhileEnumerating();
                }
                _index = 0;
                _current = default(T);
            }

            #endregion
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.