//-----------------------------------------------------------------------
//
// 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.");
}
}
}