From 8fabc422b6565be81b94b802f0a8d3eff737e633 Mon Sep 17 00:00:00 2001 From: Bruno da Silva Belo Date: Wed, 11 Dec 2019 18:47:45 -0300 Subject: [PATCH] c#: Implement IList 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 --- src/bin/eolian_mono/eolian/mono/parameter.hh | 12 +- src/bindings/mono/eina_mono/eina_list.cs | 374 +++++++++++++------ src/tests/efl_mono/Eina.cs | 71 ++-- src/tests/efl_mono/List.cs | 193 ++++++++++ src/tests/efl_mono/meson.build | 3 +- 5 files changed, 500 insertions(+), 153 deletions(-) create mode 100644 src/tests/efl_mono/List.cs diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh index deb9a9e5a8..d27889fcb4 100644 --- a/src/bin/eolian_mono/eolian/mono/parameter.hh +++ b/src/bin/eolian_mono/eolian/mono/parameter.hh @@ -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; diff --git a/src/bindings/mono/eina_mono/eina_list.cs b/src/bindings/mono/eina_mono/eina_list.cs index 70f2d91665..d14dd26359 100644 --- a/src/bindings/mono/eina_mono/eina_list.cs +++ b/src/bindings/mono/eina_mono/eina_list.cs @@ -124,19 +124,22 @@ public static class ListNativeFunctions /// Native wrapper around a linked list of items. /// Since EFL 1.23. /// -public class List : IEnumerable, IDisposable +public class List : IList, IEnumerable, IDisposable { [EditorBrowsable(EditorBrowsableState.Never)] - public IntPtr Handle {get;set;} = IntPtr.Zero; + public IntPtr Handle {get; set; } = IntPtr.Zero; + /// Whether this managed list owns the native one. /// Since EFL 1.23. /// - public bool Own {get;set;} + internal bool Own { get; set; } + /// Whether the native list wrapped owns the content it points to. /// Since EFL 1.23. /// - public bool OwnContent {get;set;} + internal bool OwnContent { get; set; } + /// Delegate for comparing two elements of this list. /// Since EFL 1.23. @@ -146,14 +149,15 @@ public class List : IEnumerable, IDisposable /// -1, 0 or 1 for respectively smaller, equal or larger. public delegate int Compare(T a, T b); - /// The number of elements on this list. - /// Since EFL 1.23. - /// - public int Length - { - get { return Count(); } - } + public bool IsReadOnly { get => !OwnContent; } + /// The number of elements in this list. + /// Since EFL 1.24. + /// + public int Count + { + get => (int)eina_list_count_custom_export_mono(Handle); + } private void InitNew() { @@ -163,38 +167,85 @@ public class List : IEnumerable, 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 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(InternalDataGet(ele)); + } + } + + private U LoopingThrough(T val, Func f1, Func f2) + { + int i = 0; + IntPtr cur = Handle; + for (; cur != IntPtr.Zero; ++i, cur = InternalNext(cur)) + { + if (NativeToManaged(InternalDataGet(cur)).Equals(val)) + { + return f1(i); + } + } + + return f2(); + } /// Creates a new empty list. /// Since EFL 1.23. /// - public List() - { - InitNew(); - } + public List() => InitNew(); /// Creates a new list wrapping the given handle. [EditorBrowsable(EditorBrowsableState.Never)] @@ -203,6 +254,7 @@ public class List : IEnumerable, IDisposable Handle = handle; Own = own; OwnContent = own; + CheckOwnerships(); } /// Creates a new list wrapping the given handle. @@ -212,15 +264,13 @@ public class List : IEnumerable, IDisposable Handle = handle; Own = own; OwnContent = ownContent; + CheckOwnerships(); } /// Finalizes this list. /// Since EFL 1.23. /// - ~List() - { - Dispose(false); - } + ~List() => Dispose(false); /// Disposes of this list. /// Since EFL 1.23. @@ -236,12 +286,14 @@ public class List : IEnumerable, 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(InternalDataGet(curr)); + break; } + + DeleteData(curr); } if (Own) @@ -269,30 +321,17 @@ public class List : IEnumerable, IDisposable /// Disposes of this list. /// Since EFL 1.23. /// - public void Free() - { - Dispose(); - } - - /// Relinquishes of the native list. - /// Since EFL 1.23. - /// - /// The previously wrapped native list handle. - public IntPtr Release() - { - IntPtr h = Handle; - Handle = IntPtr.Zero; - return h; - } + public void Free() => Dispose(); /// Sets whether this wrapper should own the native list or not. /// Since EFL 1.23. /// /// If the hash own for all ownerships. - public void SetOwnership(bool ownAll) + internal void SetOwnership(bool ownAll) { Own = ownAll; OwnContent = ownAll; + CheckOwnerships(); } /// Sets whether this wrapper should own the native list and @@ -301,19 +340,11 @@ public class List : IEnumerable, IDisposable /// /// If own the object. /// If own the content's object. - public void SetOwnership(bool own, bool ownContent) + internal void SetOwnership(bool own, bool ownContent) { Own = own; OwnContent = ownContent; - } - - /// Returns the number of elements in this list. - /// Since EFL 1.23. - /// - /// The number of elements. - public int Count() - { - return (int)eina_list_count_custom_export_mono(Handle); + CheckOwnerships(); } /// Appends val to the list. @@ -322,8 +353,9 @@ public class List : IEnumerable, IDisposable /// The item to be appended. public void Append(T val) { - IntPtr ele = ManagedToNativeAlloc(val); - Handle = eina_list_append(Handle, ele); + RequireWritable(); + + Handle = eina_list_append(Handle, ManagedToNativeAlloc(val)); } /// Prepends val to the list. @@ -332,8 +364,9 @@ public class List : IEnumerable, IDisposable /// The item to be prepended. public void Prepend(T val) { - IntPtr ele = ManagedToNativeAlloc(val); - Handle = eina_list_prepend(Handle, ele); + RequireWritable(); + + Handle = eina_list_prepend(Handle, ManagedToNativeAlloc(val)); } /// Inserts val in the list in a sorted manner. @@ -343,8 +376,11 @@ public class List : IEnumerable, IDisposable /// The item to be inserted. public void SortedInsert(T val) { - IntPtr ele = ManagedToNativeAlloc(val); - Handle = eina_list_sorted_insert(Handle, EinaCompareCb(), ele); + RequireWritable(); + + Handle = eina_list_sorted_insert(Handle, + EinaCompareCb(), + ManagedToNativeAlloc(val)); } /// Inserts val in the list in a sorted manner with the @@ -356,8 +392,11 @@ public class List : IEnumerable, IDisposable /// The item to be inserted. 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)); } /// Sorts limit elements in this list inplace. @@ -366,6 +405,8 @@ public class List : IEnumerable, IDisposable /// The max number of elements to be sorted. public void Sort(int limit = 0) { + RequireWritable(); + Handle = eina_list_sort(Handle, (uint)limit, EinaCompareCb()); } @@ -375,7 +416,10 @@ public class List : IEnumerable, IDisposable /// The function to compare two elements of the list. 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))); } /// Sorts limit elements in this list inplace. @@ -385,15 +429,16 @@ public class List : IEnumerable, IDisposable /// The function to compare two elements of the list. 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(a), NativeToManaged(b)); - }; - } + => (IntPtr a, IntPtr b) + => managedCb(NativeToManaged(a), NativeToManaged(b)); + /// Returns the nth 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 : IEnumerable, IDisposable /// /// The 0-based index to be retrieved. /// The value in the specified element. - public T Nth(int n) - { - // TODO: check bounds ??? - IntPtr ele = eina_list_nth(Handle, (uint)n); - return NativeToManaged(ele); - } + public T Nth(int n) => NativeToManaged(GetNativeDataPointer(n)); /// Sets the data at the idx position. /// Since EFL 1.23. /// /// The 0-based index to be set. /// The value to be inserted. - 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(InternalDataGet(pos)); - } - - IntPtr ele = ManagedToNativeAlloc(val); - InternalDataSet(pos, ele); + IntPtr pos = GetNativePointer(idx); + DeleteData(pos); + InternalDataSet(pos, ManagedToNativeAlloc(val)); } /// Accessor for the data at the idx position. @@ -451,10 +483,7 @@ public class List : IEnumerable, IDisposable /// /// The value contained in the last list position. public T LastDataGet() - { - IntPtr ele = eina_list_last_data_get_custom_export_mono(Handle); - return NativeToManaged(ele); - } + => NativeToManaged(eina_list_last_data_get_custom_export_mono(Handle)); /// Reverses this list in place. /// Since EFL 1.23. @@ -462,6 +491,8 @@ public class List : IEnumerable, IDisposable /// A reference to this object. public List Reverse() { + RequireWritable(); + Handle = eina_list_reverse(Handle); return this; } @@ -471,6 +502,8 @@ public class List : IEnumerable, IDisposable /// public void Shuffle() { + RequireWritable(); + Handle = eina_list_shuffle(Handle, IntPtr.Zero); } @@ -480,9 +513,10 @@ public class List : IEnumerable, IDisposable /// A managed array of the elements. 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(InternalDataGet(curr)); } @@ -494,8 +528,10 @@ public class List : IEnumerable, IDisposable /// Since EFL 1.23. /// /// The values to be appended. - 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 : IEnumerable, IDisposable /// /// The iterator. public Eina.Iterator GetIterator() - { - return new Eina.Iterator(eina_list_iterator_new(Handle), true); - } + => new Eina.Iterator(eina_list_iterator_new(Handle), true); /// Gets an iterator that iterates this list in reverse order. /// Since EFL 1.23. /// /// The iterator. public Eina.Iterator GetReversedIterator() - { - return new Eina.Iterator(eina_list_iterator_reversed_new(Handle), true); - } + => new Eina.Iterator(eina_list_iterator_reversed_new(Handle), true); /// Gets an enumerator into this list. /// Since EFL 1.23. @@ -538,18 +570,136 @@ public class List : IEnumerable, IDisposable /// /// The enumerator. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } + => this.GetEnumerator(); /// Gets an Accessor for this List. /// Since EFL 1.23. /// /// The accessor. public Eina.Accessor GetAccessor() + => new Eina.Accessor(eina_list_accessor_new(Handle), + Ownership.Managed); + + /// + /// Removes the first occurrence of a specific object. + /// Since EFL 1.24. + /// + /// The object to remove. + public bool Remove(T val) { - return new Eina.Accessor(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); } + + /// + /// Adds an item. + /// Since EFL 1.24. + /// + /// The object to add. + public void Add(T val) => Append(val); + + /// + /// Removes all items. + /// Since EFL 1.24. + /// + public void Clear() + { + RequireWritable(); + + for (; Handle != IntPtr.Zero;) + { + Handle = eina_list_remove_list(Handle, Handle); + } + } + + /// + /// Determines whether the contains a specific value. + /// Since EFL 1.24. + /// + /// The object to locate. + public bool Contains(T val) + => LoopingThrough(val, (i) => true, () => false); + + /// + /// Determines the index of a specific item. + /// Since EFL 1.24. + /// + /// The object to locate. + public int IndexOf(T val) + => LoopingThrough(val, (i) => i, () => -1); + + /// + /// Inserts an item to the at the specified index. + /// Since EFL 1.24. + /// + /// The zero-based index at which item should be inserted. + /// The object to insert. + 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)); + } + + /// + /// Removes the item at the specified index. + /// Since EFL 1.24. + /// + /// The zero-based index of the item to remove. + public void RemoveAt(int idx) + { + RequireWritable(); + + var ele = GetNativePointer(idx); + DeleteData(ele); + Handle = eina_list_remove_list(Handle, ele); + } + + /// + /// Copies the elements of the to an + /// , starting at a particular index. + /// Since EFL 1.24. + /// + /// The one-dimensional that is the + /// destination of the elements copied from . + /// The must have zero-based indexing. + /// The zero-based index in array at which copying + /// begins. + public void CopyTo(T[] array, int arrayIndex) + => ToArray().CopyTo(array, arrayIndex); } } diff --git a/src/tests/efl_mono/Eina.cs b/src/tests/efl_mono/Eina.cs index b329bc3d9d..16d65a8205 100644 --- a/src/tests/efl_mono/Eina.cs +++ b/src/tests/efl_mono/Eina.cs @@ -1726,48 +1726,48 @@ class TestEinaList public static void length_int() { var lst = new Eina.List(); - 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(); - 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(); - 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(); - 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(); - 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 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); 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) diff --git a/src/tests/efl_mono/List.cs b/src/tests/efl_mono/List.cs new file mode 100644 index 0000000000..3394cff537 --- /dev/null +++ b/src/tests/efl_mono/List.cs @@ -0,0 +1,193 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace TestSuite { + +class TestList +{ + public static void TestAdd() + { + IList list = new Eina.List(); + 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 list = new Eina.List(); + 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 list = new Eina.List(); + 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 list = new Eina.List(); + 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 list = new Eina.List(); + 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 list = new Eina.List(); + 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 list = new Eina.List(); + 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 list = new Eina.List(); + 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(); + list.Add(4); + Test.AssertRaises(()=>list.Nth(1)); + Test.AssertRaises(()=>list.Nth(-1)); + Test.AssertNotRaises + (()=>list.Nth(list.IndexOf(4))); + } + + public static void TestReadOnly() + { + var list = new Eina.List(); + int[] array = {6, 5, 4, 3, 2}; + list.Append(array); + Test.AssertEquals(list.Count, 5); + Test.AssertRaises(() => list.SetOwnership(false, true)); + list.SetOwnership(false); + Test.AssertRaises(() => list.Add(4)); + Test.AssertRaises(() => list.Append(6)); + Test.AssertRaises(() => list.Append(array)); + Test.AssertRaises(() => list.Remove(6)); + Test.AssertEquals(list.Count, 5); + Test.AssertRaises(() => list.RemoveAt(2)); + Test.AssertRaises(() => list.Insert(4, 4)); + Test.AssertRaises(() => list.Clear()); + Test.AssertRaises(() => list.Sort()); + Test.Assert(list.ToArray().SequenceEqual(array)); + } +} +}; diff --git a/src/tests/efl_mono/meson.build b/src/tests/efl_mono/meson.build index 695ff07ec8..54ddb64274 100644 --- a/src/tests/efl_mono/meson.build +++ b/src/tests/efl_mono/meson.build @@ -81,7 +81,8 @@ efl_mono_src = [ 'Value.cs', 'ValueEolian.cs', 'Inheritance.cs', - 'Hash.cs' + 'Hash.cs', + 'List.cs', ] if get_option('dotnet')