3 * Managed object list implementation
6 * Paolo Molaro (lupus@ximian.com)
8 * Copyright 2006-2009 Novell, Inc (http://www.novell.com)
9 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
12 #include "mono/metadata/mono-mlist.h"
13 #include "mono/metadata/appdomain.h"
14 #include "mono/metadata/class-internals.h"
15 #include "mono/metadata/object-internals.h"
19 MonoMList* mono_mlist_alloc_checked (MonoObject *data, MonoError *error);
22 /* matches the System.MonoListItem object*/
30 * note: we only allocate in the root domain: this lists are
31 * not exposed to managed code
33 static MonoVTable *monolist_item_vtable = NULL;
37 * \param data object to use as data
38 * Allocates a new managed list node with \p 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 * \param data object to use as data
56 * \param error set on error
57 * Allocates a new managed list node with \p data as the contents. A
58 * managed list node also represents a singly-linked list. Managed
59 * lists are garbage collected, so there is no free routine and the
60 * user is required to keep references to the managed list to prevent
61 * it from being garbage collected. On failure returns NULL and sets
65 mono_mlist_alloc_checked (MonoObject *data, MonoError *error)
69 if (!monolist_item_vtable) {
70 MonoClass *klass = mono_class_load_from_name (mono_defaults.corlib, "System", "MonoListItem");
71 monolist_item_vtable = mono_class_vtable (mono_get_root_domain (), klass);
72 g_assert (monolist_item_vtable);
74 res = (MonoMList*)mono_object_new_fast_checked (monolist_item_vtable, error);
75 return_val_if_nok (error, NULL);
76 MONO_OBJECT_SETREF (res, data, data);
81 * mono_mlist_get_data:
82 * \param list the managed list node
83 * Get the object stored in the list node \p list.
86 mono_mlist_get_data (MonoMList* list)
92 * mono_mlist_set_data:
93 * \param list the managed list node
94 * Set the object content in the list node \p list.
97 mono_mlist_set_data (MonoMList* list, MonoObject *data)
99 MONO_OBJECT_SETREF (list, data, data);
103 * mono_mlist_set_next:
104 * \param list a managed list node
105 * \param next list node that will be next for the \p list node.
106 * Set next node for \p list to \p next.
109 mono_mlist_set_next (MonoMList* list, MonoMList *next)
114 MONO_OBJECT_SETREF (list, next, next);
120 * \param list the managed list
121 * Get the number of items in the list \p list.
122 * Since managed lists are singly-linked, this operation takes O(n) time.
125 mono_mlist_length (MonoMList* list)
137 * \param list the managed list node
138 * Returns the next managed list node starting from \p list.
141 mono_mlist_next (MonoMList* list)
148 * \param list the managed list node
149 * Returns the last managed list node in list \p list.
150 * Since managed lists are singly-linked, this operation takes O(n) time.
153 mono_mlist_last (MonoMList* list)
164 * mono_mlist_prepend:
165 * \param list the managed list
166 * \param data the object to add to the list
167 * Allocate a new list node with \p data as content and prepend it
168 * to the list \p list. \p list can be NULL.
171 mono_mlist_prepend (MonoMList* list, MonoObject *data)
174 MonoMList *result = mono_mlist_prepend_checked (list, data, &error);
175 mono_error_cleanup (&error);
180 * mono_mlist_prepend_checked:
181 * \param list the managed list
182 * \param data the object to add to the list
183 * \param error set on error
184 * Allocate a new list node with \p data as content and prepend it to
185 * the list \p list. \p list can be NULL. On failure returns NULL and sets
189 mono_mlist_prepend_checked (MonoMList* list, MonoObject *data, MonoError *error)
192 MonoMList* res = mono_mlist_alloc_checked (data, error);
193 return_val_if_nok (error, NULL);
196 MONO_OBJECT_SETREF (res, next, list);
202 * \param list the managed list
203 * \param data the object to add to the list
204 * Allocate a new list node with \p data as content and append it
205 * to the list \p list. \p list can be NULL.
206 * Since managed lists are singly-linked, this operation takes O(n) time.
209 mono_mlist_append (MonoMList* list, MonoObject *data)
212 MonoMList *result = mono_mlist_append_checked (list, data, &error);
213 mono_error_cleanup (&error);
218 * mono_mlist_append_checked:
219 * \param list the managed list
220 * \param data the object to add to the list
221 * \param error set on error
222 * Allocate a new list node with \p data as content and append it
223 * to the list \p list. \p list can be NULL.
224 * Since managed lists are singly-linked, this operation takes O(n) time.
225 * On failure returns NULL and sets \p error.
228 mono_mlist_append_checked (MonoMList* list, MonoObject *data, MonoError *error)
231 MonoMList* res = mono_mlist_alloc_checked (data, error);
232 return_val_if_nok (error, NULL);
235 MonoMList* last = mono_mlist_last (list);
236 MONO_OBJECT_SETREF (last, next, res);
244 find_prev (MonoMList* list, MonoMList *item)
246 MonoMList* prev = NULL;
257 * mono_mlist_remove_item:
258 * \param list the managed list
259 * \param data the object to remove from the list
260 * Remove the list node \p item from the managed list \p list.
261 * Since managed lists are singly-linked, this operation can take O(n) time.
264 mono_mlist_remove_item (MonoMList* list, MonoMList *item)
272 prev = find_prev (list, item);
274 MONO_OBJECT_SETREF (prev, next, item->next);