2 * mono-mlist.c: Managed object list implementation
5 * Paolo Molaro (lupus@ximian.com)
7 * Copyright 2006-2009 Novell, Inc (http://www.novell.com)
8 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
11 #include "mono/metadata/mono-mlist.h"
12 #include "mono/metadata/appdomain.h"
13 #include "mono/metadata/class-internals.h"
14 #include "mono/metadata/object-internals.h"
18 MonoMList* mono_mlist_alloc_checked (MonoObject *data, MonoError *error);
21 /* matches the System.MonoListItem object*/
29 * note: we only allocate in the root domain: this lists are
30 * not exposed to managed code
32 static MonoVTable *monolist_item_vtable = NULL;
36 * @data: object to use as data
38 * Allocates a new managed list node with @data as the contents.
39 * A managed list node also represents a singly-linked list.
40 * Managed lists are garbage collected, so there is no free routine
41 * and the user is required to keep references to the managed list
42 * to prevent it from being garbage collected.
45 mono_mlist_alloc (MonoObject *data)
48 MonoMList *result = mono_mlist_alloc_checked (data, &error);
49 mono_error_cleanup (&error);
54 * mono_mlist_alloc_checked:
55 * @data: object to use as data
56 * @error: set on error
58 * Allocates a new managed list node with @data as the contents. A
59 * managed list node also represents a singly-linked list. Managed
60 * lists are garbage collected, so there is no free routine and the
61 * user is required to keep references to the managed list to prevent
62 * it from being garbage collected. On failure returns NULL and sets
66 mono_mlist_alloc_checked (MonoObject *data, MonoError *error)
68 mono_error_init (error);
70 if (!monolist_item_vtable) {
71 MonoClass *klass = mono_class_load_from_name (mono_defaults.corlib, "System", "MonoListItem");
72 monolist_item_vtable = mono_class_vtable (mono_get_root_domain (), klass);
73 g_assert (monolist_item_vtable);
75 res = (MonoMList*)mono_object_new_fast_checked (monolist_item_vtable, error);
76 return_val_if_nok (error, NULL);
77 MONO_OBJECT_SETREF (res, data, data);
82 * mono_mlist_get_data:
83 * @list: the managed list node
85 * Get the object stored in the list node @list.
88 mono_mlist_get_data (MonoMList* list)
94 * mono_mlist_set_data:
95 * @list: the managed list node
97 * Set the object content in the list node @list.
100 mono_mlist_set_data (MonoMList* list, MonoObject *data)
102 MONO_OBJECT_SETREF (list, data, data);
106 * mono_mlist_set_next:
107 * @list: a managed list node
108 * @next: list node that will be next for the @list node.
110 * Set next node for @list to @next.
113 mono_mlist_set_next (MonoMList* list, MonoMList *next)
118 MONO_OBJECT_SETREF (list, next, next);
124 * @list: the managed list
126 * Get the number of items in the list @list.
127 * Since managed lists are singly-linked, this operation takes O(n) time.
130 mono_mlist_length (MonoMList* list)
142 * @list: the managed list node
144 * Returns the next managed list node starting from @list.
147 mono_mlist_next (MonoMList* list)
154 * @list: the managed list node
156 * Returns the last managed list node in list @list.
157 * Since managed lists are singly-linked, this operation takes O(n) time.
160 mono_mlist_last (MonoMList* list)
171 * mono_mlist_prepend:
172 * @list: the managed list
173 * @data: the object to add to the list
175 * Allocate a new list node with @data as content and prepend it
176 * to the list @list. @list can be NULL.
179 mono_mlist_prepend (MonoMList* list, MonoObject *data)
182 MonoMList *result = mono_mlist_prepend_checked (list, data, &error);
183 mono_error_cleanup (&error);
188 * mono_mlist_prepend_checked:
189 * @list: the managed list
190 * @data: the object to add to the list
191 * @error: set on error
193 * Allocate a new list node with @data as content and prepend it to
194 * the list @list. @list can be NULL. On failure returns NULL and sets
198 mono_mlist_prepend_checked (MonoMList* list, MonoObject *data, MonoError *error)
200 mono_error_init (error);
201 MonoMList* res = mono_mlist_alloc_checked (data, error);
202 return_val_if_nok (error, NULL);
205 MONO_OBJECT_SETREF (res, next, list);
211 * @list: the managed list
212 * @data: the object to add to the list
214 * Allocate a new list node with @data as content and append it
215 * to the list @list. @list can be NULL.
216 * Since managed lists are singly-linked, this operation takes O(n) time.
219 mono_mlist_append (MonoMList* list, MonoObject *data)
222 MonoMList *result = mono_mlist_append_checked (list, data, &error);
223 mono_error_cleanup (&error);
228 * mono_mlist_append_checked:
229 * @list: the managed list
230 * @data: the object to add to the list
231 * @error: set on error
233 * Allocate a new list node with @data as content and append it
234 * to the list @list. @list can be NULL.
235 * Since managed lists are singly-linked, this operation takes O(n) time.
236 * On failure returns NULL and sets @error.
239 mono_mlist_append_checked (MonoMList* list, MonoObject *data, MonoError *error)
241 mono_error_init (error);
242 MonoMList* res = mono_mlist_alloc_checked (data, error);
243 return_val_if_nok (error, NULL);
246 MonoMList* last = mono_mlist_last (list);
247 MONO_OBJECT_SETREF (last, next, res);
255 find_prev (MonoMList* list, MonoMList *item)
257 MonoMList* prev = NULL;
268 * mono_mlist_remove_item:
269 * @list: the managed list
270 * @data: the object to remove from the list
272 * Remove the list node @item from the managed list @list.
273 * Since managed lists are singly-linked, this operation can take O(n) time.
276 mono_mlist_remove_item (MonoMList* list, MonoMList *item)
284 prev = find_prev (list, item);
286 MONO_OBJECT_SETREF (prev, next, item->next);