//----------------------------------------------------------------------- // // Copyright (c) 2018 Sirenix IVS // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //----------------------------------------------------------------------- namespace VRC.Udon.Serialization.OdinSerializer.Utilities { using System; using System.Collections; using System.Collections.Generic; using UnityEngine; /// /// Interface for immutable list. /// public interface IImmutableList : IList { } /// /// Interface for generic immutable list. /// public interface IImmutableList : IImmutableList, IList { /// /// Index accessor. /// new T this[int index] { get; } } /// /// Immutable list wraps another list, and allows for reading the inner list, without the ability to change it. /// [Serializable] public sealed class ImmutableList : IImmutableList { [SerializeField] private IList innerList; /// /// Creates an immutable list around another list. /// public ImmutableList(IList innerList) { if (innerList == null) { throw new ArgumentNullException("innerList"); } this.innerList = innerList; } /// /// Number of items in the list. /// public int Count { get { return this.innerList.Count; } } /// /// Immutable list cannot be changed directly, so it's size is always fixed. /// public bool IsFixedSize { get { return true; } } /// /// Immutable list are always readonly. /// public bool IsReadOnly { get { return true; } } /// /// Returns true if the inner list is synchronized. /// public bool IsSynchronized { get { return this.innerList.IsSynchronized; } } /// /// Gets the sync root object. /// public object SyncRoot { get { return this.innerList.SyncRoot; } } object IList.this[int index] { get { return this.innerList[index]; } set { throw new NotSupportedException("Immutable Lists cannot be edited."); } } object IList.this[int index] { get { return this.innerList[index]; } set { throw new NotSupportedException("Immutable Lists cannot be edited."); } } /// /// Index accessor. /// /// Index. public object this[int index] { get { return this.innerList[index]; } } /// /// Returns true if the item is contained in the list. /// /// The item's value. public bool Contains(object value) { return this.innerList.Contains(value); } /// /// Copy the list to an array, /// /// Target array. /// Index. public void CopyTo(object[] array, int arrayIndex) { this.innerList.CopyTo(array, arrayIndex); } /// /// Copy the list to an array, /// /// Target array. /// Index. public void CopyTo(Array array, int index) { this.innerList.CopyTo(array, index); } /// /// Gets an enumerator. /// public IEnumerator GetEnumerator() { return this.innerList.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { foreach (var obj in this.innerList) { yield return obj; } } int IList.Add(object value) { throw new NotSupportedException("Immutable Lists cannot be edited."); } void IList.Clear() { throw new NotSupportedException("Immutable Lists cannot be edited."); } void IList.Insert(int index, object value) { throw new NotSupportedException("Immutable Lists cannot be edited."); } void IList.Remove(object value) { throw new NotSupportedException("Immutable Lists cannot be edited."); } void IList.RemoveAt(int index) { throw new NotSupportedException("Immutable Lists cannot be edited."); } /// /// Get the index of a value. /// /// The item's value. public int IndexOf(object value) { return this.innerList.IndexOf(value); } /// /// Immutable list cannot be edited. /// /// Index. void IList.RemoveAt(int index) { throw new NotSupportedException("Immutable Lists cannot be edited."); } /// /// Immutable list cannot be edited. /// /// Index. /// Item. void IList.Insert(int index, object item) { throw new NotSupportedException("Immutable Lists cannot be edited."); } /// /// Immutable list cannot be edited. /// /// Item. void ICollection.Add(object item) { throw new NotSupportedException("Immutable Lists cannot be edited."); } /// /// Immutable list cannot be edited. /// void ICollection.Clear() { throw new NotSupportedException("Immutable Lists cannot be edited."); } /// /// Immutable list cannot be edited. /// /// Item. bool ICollection.Remove(object item) { throw new NotSupportedException("Immutable Lists cannot be edited."); } } /// /// Not yet documented. /// [Serializable] public sealed class ImmutableList : IImmutableList { [SerializeField] private IList innerList; /// /// Not yet documented. /// public ImmutableList(IList innerList) { if (innerList == null) { throw new ArgumentNullException("innerList"); } this.innerList = innerList; } /// /// Not yet documented. /// public int Count { get { return this.innerList.Count; } } bool ICollection.IsSynchronized { get { return false; } } object ICollection.SyncRoot { get { return null; } } bool IList.IsFixedSize { get { return true; } } bool IList.IsReadOnly { get { return true; } } /// /// Not yet documented. /// public bool IsReadOnly { get { return true; } } object IList.this[int index] { get { return this[index]; } set { throw new NotSupportedException("Immutable Lists cannot be edited."); } } T IList.this[int index] { get { return this.innerList[index]; } set { throw new NotSupportedException("Immutable Lists cannot be edited."); } } /// /// Not yet documented. /// public T this[int index] { get { return this.innerList[index]; } } /// /// Not yet documented. /// public bool Contains(T item) { return this.innerList.Contains(item); } /// /// Not yet documented. /// public void CopyTo(T[] array, int arrayIndex) { this.innerList.CopyTo(array, arrayIndex); } /// /// Not yet documented. /// public IEnumerator GetEnumerator() { return this.innerList.GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { this.innerList.CopyTo((T[])array, index); } void ICollection.Add(T item) { throw new NotSupportedException("Immutable Lists cannot be edited."); } void ICollection.Clear() { throw new NotSupportedException("Immutable Lists cannot be edited."); } bool ICollection.Remove(T item) { throw new NotSupportedException("Immutable Lists cannot be edited."); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } int IList.Add(object value) { throw new NotSupportedException("Immutable Lists cannot be edited."); } void IList.Clear() { throw new NotSupportedException("Immutable Lists cannot be edited."); } bool IList.Contains(object value) { return this.innerList.Contains((T)value); } int IList.IndexOf(object value) { return this.innerList.IndexOf((T)value); } void IList.Insert(int index, object value) { throw new NotSupportedException("Immutable Lists cannot be edited."); } void IList.Remove(object value) { throw new NotSupportedException("Immutable Lists cannot be edited."); } void IList.Insert(int index, T item) { throw new NotSupportedException("Immutable Lists cannot be edited."); } void IList.RemoveAt(int index) { throw new NotSupportedException("Immutable Lists cannot be edited."); } /// /// Not yet documented. /// public int IndexOf(T item) { return this.innerList.IndexOf(item); } void IList.RemoveAt(int index) { throw new NotSupportedException("Immutable Lists cannot be edited."); } } /// /// Immutable list wraps another list, and allows for reading the inner list, without the ability to change it. /// [Serializable] public sealed class ImmutableList : IImmutableList where TList : IList { private TList innerList; /// /// Creates an immutable list around another list. /// public ImmutableList(TList innerList) { if (innerList == null) { throw new ArgumentNullException("innerList"); } this.innerList = innerList; } /// /// Number of items in the list. /// public int Count { get { return this.innerList.Count; } } bool ICollection.IsSynchronized { get { return false; } } object ICollection.SyncRoot { get { return null; } } bool IList.IsFixedSize { get { return true; } } bool IList.IsReadOnly { get { return true; } } /// /// Immutable list are always readonly. /// public bool IsReadOnly { get { return true; } } object IList.this[int index] { get { return this[index]; } set { throw new NotSupportedException("Immutable Lists cannot be edited."); } } TElement IList.this[int index] { get { return this.innerList[index]; } set { throw new NotSupportedException("Immutable Lists cannot be edited."); } } /// /// Index accessor. /// /// Index. public TElement this[int index] { get { return this.innerList[index]; } } /// /// Returns true if the item is contained in the list. /// public bool Contains(TElement item) { return this.innerList.Contains(item); } /// /// Copies the list to an array. /// public void CopyTo(TElement[] array, int arrayIndex) { this.innerList.CopyTo(array, arrayIndex); } /// /// Gets an enumerator. /// public IEnumerator GetEnumerator() { return this.innerList.GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { this.innerList.CopyTo((TElement[])array, index); } void ICollection.Add(TElement item) { throw new NotSupportedException("Immutable Lists cannot be edited."); } void ICollection.Clear() { throw new NotSupportedException("Immutable Lists cannot be edited."); } bool ICollection.Remove(TElement item) { throw new NotSupportedException("Immutable Lists cannot be edited."); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } int IList.Add(object value) { throw new NotSupportedException("Immutable Lists cannot be edited."); } void IList.Clear() { throw new NotSupportedException("Immutable Lists cannot be edited."); } bool IList.Contains(object value) { return this.innerList.Contains((TElement)value); } int IList.IndexOf(object value) { return this.innerList.IndexOf((TElement)value); } void IList.Insert(int index, object value) { throw new NotSupportedException("Immutable Lists cannot be edited."); } void IList.Remove(object value) { throw new NotSupportedException("Immutable Lists cannot be edited."); } void IList.Insert(int index, TElement item) { throw new NotSupportedException("Immutable Lists cannot be edited."); } void IList.RemoveAt(int index) { throw new NotSupportedException("Immutable Lists cannot be edited."); } /// /// Gets the index of an item. /// public int IndexOf(TElement item) { return this.innerList.IndexOf(item); } void IList.RemoveAt(int index) { throw new NotSupportedException("Immutable Lists cannot be edited."); } } }