forked from enlightenment/efl
c#: Implement IList<T> to Eina.List.
Summary: Container can have three configuration over `Own` and `OwnContent`: `Own = true` and `OwnContent = true`; `Own = true` and `OwnContent = false`; `Own = false`and `OwnContent = false; If someone try to instanciate the container with `Own = false` and `OwnContent = true`, a exception raises. There is two Ownerships' behaviours in c#, where `IsReadOnly` is responsible and `IsReadOnly = !OwnContent`: Full Ownership: User can use modify/Add/Remove operations over the container, this is implemented with `OwnContent = true`. No Ownership: User **cannot** use modify/Add/Remove operations, this is implemented with `OwnContent = false`. For the memory, `Own` frees the node, while `OwnContent` frees the data portion. ref T8487 Reviewers: lauromoura, felipealmeida, YOhoho, segfaultxavi, jptiz Reviewed By: lauromoura Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T8487 Differential Revision: https://phab.enlightenment.org/D10742
This commit is contained in:
parent
42f56d0a0a
commit
8fabc422b6
|
@ -747,7 +747,7 @@ struct convert_in_variable_generator
|
|||
)
|
||||
return true;
|
||||
|
||||
if (!complex->subtypes.front().is_value_type && complex->subtypes.front().has_own
|
||||
if ((param.type.has_own && (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own))
|
||||
&& !as_generator(
|
||||
escape_keyword(param.param_name) << ".OwnContent = false;\n"
|
||||
).generate(sink, attributes::unused, context))
|
||||
|
@ -987,7 +987,7 @@ struct convert_out_assign_generator
|
|||
return as_generator(
|
||||
string << " = new " << type << "(" << string
|
||||
<< ", " << (param.type.has_own ? "true" : "false")
|
||||
<< ", " << (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own ? "true" : "false")
|
||||
<< ", " << (param.type.has_own && (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own) ? "true" : "false")
|
||||
<< ");\n"
|
||||
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context);
|
||||
}
|
||||
|
@ -1116,7 +1116,7 @@ struct convert_return_generator
|
|||
if (!complex)
|
||||
return false;
|
||||
if (!as_generator("return new " << type << "(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"}
|
||||
<< ", " << (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own ? "true" : "false")
|
||||
<< ", " << (ret_type.has_own && (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own) ? "true" : "false")
|
||||
<< ");\n")
|
||||
.generate(sink, ret_type, context))
|
||||
return false;
|
||||
|
@ -1268,9 +1268,9 @@ struct native_convert_out_assign_generator
|
|||
)
|
||||
return true;
|
||||
|
||||
if (!complex->subtypes.front().is_value_type && complex->subtypes.front().has_own
|
||||
if ((param.type.has_own && (complex->subtypes.front().is_value_type && complex->subtypes.front().has_own))
|
||||
&& !as_generator(
|
||||
string << ".OwnContent = false;\n"
|
||||
string << ".OwnContent = false;\n"
|
||||
).generate(sink, outvar, context))
|
||||
return false;
|
||||
}
|
||||
|
@ -1395,7 +1395,7 @@ struct native_convert_return_generator
|
|||
&& ret_type.c_type != "Eina_Accessor *" && ret_type.c_type != "const Eina_Accessor *"
|
||||
)
|
||||
{
|
||||
if (!complex->subtypes.front().is_value_type && complex->subtypes.front().has_own
|
||||
if ((ret_type.has_own && (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own))
|
||||
&& !as_generator("_ret_var.OwnContent = false; ")
|
||||
.generate(sink, attributes::unused, context))
|
||||
return false;
|
||||
|
|
|
@ -124,19 +124,22 @@ public static class ListNativeFunctions
|
|||
/// <summary>Native wrapper around a linked list of items.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
public class List<T> : IEnumerable<T>, IDisposable
|
||||
public class List<T> : IList<T>, IEnumerable<T>, IDisposable
|
||||
{
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public IntPtr Handle {get;set;} = IntPtr.Zero;
|
||||
public IntPtr Handle {get; set; } = IntPtr.Zero;
|
||||
|
||||
/// <summary>Whether this managed list owns the native one.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
public bool Own {get;set;}
|
||||
internal bool Own { get; set; }
|
||||
|
||||
/// <summary>Whether the native list wrapped owns the content it points to.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
///</summary>
|
||||
public bool OwnContent {get;set;}
|
||||
internal bool OwnContent { get; set; }
|
||||
|
||||
|
||||
/// <summary>Delegate for comparing two elements of this list.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
|
@ -146,14 +149,15 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// <returns>-1, 0 or 1 for respectively smaller, equal or larger.</returns>
|
||||
public delegate int Compare(T a, T b);
|
||||
|
||||
/// <summary>The number of elements on this list.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
public int Length
|
||||
{
|
||||
get { return Count(); }
|
||||
}
|
||||
public bool IsReadOnly { get => !OwnContent; }
|
||||
|
||||
/// <summary>The number of elements in this list.
|
||||
/// <para>Since EFL 1.24.</para>
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get => (int)eina_list_count_custom_export_mono(Handle);
|
||||
}
|
||||
|
||||
private void InitNew()
|
||||
{
|
||||
|
@ -163,38 +167,85 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
}
|
||||
|
||||
private IntPtr InternalLast()
|
||||
{
|
||||
return eina_list_last_custom_export_mono(Handle);
|
||||
}
|
||||
=> eina_list_last_custom_export_mono(Handle);
|
||||
|
||||
private static IntPtr InternalNext(IntPtr list)
|
||||
{
|
||||
return eina_list_next_custom_export_mono(list);
|
||||
}
|
||||
=> eina_list_next_custom_export_mono(list);
|
||||
|
||||
private static IntPtr InternalPrev(IntPtr list)
|
||||
{
|
||||
return eina_list_prev_custom_export_mono(list);
|
||||
}
|
||||
=> eina_list_prev_custom_export_mono(list);
|
||||
|
||||
private static IntPtr InternalDataGet(IntPtr list)
|
||||
{
|
||||
return eina_list_data_get_custom_export_mono(list);
|
||||
}
|
||||
=> eina_list_data_get_custom_export_mono(list);
|
||||
|
||||
private static IntPtr InternalDataSet(IntPtr list, IntPtr data)
|
||||
=> eina_list_data_set_custom_export_mono(list, data);
|
||||
|
||||
private IntPtr GetNative(int idx, Func<IntPtr, uint, IntPtr> f)
|
||||
{
|
||||
return eina_list_data_set_custom_export_mono(list, data);
|
||||
if (!(0 <= idx && idx < Count))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
var ele = f(Handle, (uint)idx);
|
||||
if (ele == IntPtr.Zero)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
return ele;
|
||||
}
|
||||
|
||||
private IntPtr GetNativeDataPointer(int idx)
|
||||
=> GetNative(idx, eina_list_nth);
|
||||
|
||||
private IntPtr GetNativePointer(int idx)
|
||||
=> GetNative(idx, eina_list_nth_list);
|
||||
|
||||
private void RequireWritable()
|
||||
{
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new NotSupportedException("Cannot modify read-only container.");
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckOwnerships()
|
||||
{
|
||||
if ((Own == false) && (OwnContent == true))
|
||||
{
|
||||
throw new InvalidOperationException(nameof(Own) + "/" + nameof(OwnContent));
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteData(IntPtr ele)
|
||||
{
|
||||
if (OwnContent)
|
||||
{
|
||||
NativeFree<T>(InternalDataGet(ele));
|
||||
}
|
||||
}
|
||||
|
||||
private U LoopingThrough<U>(T val, Func<int, U> f1, Func<U> f2)
|
||||
{
|
||||
int i = 0;
|
||||
IntPtr cur = Handle;
|
||||
for (; cur != IntPtr.Zero; ++i, cur = InternalNext(cur))
|
||||
{
|
||||
if (NativeToManaged<T>(InternalDataGet(cur)).Equals(val))
|
||||
{
|
||||
return f1(i);
|
||||
}
|
||||
}
|
||||
|
||||
return f2();
|
||||
}
|
||||
|
||||
/// <summary>Creates a new empty list.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
public List()
|
||||
{
|
||||
InitNew();
|
||||
}
|
||||
public List() => InitNew();
|
||||
|
||||
/// <summary>Creates a new list wrapping the given handle.</summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
|
@ -203,6 +254,7 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
Handle = handle;
|
||||
Own = own;
|
||||
OwnContent = own;
|
||||
CheckOwnerships();
|
||||
}
|
||||
|
||||
/// <summary>Creates a new list wrapping the given handle.</summary>
|
||||
|
@ -212,15 +264,13 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
Handle = handle;
|
||||
Own = own;
|
||||
OwnContent = ownContent;
|
||||
CheckOwnerships();
|
||||
}
|
||||
|
||||
/// <summary>Finalizes this list.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
~List()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
~List() => Dispose(false);
|
||||
|
||||
/// <summary>Disposes of this list.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
|
@ -236,12 +286,14 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
return;
|
||||
}
|
||||
|
||||
if (Own && OwnContent)
|
||||
for (IntPtr curr = h; curr != IntPtr.Zero; curr = InternalNext(curr))
|
||||
{
|
||||
for (IntPtr curr = h; curr != IntPtr.Zero; curr = InternalNext(curr))
|
||||
if (!OwnContent)
|
||||
{
|
||||
NativeFree<T>(InternalDataGet(curr));
|
||||
break;
|
||||
}
|
||||
|
||||
DeleteData(curr);
|
||||
}
|
||||
|
||||
if (Own)
|
||||
|
@ -269,30 +321,17 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// <summary>Disposes of this list.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
public void Free()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
/// <summary>Relinquishes of the native list.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
/// <returns>The previously wrapped native list handle.</returns>
|
||||
public IntPtr Release()
|
||||
{
|
||||
IntPtr h = Handle;
|
||||
Handle = IntPtr.Zero;
|
||||
return h;
|
||||
}
|
||||
public void Free() => Dispose();
|
||||
|
||||
/// <summary>Sets whether this wrapper should own the native list or not.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
/// <param name="ownAll">If the hash own for all ownerships.</param>
|
||||
public void SetOwnership(bool ownAll)
|
||||
internal void SetOwnership(bool ownAll)
|
||||
{
|
||||
Own = ownAll;
|
||||
OwnContent = ownAll;
|
||||
CheckOwnerships();
|
||||
}
|
||||
|
||||
/// <summary>Sets whether this wrapper should own the native list and
|
||||
|
@ -301,19 +340,11 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// </summary>
|
||||
/// <param name="own">If own the object.</param>
|
||||
/// <param name="ownContent">If own the content's object.</param>
|
||||
public void SetOwnership(bool own, bool ownContent)
|
||||
internal void SetOwnership(bool own, bool ownContent)
|
||||
{
|
||||
Own = own;
|
||||
OwnContent = ownContent;
|
||||
}
|
||||
|
||||
/// <summary>Returns the number of elements in this list.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
/// <returns>The number of elements.</returns>
|
||||
public int Count()
|
||||
{
|
||||
return (int)eina_list_count_custom_export_mono(Handle);
|
||||
CheckOwnerships();
|
||||
}
|
||||
|
||||
/// <summary>Appends <c>val</c> to the list.
|
||||
|
@ -322,8 +353,9 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// <param name="val">The item to be appended.</param>
|
||||
public void Append(T val)
|
||||
{
|
||||
IntPtr ele = ManagedToNativeAlloc(val);
|
||||
Handle = eina_list_append(Handle, ele);
|
||||
RequireWritable();
|
||||
|
||||
Handle = eina_list_append(Handle, ManagedToNativeAlloc(val));
|
||||
}
|
||||
|
||||
/// <summary>Prepends <c>val</c> to the list.
|
||||
|
@ -332,8 +364,9 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// <param name="val">The item to be prepended.</param>
|
||||
public void Prepend(T val)
|
||||
{
|
||||
IntPtr ele = ManagedToNativeAlloc(val);
|
||||
Handle = eina_list_prepend(Handle, ele);
|
||||
RequireWritable();
|
||||
|
||||
Handle = eina_list_prepend(Handle, ManagedToNativeAlloc(val));
|
||||
}
|
||||
|
||||
/// <summary>Inserts <c>val</c> in the list in a sorted manner.
|
||||
|
@ -343,8 +376,11 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// <param name="val">The item to be inserted.</param>
|
||||
public void SortedInsert(T val)
|
||||
{
|
||||
IntPtr ele = ManagedToNativeAlloc(val);
|
||||
Handle = eina_list_sorted_insert(Handle, EinaCompareCb<T>(), ele);
|
||||
RequireWritable();
|
||||
|
||||
Handle = eina_list_sorted_insert(Handle,
|
||||
EinaCompareCb<T>(),
|
||||
ManagedToNativeAlloc(val));
|
||||
}
|
||||
|
||||
/// <summary>Inserts <c>val</c> in the list in a sorted manner with the
|
||||
|
@ -356,8 +392,11 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// <param name="val">The item to be inserted.</param>
|
||||
public void SortedInsert(Compare compareCb, T val)
|
||||
{
|
||||
IntPtr ele = ManagedToNativeAlloc(val);
|
||||
Handle = eina_list_sorted_insert(Handle, Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb)), ele);
|
||||
RequireWritable();
|
||||
|
||||
Handle = eina_list_sorted_insert(Handle,
|
||||
Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb)),
|
||||
ManagedToNativeAlloc(val));
|
||||
}
|
||||
|
||||
/// <summary>Sorts <c>limit</c> elements in this list inplace.
|
||||
|
@ -366,6 +405,8 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// <param name="limit">The max number of elements to be sorted.</param>
|
||||
public void Sort(int limit = 0)
|
||||
{
|
||||
RequireWritable();
|
||||
|
||||
Handle = eina_list_sort(Handle, (uint)limit, EinaCompareCb<T>());
|
||||
}
|
||||
|
||||
|
@ -375,7 +416,10 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// <param name="compareCb">The function to compare two elements of the list.</param>
|
||||
public void Sort(Compare compareCb)
|
||||
{
|
||||
Handle = eina_list_sort(Handle, 0, Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb)));
|
||||
RequireWritable();
|
||||
|
||||
Handle = eina_list_sort(Handle, (uint)0,
|
||||
Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb)));
|
||||
}
|
||||
|
||||
/// <summary>Sorts <c>limit</c> elements in this list inplace.
|
||||
|
@ -385,15 +429,16 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// <param name="compareCb">The function to compare two elements of the list.</param>
|
||||
public void Sort(int limit, Compare compareCb)
|
||||
{
|
||||
Handle = eina_list_sort(Handle, (uint)limit, Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb)));
|
||||
RequireWritable();
|
||||
|
||||
Handle = eina_list_sort(Handle, (uint)limit,
|
||||
Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb)));
|
||||
}
|
||||
|
||||
private Eina.Callbacks.EinaCompareCb GetNativeCompareCb(Compare managedCb)
|
||||
{
|
||||
return (IntPtr a, IntPtr b) => {
|
||||
return managedCb(NativeToManaged<T>(a), NativeToManaged<T>(b));
|
||||
};
|
||||
}
|
||||
=> (IntPtr a, IntPtr b)
|
||||
=> managedCb(NativeToManaged<T>(a), NativeToManaged<T>(b));
|
||||
|
||||
|
||||
/// <summary>Returns the <c>n</c>th element of this list. Due to marshalling details, the returned element
|
||||
/// may be a different C# object from the one you used to append.
|
||||
|
@ -401,33 +446,20 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// </summary>
|
||||
/// <param name="n">The 0-based index to be retrieved.</param>
|
||||
/// <returns>The value in the specified element.</returns>
|
||||
public T Nth(int n)
|
||||
{
|
||||
// TODO: check bounds ???
|
||||
IntPtr ele = eina_list_nth(Handle, (uint)n);
|
||||
return NativeToManaged<T>(ele);
|
||||
}
|
||||
public T Nth(int n) => NativeToManaged<T>(GetNativeDataPointer(n));
|
||||
|
||||
/// <summary>Sets the data at the <c>idx</c> position.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
/// <param name="idx">The 0-based index to be set.</param>
|
||||
/// <param name="val">The value to be inserted.</param>
|
||||
public void DataSet(int idx, T val)
|
||||
internal void DataSet(int idx, T val)
|
||||
{
|
||||
IntPtr pos = eina_list_nth_list(Handle, (uint)idx);
|
||||
if (pos == IntPtr.Zero)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
RequireWritable();
|
||||
|
||||
if (OwnContent)
|
||||
{
|
||||
NativeFree<T>(InternalDataGet(pos));
|
||||
}
|
||||
|
||||
IntPtr ele = ManagedToNativeAlloc(val);
|
||||
InternalDataSet(pos, ele);
|
||||
IntPtr pos = GetNativePointer(idx);
|
||||
DeleteData(pos);
|
||||
InternalDataSet(pos, ManagedToNativeAlloc(val));
|
||||
}
|
||||
|
||||
/// <summary>Accessor for the data at the <c>idx</c> position.
|
||||
|
@ -451,10 +483,7 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// </summary>
|
||||
/// <returns>The value contained in the last list position.</returns>
|
||||
public T LastDataGet()
|
||||
{
|
||||
IntPtr ele = eina_list_last_data_get_custom_export_mono(Handle);
|
||||
return NativeToManaged<T>(ele);
|
||||
}
|
||||
=> NativeToManaged<T>(eina_list_last_data_get_custom_export_mono(Handle));
|
||||
|
||||
/// <summary>Reverses this list in place.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
|
@ -462,6 +491,8 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// <returns>A reference to this object.</returns>
|
||||
public List<T> Reverse()
|
||||
{
|
||||
RequireWritable();
|
||||
|
||||
Handle = eina_list_reverse(Handle);
|
||||
return this;
|
||||
}
|
||||
|
@ -471,6 +502,8 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// </summary>
|
||||
public void Shuffle()
|
||||
{
|
||||
RequireWritable();
|
||||
|
||||
Handle = eina_list_shuffle(Handle, IntPtr.Zero);
|
||||
}
|
||||
|
||||
|
@ -480,9 +513,10 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// <returns>A managed array of the elements.</returns>
|
||||
public T[] ToArray()
|
||||
{
|
||||
var managed = new T[Count()];
|
||||
var managed = new T[Count];
|
||||
int i = 0;
|
||||
for (IntPtr curr = Handle; curr != IntPtr.Zero; curr = InternalNext(curr), ++i)
|
||||
for (IntPtr curr = Handle; curr != IntPtr.Zero;
|
||||
curr = InternalNext(curr), ++i)
|
||||
{
|
||||
managed[i] = NativeToManaged<T>(InternalDataGet(curr));
|
||||
}
|
||||
|
@ -494,8 +528,10 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
/// <param name="values">The values to be appended.</param>
|
||||
public void AppendArray(T[] values)
|
||||
public void Append(T[] values)
|
||||
{
|
||||
RequireWritable();
|
||||
|
||||
foreach (T v in values)
|
||||
{
|
||||
Append(v);
|
||||
|
@ -508,18 +544,14 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// </summary>
|
||||
/// <returns>The iterator.</returns>
|
||||
public Eina.Iterator<T> GetIterator()
|
||||
{
|
||||
return new Eina.Iterator<T>(eina_list_iterator_new(Handle), true);
|
||||
}
|
||||
=> new Eina.Iterator<T>(eina_list_iterator_new(Handle), true);
|
||||
|
||||
/// <summary>Gets an iterator that iterates this list in reverse order.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
/// <returns>The iterator.</returns>
|
||||
public Eina.Iterator<T> GetReversedIterator()
|
||||
{
|
||||
return new Eina.Iterator<T>(eina_list_iterator_reversed_new(Handle), true);
|
||||
}
|
||||
=> new Eina.Iterator<T>(eina_list_iterator_reversed_new(Handle), true);
|
||||
|
||||
/// <summary>Gets an enumerator into this list.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
|
@ -538,18 +570,136 @@ public class List<T> : IEnumerable<T>, IDisposable
|
|||
/// </summary>
|
||||
/// <returns>The enumerator.</returns>
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return this.GetEnumerator();
|
||||
}
|
||||
=> this.GetEnumerator();
|
||||
|
||||
/// <summary> Gets an Accessor for this List.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
/// <returns>The accessor.</returns>
|
||||
public Eina.Accessor<T> GetAccessor()
|
||||
=> new Eina.Accessor<T>(eina_list_accessor_new(Handle),
|
||||
Ownership.Managed);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the first occurrence of a specific object.
|
||||
/// <para>Since EFL 1.24.</para>
|
||||
/// </summary>
|
||||
/// <param name="val">The object to remove.</param>
|
||||
public bool Remove(T val)
|
||||
{
|
||||
return new Eina.Accessor<T>(eina_list_accessor_new(Handle), Ownership.Managed);
|
||||
RequireWritable();
|
||||
|
||||
var prev_count = Count;
|
||||
var deleted = LoopingThrough(val,
|
||||
(i) =>
|
||||
{
|
||||
RemoveAt(i);
|
||||
return true;
|
||||
},
|
||||
() => false);
|
||||
|
||||
return deleted && (prev_count - 1 == Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an item.
|
||||
/// <para>Since EFL 1.24.</para>
|
||||
/// </summary>
|
||||
/// <param name="val">The object to add.</param>
|
||||
public void Add(T val) => Append(val);
|
||||
|
||||
/// <summary>
|
||||
/// Removes all items.
|
||||
/// <para>Since EFL 1.24.</para>
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
RequireWritable();
|
||||
|
||||
for (; Handle != IntPtr.Zero;)
|
||||
{
|
||||
Handle = eina_list_remove_list(Handle, Handle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the <see cref="List{T}" /> contains a specific value.
|
||||
/// <para>Since EFL 1.24.</para>
|
||||
/// </summary>
|
||||
/// <param name="val">The object to locate.</param>
|
||||
public bool Contains(T val)
|
||||
=> LoopingThrough(val, (i) => true, () => false);
|
||||
|
||||
/// <summary>
|
||||
/// Determines the index of a specific item.
|
||||
/// <para>Since EFL 1.24.</para>
|
||||
/// </summary>
|
||||
/// <param name="val">The object to locate.</param>
|
||||
public int IndexOf(T val)
|
||||
=> LoopingThrough(val, (i) => i, () => -1);
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item to the <see cref="List{T}" /> at the specified index.
|
||||
/// <para>Since EFL 1.24.</para>
|
||||
/// </summary>
|
||||
/// <param name="idx">The zero-based index at which item should be inserted.</param>
|
||||
/// <param name="val">The object to insert.</param>
|
||||
public void Insert(int idx, T val)
|
||||
{
|
||||
RequireWritable();
|
||||
|
||||
if (idx == 0)
|
||||
{
|
||||
Prepend(val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (idx == Count)
|
||||
{
|
||||
Append(val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (idx < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(idx), $"{nameof(idx)} cannot be negative.");
|
||||
}
|
||||
|
||||
if (Count < idx)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(idx), $"{nameof(idx)} cannot be greater than {nameof(Count)} + 1.");
|
||||
}
|
||||
|
||||
Handle = eina_list_prepend_relative_list(Handle, ManagedToNativeAlloc(val),
|
||||
GetNativePointer(idx));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="List{T}" /> item at the specified index.
|
||||
/// <para>Since EFL 1.24.</para>
|
||||
/// </summary>
|
||||
/// <param name="idx">The zero-based index of the item to remove.</param>
|
||||
public void RemoveAt(int idx)
|
||||
{
|
||||
RequireWritable();
|
||||
|
||||
var ele = GetNativePointer(idx);
|
||||
DeleteData(ele);
|
||||
Handle = eina_list_remove_list(Handle, ele);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the elements of the <see cref="List{T}" /> to an
|
||||
/// <see cref="Array" />, starting at a particular <see cref="Array" /> index.
|
||||
/// <para>Since EFL 1.24.</para>
|
||||
/// </summary>
|
||||
/// <param name="array">The one-dimensional <see cref="Array" /> that is the
|
||||
/// destination of the elements copied from <see cref="List{T}" />.
|
||||
/// The <see cref="Array" /> must have zero-based indexing.</param>
|
||||
/// <param name="arrayIndex">The zero-based index in array at which copying
|
||||
/// begins.</param>
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
=> ToArray().CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1726,48 +1726,48 @@ class TestEinaList
|
|||
public static void length_int()
|
||||
{
|
||||
var lst = new Eina.List<int>();
|
||||
Test.Assert(lst.Length == 0);
|
||||
Test.Assert(lst.Count == 0);
|
||||
lst.Append(88);
|
||||
Test.Assert(lst[0] == 88);
|
||||
Test.Assert(lst.Length == 1);
|
||||
Test.Assert(lst.Count == 1);
|
||||
lst.Append(44);
|
||||
Test.Assert(lst[1] == 44);
|
||||
Test.Assert(lst.Length == 2);
|
||||
Test.Assert(lst.Count == 2);
|
||||
lst.Append(22);
|
||||
Test.Assert(lst[2] == 22);
|
||||
Test.Assert(lst.Length == 3);
|
||||
Test.Assert(lst.Count == 3);
|
||||
lst.Dispose();
|
||||
}
|
||||
|
||||
public static void length_string()
|
||||
{
|
||||
var lst = new Eina.List<string>();
|
||||
Test.Assert(lst.Length == 0);
|
||||
Test.Assert(lst.Count == 0);
|
||||
lst.Append("a");
|
||||
Test.Assert(lst[0] == "a");
|
||||
Test.Assert(lst.Length == 1);
|
||||
Test.Assert(lst.Count == 1);
|
||||
lst.Append("b");
|
||||
Test.Assert(lst[1] == "b");
|
||||
Test.Assert(lst.Length == 2);
|
||||
Test.Assert(lst.Count == 2);
|
||||
lst.Append("c");
|
||||
Test.Assert(lst[2] == "c");
|
||||
Test.Assert(lst.Length == 3);
|
||||
Test.Assert(lst.Count == 3);
|
||||
lst.Dispose();
|
||||
}
|
||||
|
||||
public static void length_stringshare()
|
||||
{
|
||||
var lst = new Eina.List<Eina.Stringshare>();
|
||||
Test.Assert(lst.Length == 0);
|
||||
Test.Assert(lst.Count == 0);
|
||||
lst.Append("a");
|
||||
Test.Assert(lst[0] == "a");
|
||||
Test.Assert(lst.Length == 1);
|
||||
Test.Assert(lst.Count == 1);
|
||||
lst.Append("b");
|
||||
Test.Assert(lst[1] == "b");
|
||||
Test.Assert(lst.Length == 2);
|
||||
Test.Assert(lst.Count == 2);
|
||||
lst.Append("c");
|
||||
Test.Assert(lst[2] == "c");
|
||||
Test.Assert(lst.Length == 3);
|
||||
Test.Assert(lst.Count == 3);
|
||||
lst.Dispose();
|
||||
}
|
||||
|
||||
|
@ -2102,7 +2102,7 @@ class TestEinaList
|
|||
{
|
||||
var t = new Dummy.TestObject();
|
||||
var lst = new Eina.List<int>();
|
||||
lst.AppendArray(base_seq_int);
|
||||
lst.Append(base_seq_int);
|
||||
Test.Assert(t.EinaListIntIn(lst));
|
||||
Test.Assert(lst.Own);
|
||||
Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
|
||||
|
@ -2115,9 +2115,10 @@ class TestEinaList
|
|||
{
|
||||
var t = new Dummy.TestObject();
|
||||
var lst = new Eina.List<int>();
|
||||
lst.AppendArray(base_seq_int);
|
||||
lst.Append(base_seq_int);
|
||||
Test.Assert(t.EinaListIntInOwn(lst));
|
||||
Test.Assert(!lst.Own);
|
||||
Test.Assert(!lst.OwnContent);
|
||||
lst.Dispose();
|
||||
Test.Assert(lst.Handle == IntPtr.Zero);
|
||||
Test.Assert(t.CheckEinaListIntInOwn());
|
||||
|
@ -2130,6 +2131,7 @@ class TestEinaList
|
|||
Eina.List<int> lst;
|
||||
Test.Assert(t.EinaListIntOut(out lst));
|
||||
Test.Assert(!lst.Own);
|
||||
Test.Assert(!lst.OwnContent);
|
||||
Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
|
||||
lst.Dispose();
|
||||
Test.Assert(lst.Handle == IntPtr.Zero);
|
||||
|
@ -2144,7 +2146,7 @@ class TestEinaList
|
|||
Test.Assert(t.EinaListIntOutOwn(out lst));
|
||||
Test.Assert(lst.Own);
|
||||
Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
|
||||
lst.AppendArray(append_seq_int);
|
||||
lst.Append(append_seq_int);
|
||||
lst.Dispose();
|
||||
Test.Assert(lst.Handle == IntPtr.Zero);
|
||||
t.Dispose();
|
||||
|
@ -2155,6 +2157,7 @@ class TestEinaList
|
|||
var t = new Dummy.TestObject();
|
||||
var lst = t.EinaListIntReturn();
|
||||
Test.Assert(!lst.Own);
|
||||
Test.Assert(!lst.OwnContent);
|
||||
Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
|
||||
lst.Dispose();
|
||||
Test.Assert(lst.Handle == IntPtr.Zero);
|
||||
|
@ -2168,7 +2171,7 @@ class TestEinaList
|
|||
var lst = t.EinaListIntReturnOwn();
|
||||
Test.Assert(lst.Own);
|
||||
Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
|
||||
lst.AppendArray(append_seq_int);
|
||||
lst.Append(append_seq_int);
|
||||
lst.Dispose();
|
||||
Test.Assert(lst.Handle == IntPtr.Zero);
|
||||
t.Dispose();
|
||||
|
@ -2179,7 +2182,7 @@ class TestEinaList
|
|||
{
|
||||
var t = new Dummy.TestObject();
|
||||
var lst = new Eina.List<string>();
|
||||
lst.AppendArray(base_seq_str);
|
||||
lst.Append(base_seq_str);
|
||||
Test.Assert(t.EinaListStrIn(lst));
|
||||
Test.Assert(lst.Own);
|
||||
Test.Assert(lst.ToArray().SequenceEqual(base_seq_str));
|
||||
|
@ -2192,7 +2195,7 @@ class TestEinaList
|
|||
{
|
||||
var t = new Dummy.TestObject();
|
||||
var lst = new Eina.List<string>();
|
||||
lst.AppendArray(base_seq_str);
|
||||
lst.Append(base_seq_str);
|
||||
Test.Assert(t.EinaListStrInOwn(lst));
|
||||
Test.Assert(!lst.Own);
|
||||
lst.Dispose();
|
||||
|
@ -2221,7 +2224,7 @@ class TestEinaList
|
|||
Test.Assert(t.EinaListStrOutOwn(out lst));
|
||||
Test.Assert(lst.Own);
|
||||
Test.Assert(lst.ToArray().SequenceEqual(base_seq_str));
|
||||
lst.AppendArray(append_seq_str);
|
||||
lst.Append(append_seq_str);
|
||||
lst.Dispose();
|
||||
Test.Assert(lst.Handle == IntPtr.Zero);
|
||||
t.Dispose();
|
||||
|
@ -2245,7 +2248,7 @@ class TestEinaList
|
|||
var lst = t.EinaListStrReturnOwn();
|
||||
Test.Assert(lst.Own);
|
||||
Test.Assert(lst.ToArray().SequenceEqual(base_seq_str));
|
||||
lst.AppendArray(append_seq_str);
|
||||
lst.Append(append_seq_str);
|
||||
lst.Dispose();
|
||||
Test.Assert(lst.Handle == IntPtr.Zero);
|
||||
t.Dispose();
|
||||
|
@ -2256,7 +2259,7 @@ class TestEinaList
|
|||
{
|
||||
var t = new Dummy.TestObject();
|
||||
var lst = new Eina.List<Eina.Stringshare>();
|
||||
lst.AppendArray(base_seq_strshare);
|
||||
lst.Append(base_seq_strshare);
|
||||
Test.Assert(t.EinaListStrshareIn(lst));
|
||||
Test.Assert(lst.Own);
|
||||
Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare));
|
||||
|
@ -2269,7 +2272,7 @@ class TestEinaList
|
|||
{
|
||||
var t = new Dummy.TestObject();
|
||||
var lst = new Eina.List<Eina.Stringshare>();
|
||||
lst.AppendArray(base_seq_strshare);
|
||||
lst.Append(base_seq_strshare);
|
||||
Test.Assert(t.EinaListStrshareInOwn(lst));
|
||||
Test.Assert(!lst.Own);
|
||||
lst.Dispose();
|
||||
|
@ -2298,7 +2301,7 @@ class TestEinaList
|
|||
Test.Assert(t.EinaListStrshareOutOwn(out lst));
|
||||
Test.Assert(lst.Own);
|
||||
Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare));
|
||||
lst.AppendArray(append_seq_strshare);
|
||||
lst.Append(append_seq_strshare);
|
||||
lst.Dispose();
|
||||
Test.Assert(lst.Handle == IntPtr.Zero);
|
||||
t.Dispose();
|
||||
|
@ -2322,7 +2325,7 @@ class TestEinaList
|
|||
var lst = t.EinaListStrshareReturnOwn();
|
||||
Test.Assert(lst.Own);
|
||||
Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare));
|
||||
lst.AppendArray(append_seq_strshare);
|
||||
lst.Append(append_seq_strshare);
|
||||
lst.Dispose();
|
||||
Test.Assert(lst.Handle == IntPtr.Zero);
|
||||
t.Dispose();
|
||||
|
@ -2334,7 +2337,7 @@ class TestEinaList
|
|||
{
|
||||
var t = new Dummy.TestObject();
|
||||
var lst = new Eina.List<Dummy.Numberwrapper>();
|
||||
lst.AppendArray(BaseSeqObj());
|
||||
lst.Append(BaseSeqObj());
|
||||
Test.Assert(t.EinaListObjIn(lst));
|
||||
Test.Assert(lst.Own);
|
||||
NumberwrapperSequenceAssertEqual(lst.ToArray(), BaseSeqObj());
|
||||
|
@ -2347,7 +2350,7 @@ class TestEinaList
|
|||
{
|
||||
var t = new Dummy.TestObject();
|
||||
var lst = new Eina.List<Dummy.Numberwrapper>();
|
||||
lst.AppendArray(BaseSeqObj());
|
||||
lst.Append(BaseSeqObj());
|
||||
Test.Assert(t.EinaListObjInOwn(lst));
|
||||
Test.Assert(!lst.Own);
|
||||
lst.Dispose();
|
||||
|
@ -2376,7 +2379,7 @@ class TestEinaList
|
|||
Test.Assert(t.EinaListObjOutOwn(out lst));
|
||||
Test.Assert(lst.Own);
|
||||
NumberwrapperSequenceAssertEqual(lst.ToArray(), BaseSeqObj());
|
||||
lst.AppendArray(AppendSeqObj());
|
||||
lst.Append(AppendSeqObj());
|
||||
lst.Dispose();
|
||||
Test.Assert(lst.Handle == IntPtr.Zero);
|
||||
t.Dispose();
|
||||
|
@ -2400,7 +2403,7 @@ class TestEinaList
|
|||
var lst = t.EinaListObjReturnOwn();
|
||||
Test.Assert(lst.Own);
|
||||
NumberwrapperSequenceAssertEqual(lst.ToArray(), BaseSeqObj());
|
||||
lst.AppendArray(AppendSeqObj());
|
||||
lst.Append(AppendSeqObj());
|
||||
lst.Dispose();
|
||||
Test.Assert(lst.Handle == IntPtr.Zero);
|
||||
t.Dispose();
|
||||
|
@ -2411,11 +2414,11 @@ class TestEinaList
|
|||
var t = new Dummy.TestObject();
|
||||
var cmp = BaseSeqObj();
|
||||
var a = new Eina.List<Dummy.Numberwrapper>();
|
||||
a.AppendArray(cmp);
|
||||
a.Append(cmp);
|
||||
var b = t.EinaListObjReturnIn(a);
|
||||
NumberwrapperSequenceAssertEqual(a.ToArray(), b.ToArray());
|
||||
NumberwrapperSequenceAssertEqual(a.ToArray(), BaseSeqObj());
|
||||
int len = a.Length;
|
||||
int len = a.Count;
|
||||
for (int i=0; i < len; ++i)
|
||||
{
|
||||
Test.Assert(a[i].NativeHandle == b[i].NativeHandle);
|
||||
|
@ -3551,7 +3554,7 @@ class TestEinaIterator
|
|||
public static void eina_list_int_filled_iterator()
|
||||
{
|
||||
var lst = new Eina.List<int>();
|
||||
lst.AppendArray(base_seq_int);
|
||||
lst.Append(base_seq_int);
|
||||
var itr = lst.GetIterator();
|
||||
int idx = 0;
|
||||
foreach (int e in itr)
|
||||
|
@ -3583,7 +3586,7 @@ class TestEinaIterator
|
|||
public static void eina_list_str_filled_iterator()
|
||||
{
|
||||
var lst = new Eina.List<string>();
|
||||
lst.AppendArray(base_seq_str);
|
||||
lst.Append(base_seq_str);
|
||||
var itr = lst.GetIterator();
|
||||
int idx = 0;
|
||||
foreach (string e in itr)
|
||||
|
@ -3615,7 +3618,7 @@ class TestEinaIterator
|
|||
public static void eina_list_strshare_filled_iterator()
|
||||
{
|
||||
var lst = new Eina.List<Eina.Stringshare>();
|
||||
lst.AppendArray(base_seq_strshare);
|
||||
lst.Append(base_seq_strshare);
|
||||
var itr = lst.GetIterator();
|
||||
int idx = 0;
|
||||
foreach (string e in itr)
|
||||
|
@ -3648,7 +3651,7 @@ class TestEinaIterator
|
|||
{
|
||||
var lst = new Eina.List<Dummy.Numberwrapper>();
|
||||
var base_objs = BaseSeqObj();
|
||||
lst.AppendArray(base_objs);
|
||||
lst.Append(base_objs);
|
||||
var itr = lst.GetIterator();
|
||||
int idx = 0;
|
||||
foreach (Dummy.Numberwrapper e in itr)
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace TestSuite {
|
||||
|
||||
class TestList
|
||||
{
|
||||
public static void TestAdd()
|
||||
{
|
||||
IList<int> list = new Eina.List<int>();
|
||||
Test.AssertEquals(list.Count, 0);
|
||||
list.Add(1);
|
||||
Test.AssertEquals(list.Count, 1);
|
||||
list.Add(2);
|
||||
Test.AssertEquals(list.Count, 2);
|
||||
}
|
||||
|
||||
public static void TestRemoveAt()
|
||||
{
|
||||
IList<int> list = new Eina.List<int>();
|
||||
Test.AssertEquals(list.Count, 0);
|
||||
list.Add(1);
|
||||
Test.AssertEquals(list.Count, 1);
|
||||
Test.AssertEquals(list[0], 1);
|
||||
list.RemoveAt(0);
|
||||
Test.AssertEquals(list.Count, 0);
|
||||
list.Add(1);
|
||||
list.Add(0);
|
||||
list.Add(1);
|
||||
Test.AssertEquals(list.Count, 3);
|
||||
Test.AssertEquals(list[2], 1);
|
||||
list.RemoveAt(2);
|
||||
Test.AssertEquals(list.Count, 2);
|
||||
Test.AssertEquals(list[0], 1);
|
||||
}
|
||||
|
||||
public static void TestRemove()
|
||||
{
|
||||
IList<int> list = new Eina.List<int>();
|
||||
Test.Assert(!list.Remove(0));
|
||||
Test.AssertEquals(list.Count, 0);
|
||||
list.Add(1);
|
||||
Test.AssertEquals(list.Count, 1);
|
||||
Test.Assert(list.Remove(1));
|
||||
Test.AssertEquals(list.Count, 0);
|
||||
list.Add(1);
|
||||
list.Add(1);
|
||||
Test.AssertEquals(list.Count, 2);
|
||||
Test.Assert(list.Remove(1));
|
||||
Test.AssertEquals(list.Count, 1);
|
||||
list.Add(0);
|
||||
list.Add(1);
|
||||
Test.AssertEquals(list[1], 0);
|
||||
Test.AssertEquals(list.Count, 3);
|
||||
Test.Assert(!list.Remove(2));
|
||||
Test.Assert(list.Remove(1));
|
||||
Test.AssertEquals(list[1], 1);
|
||||
Test.AssertEquals(list.Count, 2);
|
||||
}
|
||||
|
||||
public static void TestContains()
|
||||
{
|
||||
IList<int> list = new Eina.List<int>();
|
||||
Test.AssertEquals(list.Count, 0);
|
||||
Test.Assert(!list.Contains(0));
|
||||
list.Add(0);
|
||||
Test.Assert(list.Contains(0));
|
||||
Test.Assert(list.Remove(0));
|
||||
Test.Assert(!list.Contains(0));
|
||||
list.Add(1);
|
||||
list.Add(0);
|
||||
Test.Assert(list.Contains(0));
|
||||
}
|
||||
|
||||
public static void TestClear()
|
||||
{
|
||||
IList<int> list = new Eina.List<int>();
|
||||
Test.AssertEquals(list.Count, 0);
|
||||
list.Clear();
|
||||
Test.AssertEquals(list.Count, 0);
|
||||
list.Add(0);
|
||||
Test.AssertEquals(list.Count, 1);
|
||||
list.Clear();
|
||||
Test.AssertEquals(list.Count, 0);
|
||||
list.Add(0);
|
||||
list.Add(0);
|
||||
Test.AssertEquals(list.Count, 2);
|
||||
list.Clear();
|
||||
Test.AssertEquals(list.Count, 0);
|
||||
list.Add(0);
|
||||
list.Add(0);
|
||||
Test.AssertEquals(list.Count, 2);
|
||||
Test.Assert(list.Remove(0));
|
||||
Test.AssertEquals(list.Count, 1);
|
||||
list.Clear();
|
||||
Test.AssertEquals(list.Count, 0);
|
||||
}
|
||||
|
||||
public static void TestInsert()
|
||||
{
|
||||
IList<int> list = new Eina.List<int>();
|
||||
list.Add(99);
|
||||
Test.AssertEquals(list.Count, 1);
|
||||
list.Insert(0, 6);
|
||||
Test.AssertEquals(list.Count, 2);
|
||||
Test.AssertEquals(list[0], 6);
|
||||
list.Insert(1, 5);
|
||||
Test.AssertEquals(list.Count, 3);
|
||||
Test.AssertEquals(list[1], 5);
|
||||
list.Insert(1, 10);
|
||||
Test.AssertEquals(list.Count, 4);
|
||||
Test.AssertEquals(list[1], 10);
|
||||
list.RemoveAt(1);
|
||||
Test.AssertEquals(list.Count, 3);
|
||||
Test.AssertEquals(list[1], 5);
|
||||
list.Insert(1, 42);
|
||||
Test.AssertEquals(list.Count, 4);
|
||||
Test.AssertEquals(list[1], 42);
|
||||
}
|
||||
|
||||
public static void TestIndexOf()
|
||||
{
|
||||
IList<int> list = new Eina.List<int>();
|
||||
Test.AssertEquals(list.Count, 0);
|
||||
list.Add(1);
|
||||
Test.AssertEquals(list.Count, 1);
|
||||
Test.AssertEquals(0, list.IndexOf(1));
|
||||
list.Insert(0, 0);
|
||||
Test.AssertEquals(list.Count, 2);
|
||||
Test.AssertEquals(0, list.IndexOf(0));
|
||||
Test.AssertEquals(1, list.IndexOf(1));
|
||||
list.Insert(0, 1);
|
||||
Test.AssertEquals(list.Count, 3);
|
||||
Test.AssertEquals(0, list.IndexOf(1));
|
||||
Test.AssertEquals(1, list.IndexOf(0));
|
||||
list.Insert(0, 1);
|
||||
Test.AssertEquals(list.Count, 4);
|
||||
Test.AssertEquals(0, list.IndexOf(1));
|
||||
Test.AssertEquals(2, list.IndexOf(0));
|
||||
}
|
||||
|
||||
public static void TestCopyTo()
|
||||
{
|
||||
IList<int> list = new Eina.List<int>();
|
||||
Test.AssertEquals(list.Count, 0);
|
||||
int[] random = {4, 40, 10, 42, 99};
|
||||
list.Add(43);
|
||||
list.Insert(0, 1);
|
||||
list.Insert(1, 50);
|
||||
Test.AssertEquals(list.Count, 3);
|
||||
Array.ForEach(random, (n) => list.Add(n));
|
||||
Test.AssertEquals(list.Count, 8);
|
||||
int[] expected = {1, 50, 43, 4, 40, 10, 42, 99};
|
||||
var result = new int[expected.Length];
|
||||
list.CopyTo(result, 0);
|
||||
for (int i = 0; i < expected.Length; ++i)
|
||||
{
|
||||
Test.AssertEquals(expected[i], result[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void TestIdxOutBounds()
|
||||
{
|
||||
var list = new Eina.List<int>();
|
||||
list.Add(4);
|
||||
Test.AssertRaises<ArgumentOutOfRangeException>(()=>list.Nth(1));
|
||||
Test.AssertRaises<ArgumentOutOfRangeException>(()=>list.Nth(-1));
|
||||
Test.AssertNotRaises<ArgumentOutOfRangeException>
|
||||
(()=>list.Nth(list.IndexOf(4)));
|
||||
}
|
||||
|
||||
public static void TestReadOnly()
|
||||
{
|
||||
var list = new Eina.List<int>();
|
||||
int[] array = {6, 5, 4, 3, 2};
|
||||
list.Append(array);
|
||||
Test.AssertEquals(list.Count, 5);
|
||||
Test.AssertRaises<InvalidOperationException>(() => list.SetOwnership(false, true));
|
||||
list.SetOwnership(false);
|
||||
Test.AssertRaises<NotSupportedException>(() => list.Add(4));
|
||||
Test.AssertRaises<NotSupportedException>(() => list.Append(6));
|
||||
Test.AssertRaises<NotSupportedException>(() => list.Append(array));
|
||||
Test.AssertRaises<NotSupportedException>(() => list.Remove(6));
|
||||
Test.AssertEquals(list.Count, 5);
|
||||
Test.AssertRaises<NotSupportedException>(() => list.RemoveAt(2));
|
||||
Test.AssertRaises<NotSupportedException>(() => list.Insert(4, 4));
|
||||
Test.AssertRaises<NotSupportedException>(() => list.Clear());
|
||||
Test.AssertRaises<NotSupportedException>(() => list.Sort());
|
||||
Test.Assert(list.ToArray().SequenceEqual(array));
|
||||
}
|
||||
}
|
||||
};
|
|
@ -81,7 +81,8 @@ efl_mono_src = [
|
|||
'Value.cs',
|
||||
'ValueEolian.cs',
|
||||
'Inheritance.cs',
|
||||
'Hash.cs'
|
||||
'Hash.cs',
|
||||
'List.cs',
|
||||
]
|
||||
|
||||
if get_option('dotnet')
|
||||
|
|
Loading…
Reference in New Issue