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.
13 #include "mono/metadata/mono-mlist.h"
14 #include "mono/metadata/appdomain.h"
15 #include "mono/metadata/class-internals.h"
16 #include "mono/metadata/object-internals.h"
20 MonoMList
* mono_mlist_alloc_checked (MonoObject
*data
, MonoError
*error
);
23 /* matches the System.MonoListItem object*/
31 * note: we only allocate in the root domain: this lists are
32 * not exposed to managed code
34 static MonoVTable
*monolist_item_vtable
= NULL
;
38 * \param data object to use as data
39 * Allocates a new managed list node with \p data as the contents.
40 * A managed list node also represents a singly-linked list.
41 * Managed lists are garbage collected, so there is no free routine
42 * and the user is required to keep references to the managed list
43 * to prevent it from being garbage collected.
46 mono_mlist_alloc (MonoObject
*data
)
49 MonoMList
*result
= mono_mlist_alloc_checked (data
, error
);
50 mono_error_cleanup (error
);
55 * mono_mlist_alloc_checked:
56 * \param data object to use as data
57 * \param error set on error
58 * Allocates a new managed list node with \p 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
)
70 if (!monolist_item_vtable
) {
72 MonoClass
*klass
= mono_class_load_from_name (mono_defaults
.corlib
, "Mono", "MonoListItem");
74 MonoClass
*klass
= mono_class_load_from_name (mono_defaults
.corlib
, "System", "MonoListItem");
76 monolist_item_vtable
= mono_class_vtable_checked (mono_get_root_domain (), klass
, error
);
77 mono_error_assert_ok (error
);
79 res
= (MonoMList
*)mono_object_new_specific_checked (monolist_item_vtable
, error
);
80 return_val_if_nok (error
, NULL
);
81 MONO_OBJECT_SETREF_INTERNAL (res
, data
, data
);
86 * mono_mlist_get_data:
87 * \param list the managed list node
88 * Get the object stored in the list node \p list.
91 mono_mlist_get_data (MonoMList
* list
)
97 * mono_mlist_set_data:
98 * \param list the managed list node
99 * Set the object content in the list node \p list.
102 mono_mlist_set_data (MonoMList
* list
, MonoObject
*data
)
104 MONO_OBJECT_SETREF_INTERNAL (list
, data
, data
);
108 * mono_mlist_set_next:
109 * \param list a managed list node
110 * \param next list node that will be next for the \p list node.
111 * Set next node for \p list to \p next.
114 mono_mlist_set_next (MonoMList
* list
, MonoMList
*next
)
119 MONO_OBJECT_SETREF_INTERNAL (list
, next
, next
);
125 * \param list the managed list
126 * Get the number of items in the list \p list.
127 * Since managed lists are singly-linked, this operation takes O(n) time.
130 mono_mlist_length (MonoMList
* list
)
142 * \param list the managed list node
143 * Returns the next managed list node starting from \p list.
146 mono_mlist_next (MonoMList
* list
)
153 * \param list the managed list node
154 * Returns the last managed list node in list \p list.
155 * Since managed lists are singly-linked, this operation takes O(n) time.
158 mono_mlist_last (MonoMList
* list
)
169 * mono_mlist_prepend:
170 * \param list the managed list
171 * \param data the object to add to the list
172 * Allocate a new list node with \p data as content and prepend it
173 * to the list \p list. \p list can be NULL.
176 mono_mlist_prepend (MonoMList
* list
, MonoObject
*data
)
179 MonoMList
*result
= mono_mlist_prepend_checked (list
, data
, error
);
180 mono_error_cleanup (error
);
185 * mono_mlist_prepend_checked:
186 * \param list the managed list
187 * \param data the object to add to the list
188 * \param error set on error
189 * Allocate a new list node with \p data as content and prepend it to
190 * the list \p list. \p list can be NULL. On failure returns NULL and sets
194 mono_mlist_prepend_checked (MonoMList
* list
, MonoObject
*data
, MonoError
*error
)
197 MonoMList
* res
= mono_mlist_alloc_checked (data
, error
);
198 return_val_if_nok (error
, NULL
);
201 MONO_OBJECT_SETREF_INTERNAL (res
, next
, list
);
207 * \param list the managed list
208 * \param data the object to add to the list
209 * Allocate a new list node with \p data as content and append it
210 * to the list \p list. \p list can be NULL.
211 * Since managed lists are singly-linked, this operation takes O(n) time.
214 mono_mlist_append (MonoMList
* list
, MonoObject
*data
)
217 MonoMList
*result
= mono_mlist_append_checked (list
, data
, error
);
218 mono_error_cleanup (error
);
223 * mono_mlist_append_checked:
224 * \param list the managed list
225 * \param data the object to add to the list
226 * \param error set on error
227 * Allocate a new list node with \p data as content and append it
228 * to the list \p list. \p list can be NULL.
229 * Since managed lists are singly-linked, this operation takes O(n) time.
230 * On failure returns NULL and sets \p error.
233 mono_mlist_append_checked (MonoMList
* list
, MonoObject
*data
, MonoError
*error
)
236 MonoMList
* res
= mono_mlist_alloc_checked (data
, error
);
237 return_val_if_nok (error
, NULL
);
240 MonoMList
* last
= mono_mlist_last (list
);
241 MONO_OBJECT_SETREF_INTERNAL (last
, next
, res
);
249 find_prev (MonoMList
* list
, MonoMList
*item
)
251 MonoMList
* prev
= NULL
;
262 * mono_mlist_remove_item:
263 * \param list the managed list
264 * \param data the object to remove from the list
265 * Remove the list node \p item from the managed list \p list.
266 * Since managed lists are singly-linked, this operation can take O(n) time.
269 mono_mlist_remove_item (MonoMList
* list
, MonoMList
*item
)
277 prev
= find_prev (list
, item
);
279 MONO_OBJECT_SETREF_INTERNAL (prev
, next
, item
->next
);