//******************************************************************************************************
// ImmutableList`1.cs - Gbtc
//
// Copyright © 2016, Grid Protection Alliance. All Rights Reserved.
//
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
// The GPA licenses this file to you under the Eclipse Public License -v 1.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.opensource.org/licenses/eclipse-1.0.php
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
// Code Modification History:
// ----------------------------------------------------------------------------------------------------
// 10/24/2016 - Steven E. Chisholm
// Generated original version of source code.
//
//
//******************************************************************************************************
using System;
using System.Collections;
using System.Collections.Generic;
namespace GSF.Immutable
{
///
/// A list that can be modified until is set to true. Once this occurs,
/// the list itself can no longer be modified. Remember, this does not cause objects contained in this class to be Immutable
/// unless they implement .
///
///
public class ImmutableList
: ImmutableObjectBase>, IList
{
private readonly bool m_isISupportsReadonlyType;
private List m_list;
private Func m_formatter;
///
/// Creates a new .
///
/// Allows items to be formatted when inserted into a list.
public ImmutableList(Func formatter = null)
{
m_formatter = formatter;
m_isISupportsReadonlyType = typeof(IImmutableObject).IsAssignableFrom(typeof(T));
m_list = new List();
}
///
/// Creates a new .
///
public ImmutableList(int capacity, Func formatter = null)
{
m_formatter = formatter;
m_isISupportsReadonlyType = typeof(IImmutableObject).IsAssignableFrom(typeof(T));
m_list = new List(capacity);
}
/// Returns an enumerator that iterates through the collection.
/// A that can be used to iterate through the collection.
/// 1
public IEnumerator GetEnumerator()
{
return m_list.GetEnumerator();
}
/// Returns an enumerator that iterates through a collection.
/// An object that can be used to iterate through the collection.
/// 2
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)m_list).GetEnumerator();
}
/// Adds an item to the .
/// The object to add to the .
/// The is read-only.
public void Add(T item)
{
TestForEditable();
if (m_formatter == null)
{
m_list.Add(item);
}
else
{
m_list.Add(m_formatter(item));
}
}
///
/// Adds the elements of the specified collection to the end of the .
///
/// The collection whose elements should be added to the end of the .
/// The collection itself cannot be null, but it can contain elements that are null
public void AddRange(IEnumerable collection)
{
TestForEditable();
if (m_formatter != null)
{
foreach (var item in collection)
{
m_list.Add(m_formatter(item));
}
return;
}
m_list.AddRange(collection);
}
/// Removes all items from the collection.
public void Clear()
{
TestForEditable();
m_list.Clear();
}
/// Determines whether the contains a specific value.
/// true if is found in the ; otherwise, false.
/// The object to locate in the .
public bool Contains(T item)
{
return m_list.Contains(item);
}
/// Copies the elements of the to an , starting at a particular index.
/// The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing.
/// The zero-based index in at which copying begins.
public void CopyTo(T[] array, int arrayIndex)
{
m_list.CopyTo(array, arrayIndex);
}
/// Removes the first occurrence of a specific object from the .
/// true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original .
/// The object to remove from the .
public bool Remove(T item)
{
TestForEditable();
return m_list.Remove(item);
}
/// Gets the number of elements contained in the .
/// The number of elements contained in the .
public int Count
{
get
{
return m_list.Count;
}
}
///
/// Requests that member fields be set to readonly.
///
protected override void SetMembersAsReadOnly()
{
if (m_isISupportsReadonlyType)
{
for (int x = 0; x < m_list.Count; x++)
{
var item = ((IImmutableObject)m_list[x]);
if (item != null)
{
item.IsReadOnly = true;
}
}
}
}
///
/// Request that member fields be cloned and marked as editable.
///
protected override void CloneMembersAsEditable()
{
if (m_isISupportsReadonlyType)
{
List oldList = m_list;
m_list = new List(oldList.Count);
for (int x = 0; x < oldList.Count; x++)
{
var item = ((IImmutableObject)oldList[x]);
if (item == null)
{
m_list.Add(default(T));
}
else
{
m_list.Add((T)item.CloneEditable());
}
}
}
else
{
m_list = new List(m_list);
}
}
/// Determines the index of a specific item in the .
/// The index of if found in the list; otherwise, -1.
/// The object to locate in the .
public int IndexOf(T item)
{
return m_list.IndexOf(item);
}
/// Inserts an item to the at the specified index.
/// The zero-based index at which should be inserted.
/// The object to insert into the .
public void Insert(int index, T item)
{
TestForEditable();
if (m_formatter == null)
{
m_list.Insert(index, item);
}
else
{
m_list.Insert(index, m_formatter(item));
}
}
/// Removes the item at the specified index.
/// The zero-based index of the item to remove.
public void RemoveAt(int index)
{
TestForEditable();
m_list.RemoveAt(index);
}
/// Gets or sets the element at the specified index.
/// The element at the specified index.
/// The zero-based index of the element to get or set.
public T this[int index]
{
get
{
return m_list[index];
}
set
{
TestForEditable();
if (m_formatter == null)
{
m_list[index] = value;
}
else
{
m_list[index] = m_formatter(value);
}
}
}
}
}