/******************************************************************************
* Copyright (C) Ultraleap, Inc. 2011-2021. *
* *
* Use subject to the terms of the Apache License 2.0 available at *
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
* between Ultraleap and you, your company or other organization. *
******************************************************************************/
using Leap.Unity.Query;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Leap.Unity
{
public static class ReadonlySliceExtensions
{
///
/// Creates a readonlySlice into the ReadonlyList with an inclusive beginIdx and an _exclusive_
/// endIdx. A readonlySlice with identical begin and end indices would be an empty readonlySlice.
///
/// A readonlySlice whose endIdx is smaller than its beginIdx will index backwards along the
/// underlying ReadonlyList.
///
/// Not providing either index argument will simply refer to the beginning of the
/// list (for beginIdx) or to the end of the list (for endIdx).
///
/// ReadonlySlices do not allocate, and they provide an enumerator definition so they can be
/// used in a foreach statement.
///
public static ReadonlySlice ReadonlySlice(this ReadonlyList list, int beginIdx = -1, int endIdx = -1)
{
if (beginIdx == -1 && endIdx == -1)
{
return new ReadonlySlice(list, 0, list.Count);
}
else if (beginIdx == -1 && endIdx != -1)
{
return new ReadonlySlice(list, 0, endIdx);
}
else if (endIdx == -1 && beginIdx != -1)
{
return new ReadonlySlice(list, beginIdx, list.Count);
}
else
{
return new ReadonlySlice(list, beginIdx, endIdx);
}
}
public static ReadonlySlice FromIndex(this ReadonlyList list, int fromIdx)
{
return ReadonlySlice(list, fromIdx);
}
}
public struct ReadonlySlice : IIndexableStruct>
{
private ReadonlyList _list;
private int _beginIdx;
private int _endIdx;
private int _direction;
///
/// Creates a readonlySlice into the ReadonlyList with an inclusive beginIdx and an _exclusive_
/// endIdx. A readonlySlice with identical begin and end indices would be an empty readonlySlice.
///
/// A readonlySlice whose endIdx is smaller than its beginIdx will index backwards along the
/// underlying ReadonlyList.
///
public ReadonlySlice(ReadonlyList list, int beginIdx, int endIdx)
{
_list = list;
_beginIdx = beginIdx;
_endIdx = endIdx;
_direction = beginIdx <= endIdx ? 1 : -1;
}
public T this[int index]
{
get
{
if (index < 0 || index > Count - 1) { throw new IndexOutOfRangeException(); }
return _list[_beginIdx + index * _direction];
}
}
public int Count
{
get
{
return (_endIdx - _beginIdx) * _direction;
}
}
#region foreach and Query()
public IndexableStructEnumerator> GetEnumerator()
{
return new IndexableStructEnumerator>(this);
}
public Query Query()
{
T[] array = ArrayPool.Spawn(Count);
for (int i = 0; i < Count; i++)
{
array[i] = this[i];
}
return new Query(array, Count);
}
#endregion
}
}