summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/eolian_mono/eolian/mono/parameter.hh12
-rw-r--r--src/bindings/mono/eina_mono/eina_list.cs364
-rw-r--r--src/tests/efl_mono/Eina.cs71
-rw-r--r--src/tests/efl_mono/List.cs193
-rw-r--r--src/tests/efl_mono/meson.build3
5 files changed, 495 insertions, 148 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh
index deb9a9e..d27889f 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
747 ) 747 )
748 return true; 748 return true;
749 749
750 if (!complex->subtypes.front().is_value_type && complex->subtypes.front().has_own 750 if ((param.type.has_own && (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own))
751 && !as_generator( 751 && !as_generator(
752 escape_keyword(param.param_name) << ".OwnContent = false;\n" 752 escape_keyword(param.param_name) << ".OwnContent = false;\n"
753 ).generate(sink, attributes::unused, context)) 753 ).generate(sink, attributes::unused, context))
@@ -987,7 +987,7 @@ struct convert_out_assign_generator
987 return as_generator( 987 return as_generator(
988 string << " = new " << type << "(" << string 988 string << " = new " << type << "(" << string
989 << ", " << (param.type.has_own ? "true" : "false") 989 << ", " << (param.type.has_own ? "true" : "false")
990 << ", " << (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own ? "true" : "false") 990 << ", " << (param.type.has_own && (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own) ? "true" : "false")
991 << ");\n" 991 << ");\n"
992 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context); 992 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context);
993 } 993 }
@@ -1116,7 +1116,7 @@ struct convert_return_generator
1116 if (!complex) 1116 if (!complex)
1117 return false; 1117 return false;
1118 if (!as_generator("return new " << type << "(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"} 1118 if (!as_generator("return new " << type << "(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"}
1119 << ", " << (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own ? "true" : "false") 1119 << ", " << (ret_type.has_own && (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own) ? "true" : "false")
1120 << ");\n") 1120 << ");\n")
1121 .generate(sink, ret_type, context)) 1121 .generate(sink, ret_type, context))
1122 return false; 1122 return false;
@@ -1268,9 +1268,9 @@ struct native_convert_out_assign_generator
1268 ) 1268 )
1269 return true; 1269 return true;
1270 1270
1271 if (!complex->subtypes.front().is_value_type && complex->subtypes.front().has_own 1271 if ((param.type.has_own && (complex->subtypes.front().is_value_type && complex->subtypes.front().has_own))
1272 && !as_generator( 1272 && !as_generator(
1273 string << ".OwnContent = false;\n" 1273 string << ".OwnContent = false;\n"
1274 ).generate(sink, outvar, context)) 1274 ).generate(sink, outvar, context))
1275 return false; 1275 return false;
1276 } 1276 }
@@ -1395,7 +1395,7 @@ struct native_convert_return_generator
1395 && ret_type.c_type != "Eina_Accessor *" && ret_type.c_type != "const Eina_Accessor *" 1395 && ret_type.c_type != "Eina_Accessor *" && ret_type.c_type != "const Eina_Accessor *"
1396 ) 1396 )
1397 { 1397 {
1398 if (!complex->subtypes.front().is_value_type && complex->subtypes.front().has_own 1398 if ((ret_type.has_own && (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own))
1399 && !as_generator("_ret_var.OwnContent = false; ") 1399 && !as_generator("_ret_var.OwnContent = false; ")
1400 .generate(sink, attributes::unused, context)) 1400 .generate(sink, attributes::unused, context))
1401 return false; 1401 return false;
diff --git a/src/bindings/mono/eina_mono/eina_list.cs b/src/bindings/mono/eina_mono/eina_list.cs
index 70f2d91..d14dd26 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
124/// <summary>Native wrapper around a linked list of items. 124/// <summary>Native wrapper around a linked list of items.
125/// <para>Since EFL 1.23.</para> 125/// <para>Since EFL 1.23.</para>
126/// </summary> 126/// </summary>
127public class List<T> : IEnumerable<T>, IDisposable 127public class List<T> : IList<T>, IEnumerable<T>, IDisposable
128{ 128{
129 129
130 [EditorBrowsable(EditorBrowsableState.Never)] 130 [EditorBrowsable(EditorBrowsableState.Never)]
131 public IntPtr Handle {get;set;} = IntPtr.Zero; 131 public IntPtr Handle {get; set; } = IntPtr.Zero;
132
132 /// <summary>Whether this managed list owns the native one. 133 /// <summary>Whether this managed list owns the native one.
133 /// <para>Since EFL 1.23.</para> 134 /// <para>Since EFL 1.23.</para>
134 /// </summary> 135 /// </summary>
135 public bool Own {get;set;} 136 internal bool Own { get; set; }
137
136 /// <summary>Whether the native list wrapped owns the content it points to. 138 /// <summary>Whether the native list wrapped owns the content it points to.
137 /// <para>Since EFL 1.23.</para> 139 /// <para>Since EFL 1.23.</para>
138 ///</summary> 140 ///</summary>
139 public bool OwnContent {get;set;} 141 internal bool OwnContent { get; set; }
142
140 143
141 /// <summary>Delegate for comparing two elements of this list. 144 /// <summary>Delegate for comparing two elements of this list.
142 /// <para>Since EFL 1.23.</para> 145 /// <para>Since EFL 1.23.</para>
@@ -146,15 +149,16 @@ public class List<T> : IEnumerable<T>, IDisposable
146 /// <returns>-1, 0 or 1 for respectively smaller, equal or larger.</returns> 149 /// <returns>-1, 0 or 1 for respectively smaller, equal or larger.</returns>
147 public delegate int Compare(T a, T b); 150 public delegate int Compare(T a, T b);
148 151
149 /// <summary>The number of elements on this list. 152 public bool IsReadOnly { get => !OwnContent; }
150 /// <para>Since EFL 1.23.</para> 153
154 /// <summary>The number of elements in this list.
155 /// <para>Since EFL 1.24.</para>
151 /// </summary> 156 /// </summary>
152 public int Length 157 public int Count
153 { 158 {
154 get { return Count(); } 159 get => (int)eina_list_count_custom_export_mono(Handle);
155 } 160 }
156 161
157
158 private void InitNew() 162 private void InitNew()
159 { 163 {
160 Handle = IntPtr.Zero; 164 Handle = IntPtr.Zero;
@@ -163,38 +167,85 @@ public class List<T> : IEnumerable<T>, IDisposable
163 } 167 }
164 168
165 private IntPtr InternalLast() 169 private IntPtr InternalLast()
166 { 170 => eina_list_last_custom_export_mono(Handle);
167 return eina_list_last_custom_export_mono(Handle);
168 }
169 171
170 private static IntPtr InternalNext(IntPtr list) 172 private static IntPtr InternalNext(IntPtr list)
173 => eina_list_next_custom_export_mono(list);
174
175 private static IntPtr InternalPrev(IntPtr list)
176 => eina_list_prev_custom_export_mono(list);
177
178 private static IntPtr InternalDataGet(IntPtr list)
179 => eina_list_data_get_custom_export_mono(list);
180
181 private static IntPtr InternalDataSet(IntPtr list, IntPtr data)
182 => eina_list_data_set_custom_export_mono(list, data);
183
184 private IntPtr GetNative(int idx, Func<IntPtr, uint, IntPtr> f)
171 { 185 {
172 return eina_list_next_custom_export_mono(list); 186 if (!(0 <= idx && idx < Count))
187 {
188 throw new ArgumentOutOfRangeException();
189 }
190
191 var ele = f(Handle, (uint)idx);
192 if (ele == IntPtr.Zero)
193 {
194 throw new ArgumentOutOfRangeException();
195 }
196
197 return ele;
173 } 198 }
174 199
175 private static IntPtr InternalPrev(IntPtr list) 200 private IntPtr GetNativeDataPointer(int idx)
201 => GetNative(idx, eina_list_nth);
202
203 private IntPtr GetNativePointer(int idx)
204 => GetNative(idx, eina_list_nth_list);
205
206 private void RequireWritable()
176 { 207 {
177 return eina_list_prev_custom_export_mono(list); 208 if (IsReadOnly)
209 {
210 throw new NotSupportedException("Cannot modify read-only container.");
211 }
178 } 212 }
179 213
180 private static IntPtr InternalDataGet(IntPtr list) 214 private void CheckOwnerships()
181 { 215 {
182 return eina_list_data_get_custom_export_mono(list); 216 if ((Own == false) && (OwnContent == true))
217 {
218 throw new InvalidOperationException(nameof(Own) + "/" + nameof(OwnContent));
219 }
183 } 220 }
184 221
185 private static IntPtr InternalDataSet(IntPtr list, IntPtr data) 222 private void DeleteData(IntPtr ele)
186 { 223 {
187 return eina_list_data_set_custom_export_mono(list, data); 224 if (OwnContent)
225 {
226 NativeFree<T>(InternalDataGet(ele));
227 }
188 } 228 }
189 229
230 private U LoopingThrough<U>(T val, Func<int, U> f1, Func<U> f2)
231 {
232 int i = 0;
233 IntPtr cur = Handle;
234 for (; cur != IntPtr.Zero; ++i, cur = InternalNext(cur))
235 {
236 if (NativeToManaged<T>(InternalDataGet(cur)).Equals(val))
237 {
238 return f1(i);
239 }
240 }
241
242 return f2();
243 }
190 244
191 /// <summary>Creates a new empty list. 245 /// <summary>Creates a new empty list.
192 /// <para>Since EFL 1.23.</para> 246 /// <para>Since EFL 1.23.</para>
193 /// </summary> 247 /// </summary>
194 public List() 248 public List() => InitNew();
195 {
196 InitNew();
197 }
198 249
199 /// <summary>Creates a new list wrapping the given handle.</summary> 250 /// <summary>Creates a new list wrapping the given handle.</summary>
200 [EditorBrowsable(EditorBrowsableState.Never)] 251 [EditorBrowsable(EditorBrowsableState.Never)]
@@ -203,6 +254,7 @@ public class List<T> : IEnumerable<T>, IDisposable
203 Handle = handle; 254 Handle = handle;
204 Own = own; 255 Own = own;
205 OwnContent = own; 256 OwnContent = own;
257 CheckOwnerships();
206 } 258 }
207 259
208 /// <summary>Creates a new list wrapping the given handle.</summary> 260 /// <summary>Creates a new list wrapping the given handle.</summary>
@@ -212,15 +264,13 @@ public class List<T> : IEnumerable<T>, IDisposable
212 Handle = handle; 264 Handle = handle;
213 Own = own; 265 Own = own;
214 OwnContent = ownContent; 266 OwnContent = ownContent;
267 CheckOwnerships();
215 } 268 }
216 269
217 /// <summary>Finalizes this list. 270 /// <summary>Finalizes this list.
218 /// <para>Since EFL 1.23.</para> 271 /// <para>Since EFL 1.23.</para>
219 /// </summary> 272 /// </summary>
220 ~List() 273 ~List() => Dispose(false);
221 {
222 Dispose(false);
223 }
224 274
225 /// <summary>Disposes of this list. 275 /// <summary>Disposes of this list.
226 /// <para>Since EFL 1.23.</para> 276 /// <para>Since EFL 1.23.</para>
@@ -236,12 +286,14 @@ public class List<T> : IEnumerable<T>, IDisposable
236 return; 286 return;
237 } 287 }
238 288
239 if (Own && OwnContent) 289 for (IntPtr curr = h; curr != IntPtr.Zero; curr = InternalNext(curr))
240 { 290 {
241 for (IntPtr curr = h; curr != IntPtr.Zero; curr = InternalNext(curr)) 291 if (!OwnContent)
242 { 292 {
243 NativeFree<T>(InternalDataGet(curr)); 293 break;
244 } 294 }
295
296 DeleteData(curr);
245 } 297 }
246 298
247 if (Own) 299 if (Own)
@@ -269,30 +321,17 @@ public class List<T> : IEnumerable<T>, IDisposable
269 /// <summary>Disposes of this list. 321 /// <summary>Disposes of this list.
270 /// <para>Since EFL 1.23.</para> 322 /// <para>Since EFL 1.23.</para>
271 /// </summary> 323 /// </summary>
272 public void Free() 324 public void Free() => Dispose();
273 {
274 Dispose();
275 }
276
277 /// <summary>Relinquishes of the native list.
278 /// <para>Since EFL 1.23.</para>
279 /// </summary>
280 /// <returns>The previously wrapped native list handle.</returns>
281 public IntPtr Release()
282 {
283 IntPtr h = Handle;
284 Handle = IntPtr.Zero;
285 return h;
286 }
287 325
288 /// <summary>Sets whether this wrapper should own the native list or not. 326 /// <summary>Sets whether this wrapper should own the native list or not.
289 /// <para>Since EFL 1.23.</para> 327 /// <para>Since EFL 1.23.</para>
290 /// </summary> 328 /// </summary>
291 /// <param name="ownAll">If the hash own for all ownerships.</param> 329 /// <param name="ownAll">If the hash own for all ownerships.</param>
292 public void SetOwnership(bool ownAll) 330 internal void SetOwnership(bool ownAll)
293 { 331 {
294 Own = ownAll; 332 Own = ownAll;
295 OwnContent = ownAll; 333 OwnContent = ownAll;
334 CheckOwnerships();
296 } 335 }
297 336
298 /// <summary>Sets whether this wrapper should own the native list and 337 /// <summary>Sets whether this wrapper should own the native list and
@@ -301,19 +340,11 @@ public class List<T> : IEnumerable<T>, IDisposable
301 /// </summary> 340 /// </summary>
302 /// <param name="own">If own the object.</param> 341 /// <param name="own">If own the object.</param>
303 /// <param name="ownContent">If own the content's object.</param> 342 /// <param name="ownContent">If own the content's object.</param>
304 public void SetOwnership(bool own, bool ownContent) 343 internal void SetOwnership(bool own, bool ownContent)
305 { 344 {
306 Own = own; 345 Own = own;
307 OwnContent = ownContent; 346 OwnContent = ownContent;
308 } 347 CheckOwnerships();
309
310 /// <summary>Returns the number of elements in this list.
311 /// <para>Since EFL 1.23.</para>
312 /// </summary>
313 /// <returns>The number of elements.</returns>
314 public int Count()
315 {
316 return (int)eina_list_count_custom_export_mono(Handle);
317 } 348 }
318 349
319 /// <summary>Appends <c>val</c> to the list. 350 /// <summary>Appends <c>val</c> to the list.
@@ -322,8 +353,9 @@ public class List<T> : IEnumerable<T>, IDisposable
322 /// <param name="val">The item to be appended.</param> 353 /// <param name="val">The item to be appended.</param>
323 public void Append(T val) 354 public void Append(T val)
324 { 355 {
325 IntPtr ele = ManagedToNativeAlloc(val); 356 RequireWritable();
326 Handle = eina_list_append(Handle, ele); 357
358 Handle = eina_list_append(Handle, ManagedToNativeAlloc(val));
327 } 359 }
328 360
329 /// <summary>Prepends <c>val</c> to the list. 361 /// <summary>Prepends <c>val</c> to the list.
@@ -332,8 +364,9 @@ public class List<T> : IEnumerable<T>, IDisposable
332 /// <param name="val">The item to be prepended.</param> 364 /// <param name="val">The item to be prepended.</param>
333 public void Prepend(T val) 365 public void Prepend(T val)
334 { 366 {
335 IntPtr ele = ManagedToNativeAlloc(val); 367 RequireWritable();
336 Handle = eina_list_prepend(Handle, ele); 368
369 Handle = eina_list_prepend(Handle, ManagedToNativeAlloc(val));
337 } 370 }
338 371
339 /// <summary>Inserts <c>val</c> in the list in a sorted manner. 372 /// <summary>Inserts <c>val</c> in the list in a sorted manner.
@@ -343,8 +376,11 @@ public class List<T> : IEnumerable<T>, IDisposable
343 /// <param name="val">The item to be inserted.</param> 376 /// <param name="val">The item to be inserted.</param>
344 public void SortedInsert(T val) 377 public void SortedInsert(T val)
345 { 378 {
346 IntPtr ele = ManagedToNativeAlloc(val); 379 RequireWritable();
347 Handle = eina_list_sorted_insert(Handle, EinaCompareCb<T>(), ele); 380
381 Handle = eina_list_sorted_insert(Handle,
382 EinaCompareCb<T>(),
383 ManagedToNativeAlloc(val));
348 } 384 }
349 385
350 /// <summary>Inserts <c>val</c> in the list in a sorted manner with the 386 /// <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
356 /// <param name="val">The item to be inserted.</param> 392 /// <param name="val">The item to be inserted.</param>
357 public void SortedInsert(Compare compareCb, T val) 393 public void SortedInsert(Compare compareCb, T val)
358 { 394 {
359 IntPtr ele = ManagedToNativeAlloc(val); 395 RequireWritable();
360 Handle = eina_list_sorted_insert(Handle, Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb)), ele); 396
397 Handle = eina_list_sorted_insert(Handle,
398 Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb)),
399 ManagedToNativeAlloc(val));
361 } 400 }
362 401
363 /// <summary>Sorts <c>limit</c> elements in this list inplace. 402 /// <summary>Sorts <c>limit</c> elements in this list inplace.
@@ -366,6 +405,8 @@ public class List<T> : IEnumerable<T>, IDisposable
366 /// <param name="limit">The max number of elements to be sorted.</param> 405 /// <param name="limit">The max number of elements to be sorted.</param>
367 public void Sort(int limit = 0) 406 public void Sort(int limit = 0)
368 { 407 {
408 RequireWritable();
409
369 Handle = eina_list_sort(Handle, (uint)limit, EinaCompareCb<T>()); 410 Handle = eina_list_sort(Handle, (uint)limit, EinaCompareCb<T>());
370 } 411 }
371 412
@@ -375,7 +416,10 @@ public class List<T> : IEnumerable<T>, IDisposable
375 /// <param name="compareCb">The function to compare two elements of the list.</param> 416 /// <param name="compareCb">The function to compare two elements of the list.</param>
376 public void Sort(Compare compareCb) 417 public void Sort(Compare compareCb)
377 { 418 {
378 Handle = eina_list_sort(Handle, 0, Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb))); 419 RequireWritable();
420
421 Handle = eina_list_sort(Handle, (uint)0,
422 Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb)));
379 } 423 }
380 424
381 /// <summary>Sorts <c>limit</c> elements in this list inplace. 425 /// <summary>Sorts <c>limit</c> elements in this list inplace.
@@ -385,15 +429,16 @@ public class List<T> : IEnumerable<T>, IDisposable
385 /// <param name="compareCb">The function to compare two elements of the list.</param> 429 /// <param name="compareCb">The function to compare two elements of the list.</param>
386 public void Sort(int limit, Compare compareCb) 430 public void Sort(int limit, Compare compareCb)
387 { 431 {
388 Handle = eina_list_sort(Handle, (uint)limit, Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb))); 432 RequireWritable();
433
434 Handle = eina_list_sort(Handle, (uint)limit,
435 Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb)));
389 } 436 }
390 437
391 private Eina.Callbacks.EinaCompareCb GetNativeCompareCb(Compare managedCb) 438 private Eina.Callbacks.EinaCompareCb GetNativeCompareCb(Compare managedCb)
392 { 439 => (IntPtr a, IntPtr b)
393 return (IntPtr a, IntPtr b) => { 440 => managedCb(NativeToManaged<T>(a), NativeToManaged<T>(b));
394 return managedCb(NativeToManaged<T>(a), NativeToManaged<T>(b)); 441
395 };
396 }
397 442
398 /// <summary>Returns the <c>n</c>th element of this list. Due to marshalling details, the returned element 443 /// <summary>Returns the <c>n</c>th element of this list. Due to marshalling details, the returned element
399 /// may be a different C# object from the one you used to append. 444 /// may be a different C# object from the one you used to append.
@@ -401,33 +446,20 @@ public class List<T> : IEnumerable<T>, IDisposable
401 /// </summary> 446 /// </summary>
402 /// <param name="n">The 0-based index to be retrieved.</param> 447 /// <param name="n">The 0-based index to be retrieved.</param>
403 /// <returns>The value in the specified element.</returns> 448 /// <returns>The value in the specified element.</returns>
404 public T Nth(int n) 449 public T Nth(int n) => NativeToManaged<T>(GetNativeDataPointer(n));
405 {
406 // TODO: check bounds ???
407 IntPtr ele = eina_list_nth(Handle, (uint)n);
408 return NativeToManaged<T>(ele);
409 }
410 450
411 /// <summary>Sets the data at the <c>idx</c> position. 451 /// <summary>Sets the data at the <c>idx</c> position.
412 /// <para>Since EFL 1.23.</para> 452 /// <para>Since EFL 1.23.</para>
413 /// </summary> 453 /// </summary>
414 /// <param name="idx">The 0-based index to be set.</param> 454 /// <param name="idx">The 0-based index to be set.</param>
415 /// <param name="val">The value to be inserted.</param> 455 /// <param name="val">The value to be inserted.</param>
416 public void DataSet(int idx, T val) 456 internal void DataSet(int idx, T val)
417 { 457 {
418 IntPtr pos = eina_list_nth_list(Handle, (uint)idx); 458 RequireWritable();
419 if (pos == IntPtr.Zero)
420 {
421 throw new IndexOutOfRangeException();
422 }
423 459
424 if (OwnContent) 460 IntPtr pos = GetNativePointer(idx);
425 { 461 DeleteData(pos);
426 NativeFree<T>(InternalDataGet(pos)); 462 InternalDataSet(pos, ManagedToNativeAlloc(val));
427 }
428
429 IntPtr ele = ManagedToNativeAlloc(val);
430 InternalDataSet(pos, ele);
431 } 463 }
432 464
433 /// <summary>Accessor for the data at the <c>idx</c> position. 465 /// <summary>Accessor for the data at the <c>idx</c> position.
@@ -451,10 +483,7 @@ public class List<T> : IEnumerable<T>, IDisposable
451 /// </summary> 483 /// </summary>
452 /// <returns>The value contained in the last list position.</returns> 484 /// <returns>The value contained in the last list position.</returns>
453 public T LastDataGet() 485 public T LastDataGet()
454 { 486 => NativeToManaged<T>(eina_list_last_data_get_custom_export_mono(Handle));
455 IntPtr ele = eina_list_last_data_get_custom_export_mono(Handle);
456 return NativeToManaged<T>(ele);
457 }
458 487
459 /// <summary>Reverses this list in place. 488 /// <summary>Reverses this list in place.
460 /// <para>Since EFL 1.23.</para> 489 /// <para>Since EFL 1.23.</para>
@@ -462,6 +491,8 @@ public class List<T> : IEnumerable<T>, IDisposable
462 /// <returns>A reference to this object.</returns> 491 /// <returns>A reference to this object.</returns>
463 public List<T> Reverse() 492 public List<T> Reverse()
464 { 493 {
494 RequireWritable();
495
465 Handle = eina_list_reverse(Handle); 496 Handle = eina_list_reverse(Handle);
466 return this; 497 return this;
467 } 498 }
@@ -471,6 +502,8 @@ public class List<T> : IEnumerable<T>, IDisposable
471 /// </summary> 502 /// </summary>
472 public void Shuffle() 503 public void Shuffle()
473 { 504 {
505 RequireWritable();
506
474 Handle = eina_list_shuffle(Handle, IntPtr.Zero); 507 Handle = eina_list_shuffle(Handle, IntPtr.Zero);
475 } 508 }
476 509
@@ -480,9 +513,10 @@ public class List<T> : IEnumerable<T>, IDisposable
480 /// <returns>A managed array of the elements.</returns> 513 /// <returns>A managed array of the elements.</returns>
481 public T[] ToArray() 514 public T[] ToArray()
482 { 515 {
483 var managed = new T[Count()]; 516 var managed = new T[Count];
484 int i = 0; 517 int i = 0;
485 for (IntPtr curr = Handle; curr != IntPtr.Zero; curr = InternalNext(curr), ++i) 518 for (IntPtr curr = Handle; curr != IntPtr.Zero;
519 curr = InternalNext(curr), ++i)
486 { 520 {
487 managed[i] = NativeToManaged<T>(InternalDataGet(curr)); 521 managed[i] = NativeToManaged<T>(InternalDataGet(curr));
488 } 522 }
@@ -494,8 +528,10 @@ public class List<T> : IEnumerable<T>, IDisposable
494 /// <para>Since EFL 1.23.</para> 528 /// <para>Since EFL 1.23.</para>
495 /// </summary> 529 /// </summary>
496 /// <param name="values">The values to be appended.</param> 530 /// <param name="values">The values to be appended.</param>
497 public void AppendArray(T[] values) 531 public void Append(T[] values)
498 { 532 {
533 RequireWritable();
534
499 foreach (T v in values) 535 foreach (T v in values)
500 { 536 {
501 Append(v); 537 Append(v);
@@ -508,18 +544,14 @@ public class List<T> : IEnumerable<T>, IDisposable
508 /// </summary> 544 /// </summary>
509 /// <returns>The iterator.</returns> 545 /// <returns>The iterator.</returns>
510 public Eina.Iterator<T> GetIterator() 546 public Eina.Iterator<T> GetIterator()
511 { 547 => new Eina.Iterator<T>(eina_list_iterator_new(Handle), true);
512 return new Eina.Iterator<T>(eina_list_iterator_new(Handle), true);
513 }
514 548
515 /// <summary>Gets an iterator that iterates this list in reverse order. 549 /// <summary>Gets an iterator that iterates this list in reverse order.
516 /// <para>Since EFL 1.23.</para> 550 /// <para>Since EFL 1.23.</para>
517 /// </summary> 551 /// </summary>
518 /// <returns>The iterator.</returns> 552 /// <returns>The iterator.</returns>
519 public Eina.Iterator<T> GetReversedIterator() 553 public Eina.Iterator<T> GetReversedIterator()
520 { 554 => new Eina.Iterator<T>(eina_list_iterator_reversed_new(Handle), true);
521 return new Eina.Iterator<T>(eina_list_iterator_reversed_new(Handle), true);
522 }
523 555
524 /// <summary>Gets an enumerator into this list. 556 /// <summary>Gets an enumerator into this list.
525 /// <para>Since EFL 1.23.</para> 557 /// <para>Since EFL 1.23.</para>
@@ -538,18 +570,136 @@ public class List<T> : IEnumerable<T>, IDisposable
538 /// </summary> 570 /// </summary>
539 /// <returns>The enumerator.</returns> 571 /// <returns>The enumerator.</returns>
540 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 572 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
541 { 573 => this.GetEnumerator();
542 return this.GetEnumerator();
543 }
544 574
545 /// <summary> Gets an Accessor for this List. 575 /// <summary> Gets an Accessor for this List.
546 /// <para>Since EFL 1.23.</para> 576 /// <para>Since EFL 1.23.</para>
547 /// </summary> 577 /// </summary>
548 /// <returns>The accessor.</returns> 578 /// <returns>The accessor.</returns>
549 public Eina.Accessor<T> GetAccessor() 579 public Eina.Accessor<T> GetAccessor()
580 => new Eina.Accessor<T>(eina_list_accessor_new(Handle),
581 Ownership.Managed);
582
583 /// <summary>
584 /// Removes the first occurrence of a specific object.
585 /// <para>Since EFL 1.24.</para>
586 /// </summary>
587 /// <param name="val">The object to remove.</param>
588 public bool Remove(T val)
550 { 589 {
551 return new Eina.Accessor<T>(eina_list_accessor_new(Handle), Ownership.Managed); 590 RequireWritable();
591
592 var prev_count = Count;
593 var deleted = LoopingThrough(val,
594 (i) =>
595 {
596 RemoveAt(i);
597 return true;
598 },
599 () => false);
600
601 return deleted && (prev_count - 1 == Count);
552 } 602 }
603
604 /// <summary>
605 /// Adds an item.
606 /// <para>Since EFL 1.24.</para>
607 /// </summary>
608 /// <param name="val">The object to add.</param>
609 public void Add(T val) => Append(val);
610
611 /// <summary>
612 /// Removes all items.
613 /// <para>Since EFL 1.24.</para>
614 /// </summary>
615 public void Clear()
616 {
617 RequireWritable();
618
619 for (; Handle != IntPtr.Zero;)
620 {
621 Handle = eina_list_remove_list(Handle, Handle);
622 }
623 }
624
625 /// <summary>
626 /// Determines whether the <see cref="List{T}" /> contains a specific value.
627 /// <para>Since EFL 1.24.</para>
628 /// </summary>
629 /// <param name="val">The object to locate.</param>
630 public bool Contains(T val)
631 => LoopingThrough(val, (i) => true, () => false);
632
633 /// <summary>
634 /// Determines the index of a specific item.
635 /// <para>Since EFL 1.24.</para>
636 /// </summary>
637 /// <param name="val">The object to locate.</param>
638 public int IndexOf(T val)
639 => LoopingThrough(val, (i) => i, () => -1);
640
641 /// <summary>
642 /// Inserts an item to the <see cref="List{T}" /> at the specified index.
643 /// <para>Since EFL 1.24.</para>
644 /// </summary>
645 /// <param name="idx">The zero-based index at which item should be inserted.</param>
646 /// <param name="val">The object to insert.</param>
647 public void Insert(int idx, T val)
648 {
649 RequireWritable();
650
651 if (idx == 0)
652 {
653 Prepend(val);
654 return;
655 }
656
657 if (idx == Count)
658 {
659 Append(val);
660 return;
661 }
662
663 if (idx < 0)
664 {
665 throw new ArgumentOutOfRangeException(nameof(idx), $"{nameof(idx)} cannot be negative.");
666 }
667
668 if (Count < idx)
669 {
670 throw new ArgumentOutOfRangeException(nameof(idx), $"{nameof(idx)} cannot be greater than {nameof(Count)} + 1.");
671 }
672
673 Handle = eina_list_prepend_relative_list(Handle, ManagedToNativeAlloc(val),
674 GetNativePointer(idx));
675 }
676
677 /// <summary>
678 /// Removes the <see cref="List{T}" /> item at the specified index.
679 /// <para>Since EFL 1.24.</para>
680 /// </summary>
681 /// <param name="idx">The zero-based index of the item to remove.</param>
682 public void RemoveAt(int idx)
683 {
684 RequireWritable();
685
686 var ele = GetNativePointer(idx);
687 DeleteData(ele);
688 Handle = eina_list_remove_list(Handle, ele);
689 }
690
691 /// <summary>
692 /// Copies the elements of the <see cref="List{T}" /> to an
693 /// <see cref="Array" />, starting at a particular <see cref="Array" /> index.
694 /// <para>Since EFL 1.24.</para>
695 /// </summary>
696 /// <param name="array">The one-dimensional <see cref="Array" /> that is the
697 /// destination of the elements copied from <see cref="List{T}" />.
698 /// The <see cref="Array" /> must have zero-based indexing.</param>
699 /// <param name="arrayIndex">The zero-based index in array at which copying
700 /// begins.</param>
701 public void CopyTo(T[] array, int arrayIndex)
702 => ToArray().CopyTo(array, arrayIndex);
553} 703}
554 704
555} 705}
diff --git a/src/tests/efl_mono/Eina.cs b/src/tests/efl_mono/Eina.cs
index b329bc3..16d65a8 100644
--- a/src/tests/efl_mono/Eina.cs
+++ b/src/tests/efl_mono/Eina.cs
@@ -1726,48 +1726,48 @@ class TestEinaList
1726 public static void length_int() 1726 public static void length_int()
1727 { 1727 {
1728 var lst = new Eina.List<int>(); 1728 var lst = new Eina.List<int>();
1729 Test.Assert(lst.Length == 0); 1729 Test.Assert(lst.Count == 0);
1730 lst.Append(88); 1730 lst.Append(88);
1731 Test.Assert(lst[0] == 88); 1731 Test.Assert(lst[0] == 88);
1732 Test.Assert(lst.Length == 1); 1732 Test.Assert(lst.Count == 1);
1733 lst.Append(44); 1733 lst.Append(44);
1734 Test.Assert(lst[1] == 44); 1734 Test.Assert(lst[1] == 44);
1735 Test.Assert(lst.Length == 2); 1735 Test.Assert(lst.Count == 2);
1736 lst.Append(22); 1736 lst.Append(22);
1737 Test.Assert(lst[2] == 22); 1737 Test.Assert(lst[2] == 22);
1738 Test.Assert(lst.Length == 3); 1738 Test.Assert(lst.Count == 3);
1739 lst.Dispose(); 1739 lst.Dispose();
1740 } 1740 }
1741 1741
1742 public static void length_string() 1742 public static void length_string()
1743 { 1743 {
1744 var lst = new Eina.List<string>(); 1744 var lst = new Eina.List<string>();
1745 Test.Assert(lst.Length == 0); 1745 Test.Assert(lst.Count == 0);
1746 lst.Append("a"); 1746 lst.Append("a");
1747 Test.Assert(lst[0] == "a"); 1747 Test.Assert(lst[0] == "a");
1748 Test.Assert(lst.Length == 1); 1748 Test.Assert(lst.Count == 1);
1749 lst.Append("b"); 1749 lst.Append("b");
1750 Test.Assert(lst[1] == "b"); 1750 Test.Assert(lst[1] == "b");
1751 Test.Assert(lst.Length == 2); 1751 Test.Assert(lst.Count == 2);
1752 lst.Append("c"); 1752 lst.Append("c");
1753 Test.Assert(lst[2] == "c"); 1753 Test.Assert(lst[2] == "c");
1754 Test.Assert(lst.Length == 3); 1754 Test.Assert(lst.Count == 3);
1755 lst.Dispose(); 1755 lst.Dispose();
1756 } 1756 }
1757 1757
1758 public static void length_stringshare() 1758 public static void length_stringshare()
1759 { 1759 {
1760 var lst = new Eina.List<Eina.Stringshare>(); 1760 var lst = new Eina.List<Eina.Stringshare>();
1761 Test.Assert(lst.Length == 0); 1761 Test.Assert(lst.Count == 0);
1762 lst.Append("a"); 1762 lst.Append("a");
1763 Test.Assert(lst[0] == "a"); 1763 Test.Assert(lst[0] == "a");
1764 Test.Assert(lst.Length == 1); 1764 Test.Assert(lst.Count == 1);
1765 lst.Append("b"); 1765 lst.Append("b");
1766 Test.Assert(lst[1] == "b"); 1766 Test.Assert(lst[1] == "b");
1767 Test.Assert(lst.Length == 2); 1767 Test.Assert(lst.Count == 2);
1768 lst.Append("c"); 1768 lst.Append("c");
1769 Test.Assert(lst[2] == "c"); 1769 Test.Assert(lst[2] == "c");
1770 Test.Assert(lst.Length == 3); 1770 Test.Assert(lst.Count == 3);
1771 lst.Dispose(); 1771 lst.Dispose();
1772 } 1772 }
1773 1773
@@ -2102,7 +2102,7 @@ class TestEinaList
2102 { 2102 {
2103 var t = new Dummy.TestObject(); 2103 var t = new Dummy.TestObject();
2104 var lst = new Eina.List<int>(); 2104 var lst = new Eina.List<int>();
2105 lst.AppendArray(base_seq_int); 2105 lst.Append(base_seq_int);
2106 Test.Assert(t.EinaListIntIn(lst)); 2106 Test.Assert(t.EinaListIntIn(lst));
2107 Test.Assert(lst.Own); 2107 Test.Assert(lst.Own);
2108 Test.Assert(lst.ToArray().SequenceEqual(base_seq_int)); 2108 Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
@@ -2115,9 +2115,10 @@ class TestEinaList
2115 { 2115 {
2116 var t = new Dummy.TestObject(); 2116 var t = new Dummy.TestObject();
2117 var lst = new Eina.List<int>(); 2117 var lst = new Eina.List<int>();
2118 lst.AppendArray(base_seq_int); 2118 lst.Append(base_seq_int);
2119 Test.Assert(t.EinaListIntInOwn(lst)); 2119 Test.Assert(t.EinaListIntInOwn(lst));
2120 Test.Assert(!lst.Own); 2120 Test.Assert(!lst.Own);
2121 Test.Assert(!lst.OwnContent);
2121 lst.Dispose(); 2122 lst.Dispose();
2122 Test.Assert(lst.Handle == IntPtr.Zero); 2123 Test.Assert(lst.Handle == IntPtr.Zero);
2123 Test.Assert(t.CheckEinaListIntInOwn()); 2124 Test.Assert(t.CheckEinaListIntInOwn());
@@ -2130,6 +2131,7 @@ class TestEinaList
2130 Eina.List<int> lst; 2131 Eina.List<int> lst;
2131 Test.Assert(t.EinaListIntOut(out lst)); 2132 Test.Assert(t.EinaListIntOut(out lst));
2132 Test.Assert(!lst.Own); 2133 Test.Assert(!lst.Own);
2134 Test.Assert(!lst.OwnContent);
2133 Test.Assert(lst.ToArray().SequenceEqual(base_seq_int)); 2135 Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
2134 lst.Dispose(); 2136 lst.Dispose();
2135 Test.Assert(lst.Handle == IntPtr.Zero); 2137 Test.Assert(lst.Handle == IntPtr.Zero);
@@ -2144,7 +2146,7 @@ class TestEinaList
2144 Test.Assert(t.EinaListIntOutOwn(out lst)); 2146 Test.Assert(t.EinaListIntOutOwn(out lst));
2145 Test.Assert(lst.Own); 2147 Test.Assert(lst.Own);
2146 Test.Assert(lst.ToArray().SequenceEqual(base_seq_int)); 2148 Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
2147 lst.AppendArray(append_seq_int); 2149 lst.Append(append_seq_int);
2148 lst.Dispose(); 2150 lst.Dispose();
2149 Test.Assert(lst.Handle == IntPtr.Zero); 2151 Test.Assert(lst.Handle == IntPtr.Zero);
2150 t.Dispose(); 2152 t.Dispose();
@@ -2155,6 +2157,7 @@ class TestEinaList
2155 var t = new Dummy.TestObject(); 2157 var t = new Dummy.TestObject();
2156 var lst = t.EinaListIntReturn(); 2158 var lst = t.EinaListIntReturn();
2157 Test.Assert(!lst.Own); 2159 Test.Assert(!lst.Own);
2160 Test.Assert(!lst.OwnContent);
2158 Test.Assert(lst.ToArray().SequenceEqual(base_seq_int)); 2161 Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
2159 lst.Dispose(); 2162 lst.Dispose();
2160 Test.Assert(lst.Handle == IntPtr.Zero); 2163 Test.Assert(lst.Handle == IntPtr.Zero);
@@ -2168,7 +2171,7 @@ class TestEinaList
2168 var lst = t.EinaListIntReturnOwn(); 2171 var lst = t.EinaListIntReturnOwn();
2169 Test.Assert(lst.Own); 2172 Test.Assert(lst.Own);
2170 Test.Assert(lst.ToArray().SequenceEqual(base_seq_int)); 2173 Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
2171 lst.AppendArray(append_seq_int); 2174 lst.Append(append_seq_int);
2172 lst.Dispose(); 2175 lst.Dispose();
2173 Test.Assert(lst.Handle == IntPtr.Zero); 2176 Test.Assert(lst.Handle == IntPtr.Zero);
2174 t.Dispose(); 2177 t.Dispose();
@@ -2179,7 +2182,7 @@ class TestEinaList
2179 { 2182 {
2180 var t = new Dummy.TestObject(); 2183 var t = new Dummy.TestObject();
2181 var lst = new Eina.List<string>(); 2184 var lst = new Eina.List<string>();
2182 lst.AppendArray(base_seq_str); 2185 lst.Append(base_seq_str);
2183 Test.Assert(t.EinaListStrIn(lst)); 2186 Test.Assert(t.EinaListStrIn(lst));
2184 Test.Assert(lst.Own); 2187 Test.Assert(lst.Own);
2185 Test.Assert(lst.ToArray().SequenceEqual(base_seq_str)); 2188 Test.Assert(lst.ToArray().SequenceEqual(base_seq_str));
@@ -2192,7 +2195,7 @@ class TestEinaList
2192 { 2195 {
2193 var t = new Dummy.TestObject(); 2196 var t = new Dummy.TestObject();
2194 var lst = new Eina.List<string>(); 2197 var lst = new Eina.List<string>();
2195 lst.AppendArray(base_seq_str); 2198 lst.Append(base_seq_str);
2196 Test.Assert(t.EinaListStrInOwn(lst)); 2199 Test.Assert(t.EinaListStrInOwn(lst));
2197 Test.Assert(!lst.Own); 2200 Test.Assert(!lst.Own);
2198 lst.Dispose(); 2201 lst.Dispose();
@@ -2221,7 +2224,7 @@ class TestEinaList
2221 Test.Assert(t.EinaListStrOutOwn(out lst)); 2224 Test.Assert(t.EinaListStrOutOwn(out lst));
2222 Test.Assert(lst.Own); 2225 Test.Assert(lst.Own);
2223 Test.Assert(lst.ToArray().SequenceEqual(base_seq_str)); 2226 Test.Assert(lst.ToArray().SequenceEqual(base_seq_str));
2224 lst.AppendArray(append_seq_str); 2227 lst.Append(append_seq_str);
2225 lst.Dispose(); 2228 lst.Dispose();
2226 Test.Assert(lst.Handle == IntPtr.Zero); 2229 Test.Assert(lst.Handle == IntPtr.Zero);
2227 t.Dispose(); 2230 t.Dispose();
@@ -2245,7 +2248,7 @@ class TestEinaList
2245 var lst = t.EinaListStrReturnOwn(); 2248 var lst = t.EinaListStrReturnOwn();
2246 Test.Assert(lst.Own); 2249 Test.Assert(lst.Own);
2247 Test.Assert(lst.ToArray().SequenceEqual(base_seq_str)); 2250 Test.Assert(lst.ToArray().SequenceEqual(base_seq_str));
2248 lst.AppendArray(append_seq_str); 2251 lst.Append(append_seq_str);
2249 lst.Dispose(); 2252 lst.Dispose();
2250 Test.Assert(lst.Handle == IntPtr.Zero); 2253 Test.Assert(lst.Handle == IntPtr.Zero);
2251 t.Dispose(); 2254 t.Dispose();
@@ -2256,7 +2259,7 @@ class TestEinaList
2256 { 2259 {
2257 var t = new Dummy.TestObject(); 2260 var t = new Dummy.TestObject();
2258 var lst = new Eina.List<Eina.Stringshare>(); 2261 var lst = new Eina.List<Eina.Stringshare>();
2259 lst.AppendArray(base_seq_strshare); 2262 lst.Append(base_seq_strshare);
2260 Test.Assert(t.EinaListStrshareIn(lst)); 2263 Test.Assert(t.EinaListStrshareIn(lst));
2261 Test.Assert(lst.Own); 2264 Test.Assert(lst.Own);
2262 Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare)); 2265 Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare));
@@ -2269,7 +2272,7 @@ class TestEinaList
2269 { 2272 {
2270 var t = new Dummy.TestObject(); 2273 var t = new Dummy.TestObject();
2271 var lst = new Eina.List<Eina.Stringshare>(); 2274 var lst = new Eina.List<Eina.Stringshare>();
2272 lst.AppendArray(base_seq_strshare); 2275 lst.Append(base_seq_strshare);
2273 Test.Assert(t.EinaListStrshareInOwn(lst)); 2276 Test.Assert(t.EinaListStrshareInOwn(lst));
2274 Test.Assert(!lst.Own); 2277 Test.Assert(!lst.Own);
2275 lst.Dispose(); 2278 lst.Dispose();
@@ -2298,7 +2301,7 @@ class TestEinaList
2298 Test.Assert(t.EinaListStrshareOutOwn(out lst)); 2301 Test.Assert(t.EinaListStrshareOutOwn(out lst));
2299 Test.Assert(lst.Own); 2302 Test.Assert(lst.Own);
2300 Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare)); 2303 Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare));
2301 lst.AppendArray(append_seq_strshare); 2304 lst.Append(append_seq_strshare);
2302 lst.Dispose(); 2305 lst.Dispose();
2303 Test.Assert(lst.Handle == IntPtr.Zero); 2306 Test.Assert(lst.Handle == IntPtr.Zero);
2304 t.Dispose(); 2307 t.Dispose();
@@ -2322,7 +2325,7 @@ class TestEinaList
2322 var lst = t.EinaListStrshareReturnOwn(); 2325 var lst = t.EinaListStrshareReturnOwn();
2323 Test.Assert(lst.Own); 2326 Test.Assert(lst.Own);
2324 Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare)); 2327 Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare));
2325 lst.AppendArray(append_seq_strshare); 2328 lst.Append(append_seq_strshare);
2326 lst.Dispose(); 2329 lst.Dispose();
2327 Test.Assert(lst.Handle == IntPtr.Zero); 2330 Test.Assert(lst.Handle == IntPtr.Zero);
2328 t.Dispose(); 2331 t.Dispose();
@@ -2334,7 +2337,7 @@ class TestEinaList
2334 { 2337 {
2335 var t = new Dummy.TestObject(); 2338 var t = new Dummy.TestObject();
2336 var lst = new Eina.List<Dummy.Numberwrapper>(); 2339 var lst = new Eina.List<Dummy.Numberwrapper>();
2337 lst.AppendArray(BaseSeqObj()); 2340 lst.Append(BaseSeqObj());
2338 Test.Assert(t.EinaListObjIn(lst)); 2341 Test.Assert(t.EinaListObjIn(lst));
2339 Test.Assert(lst.Own); 2342 Test.Assert(lst.Own);
2340 NumberwrapperSequenceAssertEqual(lst.ToArray(), BaseSeqObj()); 2343 NumberwrapperSequenceAssertEqual(lst.ToArray(), BaseSeqObj());
@@ -2347,7 +2350,7 @@ class TestEinaList
2347 { 2350 {
2348 var t = new Dummy.TestObject(); 2351 var t = new Dummy.TestObject();
2349 var lst = new Eina.List<Dummy.Numberwrapper>(); 2352 var lst = new Eina.List<Dummy.Numberwrapper>();
2350 lst.AppendArray(BaseSeqObj()); 2353 lst.Append(BaseSeqObj());
2351 Test.Assert(t.EinaListObjInOwn(lst)); 2354 Test.Assert(t.EinaListObjInOwn(lst));
2352 Test.Assert(!lst.Own); 2355 Test.Assert(!lst.Own);
2353 lst.Dispose(); 2356 lst.Dispose();
@@ -2376,7 +2379,7 @@ class TestEinaList
2376 Test.Assert(t.EinaListObjOutOwn(out lst)); 2379 Test.Assert(t.EinaListObjOutOwn(out lst));
2377 Test.Assert(lst.Own); 2380 Test.Assert(lst.Own);
2378 NumberwrapperSequenceAssertEqual(lst.ToArray(), BaseSeqObj()); 2381 NumberwrapperSequenceAssertEqual(lst.ToArray(), BaseSeqObj());
2379 lst.AppendArray(AppendSeqObj()); 2382 lst.Append(AppendSeqObj());
2380 lst.Dispose(); 2383 lst.Dispose();
2381 Test.Assert(lst.Handle == IntPtr.Zero); 2384 Test.Assert(lst.Handle == IntPtr.Zero);
2382 t.Dispose(); 2385 t.Dispose();
@@ -2400,7 +2403,7 @@ class TestEinaList
2400 var lst = t.EinaListObjReturnOwn(); 2403 var lst = t.EinaListObjReturnOwn();
2401 Test.Assert(lst.Own); 2404 Test.Assert(lst.Own);
2402 NumberwrapperSequenceAssertEqual(lst.ToArray(), BaseSeqObj()); 2405 NumberwrapperSequenceAssertEqual(lst.ToArray(), BaseSeqObj());
2403 lst.AppendArray(AppendSeqObj()); 2406 lst.Append(AppendSeqObj());
2404 lst.Dispose(); 2407 lst.Dispose();
2405 Test.Assert(lst.Handle == IntPtr.Zero); 2408 Test.Assert(lst.Handle == IntPtr.Zero);
2406 t.Dispose(); 2409 t.Dispose();
@@ -2411,11 +2414,11 @@ class TestEinaList
2411 var t = new Dummy.TestObject(); 2414 var t = new Dummy.TestObject();
2412 var cmp = BaseSeqObj(); 2415 var cmp = BaseSeqObj();
2413 var a = new Eina.List<Dummy.Numberwrapper>(); 2416 var a = new Eina.List<Dummy.Numberwrapper>();
2414 a.AppendArray(cmp); 2417 a.Append(cmp);
2415 var b = t.EinaListObjReturnIn(a); 2418 var b = t.EinaListObjReturnIn(a);
2416 NumberwrapperSequenceAssertEqual(a.ToArray(), b.ToArray()); 2419 NumberwrapperSequenceAssertEqual(a.ToArray(), b.ToArray());
2417 NumberwrapperSequenceAssertEqual(a.ToArray(), BaseSeqObj()); 2420 NumberwrapperSequenceAssertEqual(a.ToArray(), BaseSeqObj());
2418 int len = a.Length; 2421 int len = a.Count;
2419 for (int i=0; i < len; ++i) 2422 for (int i=0; i < len; ++i)
2420 { 2423 {
2421 Test.Assert(a[i].NativeHandle == b[i].NativeHandle); 2424 Test.Assert(a[i].NativeHandle == b[i].NativeHandle);
@@ -3551,7 +3554,7 @@ class TestEinaIterator
3551 public static void eina_list_int_filled_iterator() 3554 public static void eina_list_int_filled_iterator()
3552 { 3555 {
3553 var lst = new Eina.List<int>(); 3556 var lst = new Eina.List<int>();
3554 lst.AppendArray(base_seq_int); 3557 lst.Append(base_seq_int);
3555 var itr = lst.GetIterator(); 3558 var itr = lst.GetIterator();
3556 int idx = 0; 3559 int idx = 0;
3557 foreach (int e in itr) 3560 foreach (int e in itr)
@@ -3583,7 +3586,7 @@ class TestEinaIterator
3583 public static void eina_list_str_filled_iterator() 3586 public static void eina_list_str_filled_iterator()
3584 { 3587 {
3585 var lst = new Eina.List<string>(); 3588 var lst = new Eina.List<string>();
3586 lst.AppendArray(base_seq_str); 3589 lst.Append(base_seq_str);
3587 var itr = lst.GetIterator(); 3590 var itr = lst.GetIterator();
3588 int idx = 0; 3591 int idx = 0;
3589 foreach (string e in itr) 3592 foreach (string e in itr)
@@ -3615,7 +3618,7 @@ class TestEinaIterator
3615 public static void eina_list_strshare_filled_iterator() 3618 public static void eina_list_strshare_filled_iterator()
3616 { 3619 {
3617 var lst = new Eina.List<Eina.Stringshare>(); 3620 var lst = new Eina.List<Eina.Stringshare>();
3618 lst.AppendArray(base_seq_strshare); 3621 lst.Append(base_seq_strshare);
3619 var itr = lst.GetIterator(); 3622 var itr = lst.GetIterator();
3620 int idx = 0; 3623 int idx = 0;
3621 foreach (string e in itr) 3624 foreach (string e in itr)
@@ -3648,7 +3651,7 @@ class TestEinaIterator
3648 { 3651 {
3649 var lst = new Eina.List<Dummy.Numberwrapper>(); 3652 var lst = new Eina.List<Dummy.Numberwrapper>();
3650 var base_objs = BaseSeqObj(); 3653 var base_objs = BaseSeqObj();
3651 lst.AppendArray(base_objs); 3654 lst.Append(base_objs);
3652 var itr = lst.GetIterator(); 3655 var itr = lst.GetIterator();
3653 int idx = 0; 3656 int idx = 0;
3654 foreach (Dummy.Numberwrapper e in itr) 3657 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 0000000..3394cff
--- /dev/null
+++ b/src/tests/efl_mono/List.cs
@@ -0,0 +1,193 @@
1using System;
2using System.Collections.Generic;
3using System.Linq;
4
5namespace TestSuite {
6
7class TestList
8{
9 public static void TestAdd()
10 {
11 IList<int> list = new Eina.List<int>();
12 Test.AssertEquals(list.Count, 0);
13 list.Add(1);
14 Test.AssertEquals(list.Count, 1);
15 list.Add(2);
16 Test.AssertEquals(list.Count, 2);
17 }
18
19 public static void TestRemoveAt()
20 {
21 IList<int> list = new Eina.List<int>();
22 Test.AssertEquals(list.Count, 0);
23 list.Add(1);
24 Test.AssertEquals(list.Count, 1);
25 Test.AssertEquals(list[0], 1);
26 list.RemoveAt(0);
27 Test.AssertEquals(list.Count, 0);
28 list.Add(1);
29 list.Add(0);
30 list.Add(1);
31 Test.AssertEquals(list.Count, 3);
32 Test.AssertEquals(list[2], 1);
33 list.RemoveAt(2);
34 Test.AssertEquals(list.Count, 2);
35 Test.AssertEquals(list[0], 1);
36 }
37
38 public static void TestRemove()
39 {
40 IList<int> list = new Eina.List<int>();
41 Test.Assert(!list.Remove(0));
42 Test.AssertEquals(list.Count, 0);
43 list.Add(1);
44 Test.AssertEquals(list.Count, 1);
45 Test.Assert(list.Remove(1));
46 Test.AssertEquals(list.Count, 0);
47 list.Add(1);
48 list.Add(1);
49 Test.AssertEquals(list.Count, 2);
50 Test.Assert(list.Remove(1));
51 Test.AssertEquals(list.Count, 1);
52 list.Add(0);
53 list.Add(1);
54 Test.AssertEquals(list[1], 0);
55 Test.AssertEquals(list.Count, 3);
56 Test.Assert(!list.Remove(2));
57 Test.Assert(list.Remove(1));
58 Test.AssertEquals(list[1], 1);
59 Test.AssertEquals(list.Count, 2);
60 }
61
62 public static void TestContains()
63 {
64 IList<int> list = new Eina.List<int>();
65 Test.AssertEquals(list.Count, 0);
66 Test.Assert(!list.Contains(0));
67 list.Add(0);
68 Test.Assert(list.Contains(0));
69 Test.Assert(list.Remove(0));
70 Test.Assert(!list.Contains(0));
71 list.Add(1);
72 list.Add(0);
73 Test.Assert(list.Contains(0));
74 }
75
76 public static void TestClear()
77 {
78 IList<int> list = new Eina.List<int>();
79 Test.AssertEquals(list.Count, 0);
80 list.Clear();
81 Test.AssertEquals(list.Count, 0);
82 list.Add(0);
83 Test.AssertEquals(list.Count, 1);
84 list.Clear();
85 Test.AssertEquals(list.Count, 0);
86 list.Add(0);
87 list.Add(0);
88 Test.AssertEquals(list.Count, 2);
89 list.Clear();
90 Test.AssertEquals(list.Count, 0);
91 list.Add(0);
92 list.Add(0);
93 Test.AssertEquals(list.Count, 2);
94 Test.Assert(list.Remove(0));
95 Test.AssertEquals(list.Count, 1);
96 list.Clear();
97 Test.AssertEquals(list.Count, 0);
98 }
99
100 public static void TestInsert()
101 {
102 IList<int> list = new Eina.List<int>();
103 list.Add(99);
104 Test.AssertEquals(list.Count, 1);
105 list.Insert(0, 6);
106 Test.AssertEquals(list.Count, 2);
107 Test.AssertEquals(list[0], 6);
108 list.Insert(1, 5);
109 Test.AssertEquals(list.Count, 3);
110 Test.AssertEquals(list[1], 5);
111 list.Insert(1, 10);
112 Test.AssertEquals(list.Count, 4);
113 Test.AssertEquals(list[1], 10);
114 list.RemoveAt(1);
115 Test.AssertEquals(list.Count, 3);
116 Test.AssertEquals(list[1], 5);
117 list.Insert(1, 42);
118 Test.AssertEquals(list.Count, 4);
119 Test.AssertEquals(list[1], 42);
120 }
121
122 public static void TestIndexOf()
123 {
124 IList<int> list = new Eina.List<int>();
125 Test.AssertEquals(list.Count, 0);
126 list.Add(1);
127 Test.AssertEquals(list.Count, 1);
128 Test.AssertEquals(0, list.IndexOf(1));
129 list.Insert(0, 0);
130 Test.AssertEquals(list.Count, 2);
131 Test.AssertEquals(0, list.IndexOf(0));
132 Test.AssertEquals(1, list.IndexOf(1));
133 list.Insert(0, 1);
134 Test.AssertEquals(list.Count, 3);
135 Test.AssertEquals(0, list.IndexOf(1));
136 Test.AssertEquals(1, list.IndexOf(0));
137 list.Insert(0, 1);
138 Test.AssertEquals(list.Count, 4);
139 Test.AssertEquals(0, list.IndexOf(1));
140 Test.AssertEquals(2, list.IndexOf(0));
141 }
142
143 public static void TestCopyTo()
144 {
145 IList<int> list = new Eina.List<int>();
146 Test.AssertEquals(list.Count, 0);
147 int[] random = {4, 40, 10, 42, 99};
148 list.Add(43);
149 list.Insert(0, 1);
150 list.Insert(1, 50);
151 Test.AssertEquals(list.Count, 3);
152 Array.ForEach(random, (n) => list.Add(n));
153 Test.AssertEquals(list.Count, 8);
154 int[] expected = {1, 50, 43, 4, 40, 10, 42, 99};
155 var result = new int[expected.Length];
156 list.CopyTo(result, 0);
157 for (int i = 0; i < expected.Length; ++i)
158 {
159 Test.AssertEquals(expected[i], result[i]);
160 }
161 }
162
163 public static void TestIdxOutBounds()
164 {
165 var list = new Eina.List<int>();
166 list.Add(4);
167 Test.AssertRaises<ArgumentOutOfRangeException>(()=>list.Nth(1));
168 Test.AssertRaises<ArgumentOutOfRangeException>(()=>list.Nth(-1));
169 Test.AssertNotRaises<ArgumentOutOfRangeException>
170 (()=>list.Nth(list.IndexOf(4)));
171 }
172
173 public static void TestReadOnly()
174 {
175 var list = new Eina.List<int>();
176 int[] array = {6, 5, 4, 3, 2};
177 list.Append(array);
178 Test.AssertEquals(list.Count, 5);
179 Test.AssertRaises<InvalidOperationException>(() => list.SetOwnership(false, true));
180 list.SetOwnership(false);
181 Test.AssertRaises<NotSupportedException>(() => list.Add(4));
182 Test.AssertRaises<NotSupportedException>(() => list.Append(6));
183 Test.AssertRaises<NotSupportedException>(() => list.Append(array));
184 Test.AssertRaises<NotSupportedException>(() => list.Remove(6));
185 Test.AssertEquals(list.Count, 5);
186 Test.AssertRaises<NotSupportedException>(() => list.RemoveAt(2));
187 Test.AssertRaises<NotSupportedException>(() => list.Insert(4, 4));
188 Test.AssertRaises<NotSupportedException>(() => list.Clear());
189 Test.AssertRaises<NotSupportedException>(() => list.Sort());
190 Test.Assert(list.ToArray().SequenceEqual(array));
191 }
192}
193};
diff --git a/src/tests/efl_mono/meson.build b/src/tests/efl_mono/meson.build
index 695ff07..54ddb64 100644
--- a/src/tests/efl_mono/meson.build
+++ b/src/tests/efl_mono/meson.build
@@ -81,7 +81,8 @@ efl_mono_src = [
81 'Value.cs', 81 'Value.cs',
82 'ValueEolian.cs', 82 'ValueEolian.cs',
83 'Inheritance.cs', 83 'Inheritance.cs',
84 'Hash.cs' 84 'Hash.cs',
85 'List.cs',
85] 86]
86 87
87if get_option('dotnet') 88if get_option('dotnet')