1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module glib.ListSG;
26 
27 private import glib.Str;
28 private import glib.c.functions;
29 public  import glib.c.types;
30 private import gobject.ObjectG;
31 public  import gtkc.glibtypes;
32 
33 
34 /**
35  * The #GSList struct is used for each element in the singly-linked
36  * list.
37  */
38 public class ListSG
39 {
40 	/** the main Gtk struct */
41 	protected GSList* gSList;
42 	protected bool ownedRef;
43 
44 	/** Get the main Gtk struct */
45 	public GSList* getListSGStruct(bool transferOwnership = false)
46 	{
47 		if (transferOwnership)
48 			ownedRef = false;
49 		return gSList;
50 	}
51 
52 	/** the main Gtk struct as a void* */
53 	protected void* getStruct()
54 	{
55 		return cast(void*)gSList;
56 	}
57 
58 	/**
59 	 * Sets our main struct and passes it to the parent class.
60 	 */
61 	public this (GSList* gSList, bool ownedRef = false)
62 	{
63 		this.gSList = gSList;
64 		this.ownedRef = ownedRef;
65 	}
66 
67 	/** */
68 	@property void* data()
69 	{
70 		return gSList.data;
71 	}
72 
73 	/**
74 	 * get the next element
75 	 * Returns: the next element, or NULL if there are no more elements.
76 	 */
77 	@property ListSG next()
78 	{
79 		if ( gSList.next is null )
80 		{
81 			return null;
82 		}
83 
84 		return new ListSG(gSList.next);
85 	}
86 
87 	/**
88 	 * Turn the list into a D array of the desiered type.
89 	 * Type T wraps should match the type of the data.
90 	 */
91 	public T[] toArray(T, TC = getCType!T)()
92 	if ( is(T == class) )
93 	{
94 		T[] arr = new T[length()];
95 		ListSG list = this;
96 		size_t count;
97 
98 		while(list !is null && count < arr.length)
99 		{
100 			arr[count] = ObjectG.getDObject!(T)(cast(TC)list.data);
101 			list = list.next();
102 			count++;
103 		}
104 
105 		return arr;
106 	}
107 
108 	/** Ditto */
109 	public T[] toArray(T)()
110 	if ( is ( T == string ) )
111 	{
112 		T[] arr = new T[length()];
113 		ListSG list = this;
114 		size_t count;
115 
116 		while(list !is null && count < arr.length)
117 		{
118 			arr[count] = Str.toString(cast(char*)list.data);
119 			list = list.next();
120 			count++;
121 		}
122 
123 		return arr;
124 	}
125 
126 	private template getCType(T)
127 	{
128 		static if ( is(T == class) )
129 			alias getCType = typeof(T.tupleof[0]);
130 		else
131 			alias getCType = void*;
132 	}
133 
134 	unittest
135 	{
136 		import gobject.Value;
137 
138 		auto list = new ListSG(null);
139 		list = list.append(new Value(0).getValueStruct());
140 		list = list.append(new Value(1).getValueStruct());
141 		auto arr = list.toArray!Value();
142 
143 		assert(arr[0].getInt() == 0);
144 		assert(arr[1].getInt() == 1);
145 
146 		list = new ListSG(null);
147 		list = list.append(cast(void*)"test\0".ptr);
148 		list = list.append(cast(void*)"test2\0".ptr);
149 
150 		assert(["test", "test2"] == list.toArray!string());
151 	}
152 
153 	/**
154 	 */
155 
156 	/**
157 	 * Allocates space for one #GSList element. It is called by the
158 	 * g_slist_append(), g_slist_prepend(), g_slist_insert() and
159 	 * g_slist_insert_sorted() functions and so is rarely used on its own.
160 	 *
161 	 * Returns: a pointer to the newly-allocated #GSList element.
162 	 */
163 	public static ListSG alloc()
164 	{
165 		auto p = g_slist_alloc();
166 
167 		if(p is null)
168 		{
169 			return null;
170 		}
171 
172 		return new ListSG(cast(GSList*) p);
173 	}
174 
175 	/**
176 	 * Adds a new element on to the end of the list.
177 	 *
178 	 * The return value is the new start of the list, which may
179 	 * have changed, so make sure you store the new value.
180 	 *
181 	 * Note that g_slist_append() has to traverse the entire list
182 	 * to find the end, which is inefficient when adding multiple
183 	 * elements. A common idiom to avoid the inefficiency is to prepend
184 	 * the elements and reverse the list when all elements have been added.
185 	 *
186 	 * |[<!-- language="C" -->
187 	 * // Notice that these are initialized to the empty list.
188 	 * GSList *list = NULL, *number_list = NULL;
189 	 *
190 	 * // This is a list of strings.
191 	 * list = g_slist_append (list, "first");
192 	 * list = g_slist_append (list, "second");
193 	 *
194 	 * // This is a list of integers.
195 	 * number_list = g_slist_append (number_list, GINT_TO_POINTER (27));
196 	 * number_list = g_slist_append (number_list, GINT_TO_POINTER (14));
197 	 * ]|
198 	 *
199 	 * Params:
200 	 *     data = the data for the new element
201 	 *
202 	 * Returns: the new start of the #GSList
203 	 */
204 	public ListSG append(void* data)
205 	{
206 		auto p = g_slist_append(gSList, data);
207 
208 		if(p is null)
209 		{
210 			return null;
211 		}
212 
213 		return new ListSG(cast(GSList*) p);
214 	}
215 
216 	/**
217 	 * Adds the second #GSList onto the end of the first #GSList.
218 	 * Note that the elements of the second #GSList are not copied.
219 	 * They are used directly.
220 	 *
221 	 * Params:
222 	 *     list2 = the #GSList to add to the end of the first #GSList
223 	 *
224 	 * Returns: the start of the new #GSList
225 	 */
226 	public ListSG concat(ListSG list2)
227 	{
228 		auto p = g_slist_concat(gSList, (list2 is null) ? null : list2.getListSGStruct());
229 
230 		if(p is null)
231 		{
232 			return null;
233 		}
234 
235 		return new ListSG(cast(GSList*) p);
236 	}
237 
238 	/**
239 	 * Copies a #GSList.
240 	 *
241 	 * Note that this is a "shallow" copy. If the list elements
242 	 * consist of pointers to data, the pointers are copied but
243 	 * the actual data isn't. See g_slist_copy_deep() if you need
244 	 * to copy the data as well.
245 	 *
246 	 * Returns: a copy of @list
247 	 */
248 	public ListSG copy()
249 	{
250 		auto p = g_slist_copy(gSList);
251 
252 		if(p is null)
253 		{
254 			return null;
255 		}
256 
257 		return new ListSG(cast(GSList*) p);
258 	}
259 
260 	/**
261 	 * Makes a full (deep) copy of a #GSList.
262 	 *
263 	 * In contrast with g_slist_copy(), this function uses @func to make a copy of
264 	 * each list element, in addition to copying the list container itself.
265 	 *
266 	 * @func, as a #GCopyFunc, takes two arguments, the data to be copied
267 	 * and a @user_data pointer. On common processor architectures, it's safe to
268 	 * pass %NULL as @user_data if the copy function takes only one argument. You
269 	 * may get compiler warnings from this though if compiling with GCC’s
270 	 * `-Wcast-function-type` warning.
271 	 *
272 	 * For instance, if @list holds a list of GObjects, you can do:
273 	 * |[<!-- language="C" -->
274 	 * another_list = g_slist_copy_deep (list, (GCopyFunc) g_object_ref, NULL);
275 	 * ]|
276 	 *
277 	 * And, to entirely free the new list, you could do:
278 	 * |[<!-- language="C" -->
279 	 * g_slist_free_full (another_list, g_object_unref);
280 	 * ]|
281 	 *
282 	 * Params:
283 	 *     func = a copy function used to copy every element in the list
284 	 *     userData = user data passed to the copy function @func, or #NULL
285 	 *
286 	 * Returns: a full copy of @list, use g_slist_free_full() to free it
287 	 *
288 	 * Since: 2.34
289 	 */
290 	public ListSG copyDeep(GCopyFunc func, void* userData)
291 	{
292 		auto p = g_slist_copy_deep(gSList, func, userData);
293 
294 		if(p is null)
295 		{
296 			return null;
297 		}
298 
299 		return new ListSG(cast(GSList*) p);
300 	}
301 
302 	/**
303 	 * Removes the node link_ from the list and frees it.
304 	 * Compare this to g_slist_remove_link() which removes the node
305 	 * without freeing it.
306 	 *
307 	 * Removing arbitrary nodes from a singly-linked list requires time
308 	 * that is proportional to the length of the list (ie. O(n)). If you
309 	 * find yourself using g_slist_delete_link() frequently, you should
310 	 * consider a different data structure, such as the doubly-linked
311 	 * #GList.
312 	 *
313 	 * Params:
314 	 *     link = node to delete
315 	 *
316 	 * Returns: the new head of @list
317 	 */
318 	public ListSG deleteLink(ListSG link)
319 	{
320 		auto p = g_slist_delete_link(gSList, (link is null) ? null : link.getListSGStruct());
321 
322 		if(p is null)
323 		{
324 			return null;
325 		}
326 
327 		return new ListSG(cast(GSList*) p);
328 	}
329 
330 	/**
331 	 * Finds the element in a #GSList which
332 	 * contains the given data.
333 	 *
334 	 * Params:
335 	 *     data = the element data to find
336 	 *
337 	 * Returns: the found #GSList element,
338 	 *     or %NULL if it is not found
339 	 */
340 	public ListSG find(void* data)
341 	{
342 		auto p = g_slist_find(gSList, data);
343 
344 		if(p is null)
345 		{
346 			return null;
347 		}
348 
349 		return new ListSG(cast(GSList*) p);
350 	}
351 
352 	/**
353 	 * Finds an element in a #GSList, using a supplied function to
354 	 * find the desired element. It iterates over the list, calling
355 	 * the given function which should return 0 when the desired
356 	 * element is found. The function takes two #gconstpointer arguments,
357 	 * the #GSList element's data as the first argument and the
358 	 * given user data.
359 	 *
360 	 * Params:
361 	 *     data = user data passed to the function
362 	 *     func = the function to call for each element.
363 	 *         It should return 0 when the desired element is found
364 	 *
365 	 * Returns: the found #GSList element, or %NULL if it is not found
366 	 */
367 	public ListSG findCustom(void* data, GCompareFunc func)
368 	{
369 		auto p = g_slist_find_custom(gSList, data, func);
370 
371 		if(p is null)
372 		{
373 			return null;
374 		}
375 
376 		return new ListSG(cast(GSList*) p);
377 	}
378 
379 	alias foreac = foreach_;
380 	/**
381 	 * Calls a function for each element of a #GSList.
382 	 *
383 	 * It is safe for @func to remove the element from @list, but it must
384 	 * not modify any part of the list after that element.
385 	 *
386 	 * Params:
387 	 *     func = the function to call with each element's data
388 	 *     userData = user data to pass to the function
389 	 */
390 	public void foreach_(GFunc func, void* userData)
391 	{
392 		g_slist_foreach(gSList, func, userData);
393 	}
394 
395 	/**
396 	 * Frees all of the memory used by a #GSList.
397 	 * The freed elements are returned to the slice allocator.
398 	 *
399 	 * If list elements contain dynamically-allocated memory,
400 	 * you should either use g_slist_free_full() or free them manually
401 	 * first.
402 	 */
403 	public void free()
404 	{
405 		g_slist_free(gSList);
406 	}
407 
408 	/**
409 	 * Frees one #GSList element.
410 	 * It is usually used after g_slist_remove_link().
411 	 */
412 	public void free1()
413 	{
414 		g_slist_free_1(gSList);
415 	}
416 
417 	/**
418 	 * Convenience method, which frees all the memory used by a #GSList, and
419 	 * calls the specified destroy function on every element's data.
420 	 *
421 	 * @free_func must not modify the list (eg, by removing the freed
422 	 * element from it).
423 	 *
424 	 * Params:
425 	 *     freeFunc = the function to be called to free each element's data
426 	 *
427 	 * Since: 2.28
428 	 */
429 	public void freeFull(GDestroyNotify freeFunc)
430 	{
431 		g_slist_free_full(gSList, freeFunc);
432 	}
433 
434 	/**
435 	 * Gets the position of the element containing
436 	 * the given data (starting from 0).
437 	 *
438 	 * Params:
439 	 *     data = the data to find
440 	 *
441 	 * Returns: the index of the element containing the data,
442 	 *     or -1 if the data is not found
443 	 */
444 	public int index(void* data)
445 	{
446 		return g_slist_index(gSList, data);
447 	}
448 
449 	/**
450 	 * Inserts a new element into the list at the given position.
451 	 *
452 	 * Params:
453 	 *     data = the data for the new element
454 	 *     position = the position to insert the element.
455 	 *         If this is negative, or is larger than the number
456 	 *         of elements in the list, the new element is added on
457 	 *         to the end of the list.
458 	 *
459 	 * Returns: the new start of the #GSList
460 	 */
461 	public ListSG insert(void* data, int position)
462 	{
463 		auto p = g_slist_insert(gSList, data, position);
464 
465 		if(p is null)
466 		{
467 			return null;
468 		}
469 
470 		return new ListSG(cast(GSList*) p);
471 	}
472 
473 	/**
474 	 * Inserts a node before @sibling containing @data.
475 	 *
476 	 * Params:
477 	 *     sibling = node to insert @data before
478 	 *     data = data to put in the newly-inserted node
479 	 *
480 	 * Returns: the new head of the list.
481 	 */
482 	public ListSG insertBefore(ListSG sibling, void* data)
483 	{
484 		auto p = g_slist_insert_before(gSList, (sibling is null) ? null : sibling.getListSGStruct(), data);
485 
486 		if(p is null)
487 		{
488 			return null;
489 		}
490 
491 		return new ListSG(cast(GSList*) p);
492 	}
493 
494 	/**
495 	 * Inserts a new element into the list, using the given
496 	 * comparison function to determine its position.
497 	 *
498 	 * Params:
499 	 *     data = the data for the new element
500 	 *     func = the function to compare elements in the list.
501 	 *         It should return a number > 0 if the first parameter
502 	 *         comes after the second parameter in the sort order.
503 	 *
504 	 * Returns: the new start of the #GSList
505 	 */
506 	public ListSG insertSorted(void* data, GCompareFunc func)
507 	{
508 		auto p = g_slist_insert_sorted(gSList, data, func);
509 
510 		if(p is null)
511 		{
512 			return null;
513 		}
514 
515 		return new ListSG(cast(GSList*) p);
516 	}
517 
518 	/**
519 	 * Inserts a new element into the list, using the given
520 	 * comparison function to determine its position.
521 	 *
522 	 * Params:
523 	 *     data = the data for the new element
524 	 *     func = the function to compare elements in the list.
525 	 *         It should return a number > 0 if the first parameter
526 	 *         comes after the second parameter in the sort order.
527 	 *     userData = data to pass to comparison function
528 	 *
529 	 * Returns: the new start of the #GSList
530 	 *
531 	 * Since: 2.10
532 	 */
533 	public ListSG insertSortedWithData(void* data, GCompareDataFunc func, void* userData)
534 	{
535 		auto p = g_slist_insert_sorted_with_data(gSList, data, func, userData);
536 
537 		if(p is null)
538 		{
539 			return null;
540 		}
541 
542 		return new ListSG(cast(GSList*) p);
543 	}
544 
545 	/**
546 	 * Gets the last element in a #GSList.
547 	 *
548 	 * This function iterates over the whole list.
549 	 *
550 	 * Returns: the last element in the #GSList,
551 	 *     or %NULL if the #GSList has no elements
552 	 */
553 	public ListSG last()
554 	{
555 		auto p = g_slist_last(gSList);
556 
557 		if(p is null)
558 		{
559 			return null;
560 		}
561 
562 		return new ListSG(cast(GSList*) p);
563 	}
564 
565 	/**
566 	 * Gets the number of elements in a #GSList.
567 	 *
568 	 * This function iterates over the whole list to
569 	 * count its elements. To check whether the list is non-empty, it is faster to
570 	 * check @list against %NULL.
571 	 *
572 	 * Returns: the number of elements in the #GSList
573 	 */
574 	public uint length()
575 	{
576 		return g_slist_length(gSList);
577 	}
578 
579 	/**
580 	 * Gets the element at the given position in a #GSList.
581 	 *
582 	 * Params:
583 	 *     n = the position of the element, counting from 0
584 	 *
585 	 * Returns: the element, or %NULL if the position is off
586 	 *     the end of the #GSList
587 	 */
588 	public ListSG nth(uint n)
589 	{
590 		auto p = g_slist_nth(gSList, n);
591 
592 		if(p is null)
593 		{
594 			return null;
595 		}
596 
597 		return new ListSG(cast(GSList*) p);
598 	}
599 
600 	/**
601 	 * Gets the data of the element at the given position.
602 	 *
603 	 * Params:
604 	 *     n = the position of the element
605 	 *
606 	 * Returns: the element's data, or %NULL if the position
607 	 *     is off the end of the #GSList
608 	 */
609 	public void* nthData(uint n)
610 	{
611 		return g_slist_nth_data(gSList, n);
612 	}
613 
614 	/**
615 	 * Gets the position of the given element
616 	 * in the #GSList (starting from 0).
617 	 *
618 	 * Params:
619 	 *     llink = an element in the #GSList
620 	 *
621 	 * Returns: the position of the element in the #GSList,
622 	 *     or -1 if the element is not found
623 	 */
624 	public int position(ListSG llink)
625 	{
626 		return g_slist_position(gSList, (llink is null) ? null : llink.getListSGStruct());
627 	}
628 
629 	/**
630 	 * Adds a new element on to the start of the list.
631 	 *
632 	 * The return value is the new start of the list, which
633 	 * may have changed, so make sure you store the new value.
634 	 *
635 	 * |[<!-- language="C" -->
636 	 * // Notice that it is initialized to the empty list.
637 	 * GSList *list = NULL;
638 	 * list = g_slist_prepend (list, "last");
639 	 * list = g_slist_prepend (list, "first");
640 	 * ]|
641 	 *
642 	 * Params:
643 	 *     data = the data for the new element
644 	 *
645 	 * Returns: the new start of the #GSList
646 	 */
647 	public ListSG prepend(void* data)
648 	{
649 		auto p = g_slist_prepend(gSList, data);
650 
651 		if(p is null)
652 		{
653 			return null;
654 		}
655 
656 		return new ListSG(cast(GSList*) p);
657 	}
658 
659 	/**
660 	 * Removes an element from a #GSList.
661 	 * If two elements contain the same data, only the first is removed.
662 	 * If none of the elements contain the data, the #GSList is unchanged.
663 	 *
664 	 * Params:
665 	 *     data = the data of the element to remove
666 	 *
667 	 * Returns: the new start of the #GSList
668 	 */
669 	public ListSG remove(void* data)
670 	{
671 		auto p = g_slist_remove(gSList, data);
672 
673 		if(p is null)
674 		{
675 			return null;
676 		}
677 
678 		return new ListSG(cast(GSList*) p);
679 	}
680 
681 	/**
682 	 * Removes all list nodes with data equal to @data.
683 	 * Returns the new head of the list. Contrast with
684 	 * g_slist_remove() which removes only the first node
685 	 * matching the given data.
686 	 *
687 	 * Params:
688 	 *     data = data to remove
689 	 *
690 	 * Returns: new head of @list
691 	 */
692 	public ListSG removeAll(void* data)
693 	{
694 		auto p = g_slist_remove_all(gSList, data);
695 
696 		if(p is null)
697 		{
698 			return null;
699 		}
700 
701 		return new ListSG(cast(GSList*) p);
702 	}
703 
704 	/**
705 	 * Removes an element from a #GSList, without
706 	 * freeing the element. The removed element's next
707 	 * link is set to %NULL, so that it becomes a
708 	 * self-contained list with one element.
709 	 *
710 	 * Removing arbitrary nodes from a singly-linked list
711 	 * requires time that is proportional to the length of the list
712 	 * (ie. O(n)). If you find yourself using g_slist_remove_link()
713 	 * frequently, you should consider a different data structure,
714 	 * such as the doubly-linked #GList.
715 	 *
716 	 * Params:
717 	 *     link = an element in the #GSList
718 	 *
719 	 * Returns: the new start of the #GSList, without the element
720 	 */
721 	public ListSG removeLink(ListSG link)
722 	{
723 		auto p = g_slist_remove_link(gSList, (link is null) ? null : link.getListSGStruct());
724 
725 		if(p is null)
726 		{
727 			return null;
728 		}
729 
730 		return new ListSG(cast(GSList*) p);
731 	}
732 
733 	/**
734 	 * Reverses a #GSList.
735 	 *
736 	 * Returns: the start of the reversed #GSList
737 	 */
738 	public ListSG reverse()
739 	{
740 		auto p = g_slist_reverse(gSList);
741 
742 		if(p is null)
743 		{
744 			return null;
745 		}
746 
747 		return new ListSG(cast(GSList*) p);
748 	}
749 
750 	/**
751 	 * Sorts a #GSList using the given comparison function. The algorithm
752 	 * used is a stable sort.
753 	 *
754 	 * Params:
755 	 *     compareFunc = the comparison function used to sort the #GSList.
756 	 *         This function is passed the data from 2 elements of the #GSList
757 	 *         and should return 0 if they are equal, a negative value if the
758 	 *         first element comes before the second, or a positive value if
759 	 *         the first element comes after the second.
760 	 *
761 	 * Returns: the start of the sorted #GSList
762 	 */
763 	public ListSG sort(GCompareFunc compareFunc)
764 	{
765 		auto p = g_slist_sort(gSList, compareFunc);
766 
767 		if(p is null)
768 		{
769 			return null;
770 		}
771 
772 		return new ListSG(cast(GSList*) p);
773 	}
774 
775 	/**
776 	 * Like g_slist_sort(), but the sort function accepts a user data argument.
777 	 *
778 	 * Params:
779 	 *     compareFunc = comparison function
780 	 *     userData = data to pass to comparison function
781 	 *
782 	 * Returns: new head of the list
783 	 */
784 	public ListSG sortWithData(GCompareDataFunc compareFunc, void* userData)
785 	{
786 		auto p = g_slist_sort_with_data(gSList, compareFunc, userData);
787 
788 		if(p is null)
789 		{
790 			return null;
791 		}
792 
793 		return new ListSG(cast(GSList*) p);
794 	}
795 }