Max 5 API Reference
00001 #ifndef _LINKLIST_H_ 00002 #define _LINKLIST_H_ 00003 00004 #if C74_PRAGMA_STRUCT_PACKPUSH 00005 #pragma pack(push, 2) 00006 #elif C74_PRAGMA_STRUCT_PACK 00007 #pragma pack(2) 00008 #endif 00009 00010 00011 /** A linklist element. This struct is provided for debugging convenience, 00012 but should be considered opaque and is subject to change without notice. 00013 00014 @ingroup linklist 00015 @see t_linklist 00016 */ 00017 typedef struct _llelem 00018 { 00019 t_object *thing; 00020 struct _llelem *next; 00021 struct _llelem *prev; 00022 } t_llelem; 00023 00024 00025 /** The linklist object. This struct is provided for debugging convenience, 00026 but should be considered opaque and is subject to change without notice. 00027 00028 @ingroup linklist 00029 @see t_llelem 00030 */ 00031 typedef struct _linklist 00032 { 00033 t_object ob; 00034 long count; 00035 t_llelem *head; 00036 t_llelem *tail; 00037 long readonly; 00038 void *lock; 00039 t_llelem *cache; 00040 long flags; 00041 } t_linklist; 00042 00043 #if C74_PRAGMA_STRUCT_PACKPUSH 00044 #pragma pack(pop) 00045 #elif C74_PRAGMA_STRUCT_PACK 00046 #pragma pack() 00047 #endif 00048 00049 #define LINKLIST_PRUNE_CHUCK 0x00000001L // chucks object rather than deletes it in linklist_prune 00050 00051 /** 00052 Comparison function pointer type. 00053 00054 Methods that require a comparison function pointer to be passed in use this type. 00055 It should return <code>true</code> or <code>false</code> depending on the outcome of the 00056 comparison of the two linklist items passed in as arguments. 00057 00058 @ingroup datastore 00059 @see linklist_match() 00060 @see hashtab_findfirst() 00061 @see indexmap_sort() 00062 */ 00063 typedef long (*t_cmpfn)(void *, void *); 00064 00065 #ifdef __cplusplus 00066 extern "C" { 00067 #endif // __cplusplus 00068 00069 00070 // documented elsewhere 00071 void *object_method(void *x, t_symbol *s, ...); 00072 00073 00074 // private 00075 void c_linklist(void); 00076 00077 00078 /** 00079 Create a new linklist object. 00080 You can free the linklist by calling object_free() on the linklist's pointer, 00081 or by using linklist_chuck(). 00082 00083 @ingroup linklist 00084 @return Pointer to the new linklist object. 00085 00086 @see object_free() 00087 @see linklist_chuck() 00088 */ 00089 t_linklist *linklist_new(void); 00090 00091 00092 /** 00093 Free a linklist, but don't free the items it contains. 00094 00095 The linklist can contain a variety of different types of data. 00096 By default, the linklist assumes that all items are max objects with a valid 00097 #t_object header. 00098 00099 You can alter the linklist's notion of what it contains by using the 00100 linklist_flags() method. 00101 00102 When you free the linklist by calling object_free() it then tries to free all of the items it contains. 00103 If the linklist is storing a custom type of data, or should otherwise not free the data it contains, 00104 then call linklist_chuck() to free the object instead of object_free(). 00105 00106 @ingroup linklist 00107 @param x The linklist object to be freed. 00108 @see object_free 00109 */ 00110 void linklist_chuck(t_linklist *x); 00111 00112 00113 /** 00114 Return the number of items in a linklist object. 00115 00116 @ingroup linklist 00117 00118 @param x The linklist instance. 00119 @return The number of items in the linklist object. 00120 */ 00121 long linklist_getsize(t_linklist *x); 00122 00123 00124 /** 00125 Return the item stored in a linklist at a specified index. 00126 00127 @ingroup linklist 00128 00129 @param x The linklist instance. 00130 @param index The index in the linklist to fetch. Indices are zero-based. 00131 @return The item from the linklist stored at index. 00132 If there is no item at the index, <code>NULL</code> is returned 00133 */ 00134 void *linklist_getindex(t_linklist *x, long index); 00135 00136 00137 // private 00138 t_llelem *linklist_index2ptr(t_linklist *x, long index); 00139 00140 00141 // private 00142 long linklist_ptr2index(t_linklist *x, t_llelem *p); 00143 00144 00145 /** 00146 Return an item's index, given the item itself. 00147 00148 @ingroup linklist 00149 00150 @param x The linklist instance. 00151 @param p The item pointer to search for in the linklist. 00152 @return The index of the item given in the linklist. 00153 If the item is not in the linklist #MAX_ERR_GENERIC is returned. 00154 */ 00155 long linklist_objptr2index(t_linklist *x, void *p); 00156 00157 00158 /** 00159 Add an item to the end of the list. 00160 00161 @ingroup linklist 00162 00163 @param x The linklist instance. 00164 @param o The item pointer to append to the linked-list. 00165 @return The index of the item in the linklist. 00166 */ 00167 long linklist_append(t_linklist *x, void *o); 00168 00169 00170 /** Insert an item into the list at the specified index. 00171 @ingroup linklist 00172 @param x The linklist instance. 00173 @param o The item pointer to insert. 00174 @param index The index at which to insert. Index 0 is the head of the list. 00175 @return The index of the item in the linklist, or -1 if the insert failed. 00176 */ 00177 long linklist_insertindex(t_linklist *x, void *o, long index); 00178 00179 00180 /** Insert an item into the list, keeping the list sorted according to a specified comparison function. 00181 @ingroup linklist 00182 @param x The linklist instance. 00183 @param o The item pointer to insert. 00184 @param cmpfn A comparison function by which the list should be sorted. 00185 @return The index of the new item in the linklist, or -1 if the insert failed. 00186 */ 00187 long linklist_insert_sorted(t_linklist *x, void *o, long cmpfn(void *, void *)); 00188 00189 00190 /** 00191 Insert an item into the list after another specified item. 00192 00193 @ingroup linklist 00194 00195 @param x The linklist instance. 00196 @param o The item pointer to insert. 00197 @param objptr The item pointer after which to insert in the list. 00198 00199 @return An opaque linklist element. 00200 */ 00201 t_llelem *linklist_insertafterobjptr(t_linklist *x, void *o, void *objptr); // inserts object o after objptr 00202 00203 00204 /** 00205 Insert an item into the list before another specified item. 00206 00207 @ingroup linklist 00208 00209 @param x The linklist instance. 00210 @param o The item pointer to insert. 00211 @param objptr The item pointer before which to insert in the list. 00212 00213 @return An opaque linklist element. 00214 */ 00215 t_llelem *linklist_insertbeforeobjptr(t_linklist *x, void *o, void *objptr); // inserts object o before objptr 00216 00217 00218 /** 00219 Move an existing item in the list to a position after another specified item in the list. 00220 00221 @ingroup linklist 00222 00223 @param x The linklist instance. 00224 @param o The item pointer to insert. 00225 @param objptr The item pointer after which to move o in the list. 00226 00227 @return An opaque linklist element. 00228 */ 00229 t_llelem *linklist_moveafterobjptr(t_linklist *x, void *o, void *objptr); // move existing object o after objptr 00230 00231 00232 /** 00233 Move an existing item in the list to a position before another specified item in the list. 00234 00235 @ingroup linklist 00236 00237 @param x The linklist instance. 00238 @param o The item pointer to insert. 00239 @param objptr The item pointer before which to move o in the list. 00240 00241 @return An opaque linklist element. 00242 */ 00243 t_llelem *linklist_movebeforeobjptr(t_linklist *x, void *o, void *objptr); // move existing object o before objptr 00244 00245 00246 // private 00247 t_llelem *linklist_insertptr(t_linklist *x, void *o, t_llelem *p); //inserts before ptr 00248 00249 00250 /** 00251 Remove the item from the list at the specified index and free it. 00252 00253 The linklist can contain a variety of different types of data. 00254 By default, the linklist assumes that all items are max objects with a valid 00255 #t_object header. Thus by default, it frees items by calling object_free() on them. 00256 00257 You can alter the linklist's notion of what it contains by using the 00258 linklist_flags() method. 00259 00260 If you wish to remove an item from the linklist and free it yourself, then you 00261 should use linklist_chuckptr(). 00262 00263 @ingroup linklist 00264 00265 @param x The linklist instance. 00266 @param index The index of the item to delete. 00267 @return Returns #MAX_ERR_NONE on successful deletion, otherwise returns #MAX_ERR_GENERIC 00268 00269 @see linklist_chuckindex 00270 @see linklist_chuckobject 00271 */ 00272 long linklist_deleteindex(t_linklist *x, long index); 00273 00274 00275 /** 00276 Remove the item from the list at the specified index. 00277 00278 You are responsible for freeing any memory associated with the item that is 00279 removed from the linklist. 00280 00281 @ingroup linklist 00282 00283 @param x The linklist instance. 00284 @param index The index of the item to remove. 00285 @return Returns #MAX_ERR_NONE on successful removal, otherwise returns #MAX_ERR_GENERIC 00286 00287 @see linklist_deleteindex 00288 @see linklist_chuckobject 00289 */ 00290 long linklist_chuckindex(t_linklist *x, long index); 00291 00292 00293 /** 00294 Remove the specified item from the list. 00295 00296 You are responsible for freeing any memory associated with the item that is 00297 removed from the linklist. 00298 00299 @ingroup linklist 00300 00301 @param x The linklist instance. 00302 @param o The pointer to the item to remove. 00303 @return Returns #MAX_ERR_NONE on successful removal, otherwise returns #MAX_ERR_GENERIC 00304 00305 @see linklist_deleteindex 00306 @see linklist_chuckindex 00307 */ 00308 void linklist_chuckobject(t_linklist *x, void *o); 00309 00310 00311 // private 00312 long linklist_deleteptr(t_linklist *x, t_llelem *p); 00313 00314 00315 // private 00316 long linklist_chuckptr(t_linklist *x, t_llelem *p); //like delete, but don't free it 00317 00318 00319 /** 00320 Remove and free all items in the list. 00321 00322 Freeing items in the list is subject to the same rules as linklist_deleteindex(). 00323 You can alter the linklist's notion of what it contains, and thus how items are freed, 00324 by using the linklist_flags() method. 00325 00326 @ingroup linklist 00327 @param x The linklist instance. 00328 */ 00329 void linklist_clear(t_linklist *x); 00330 00331 00332 // private 00333 long linklist_insertnodeindex(t_linklist *x, t_llelem *p, long index); 00334 00335 // private 00336 t_llelem *linklist_insertnodeptr(t_linklist *x, t_llelem *p1, t_llelem *p2); 00337 00338 // private 00339 long linklist_appendnode(t_linklist *x, t_llelem *p); 00340 00341 // private 00342 t_llelem *linklistelem_new(t_linklist *x); 00343 00344 // private 00345 void linklistelem_free(t_linklist *x, t_llelem *elem); 00346 00347 00348 /** 00349 Retrieve linklist items as an array of pointers. 00350 00351 @ingroup linklist 00352 00353 @param x The linklist instance. 00354 @param a The address of the first pointer in the array to fill. 00355 @param max The number of pointers in the array. 00356 @return The number of items from the list actually returned in the array. 00357 */ 00358 long linklist_makearray(t_linklist *x, void **a, long max); 00359 00360 00361 /** 00362 Reverse the order of items in the linked-list. 00363 00364 @ingroup linklist 00365 @param x The linklist instance. 00366 */ 00367 void linklist_reverse(t_linklist *x); 00368 00369 00370 /** 00371 Rotate items in the linked list in circular fashion. 00372 00373 @ingroup linklist 00374 @param x The linklist instance. 00375 @param i The number of positions in the list to shift items. 00376 */ 00377 void linklist_rotate(t_linklist *x, long i); 00378 00379 00380 /** 00381 Randomize the order of items in the linked-list. 00382 00383 @ingroup linklist 00384 @param x The linklist instance. 00385 */ 00386 void linklist_shuffle(t_linklist *x); 00387 00388 00389 /** 00390 Swap the position of two items in the linked-list, specified by index. 00391 00392 @ingroup linklist 00393 @param x The linklist instance. 00394 @param a The index of the first item to swap. 00395 @param b The index of the second item to swap. 00396 */ 00397 void linklist_swap(t_linklist *x, long a, long b); 00398 00399 00400 /** 00401 Search the linked list for the first item meeting defined criteria. 00402 The items in the list are traversed, calling a specified comparison function on each 00403 until the comparison function returns true. 00404 00405 @ingroup linklist 00406 @param x The linklist instance. 00407 @param o The address to pointer that will be set with the matching item. 00408 @param cmpfn The function used to determine a match in the list. 00409 @param cmpdata An argument to be passed to the #t_cmpfn. 00410 This will be passed as the second of the two args to the #t_cmpfn. 00411 The first arg will be the linklist item at each iteration in the list. 00412 @return The index of the matching item, or -1 if no match is found. 00413 00414 @remark The following shows how to manually do what linklist_chuckobject() does. 00415 @code 00416 void *obj; 00417 long index; 00418 00419 index = linklist_findfirst(x, &obj, #linklist_match, o); 00420 if(index != -1) 00421 linklist_chuckindex(x, index); 00422 @endcode 00423 00424 @see linklist_match 00425 @see t_cmpfn 00426 @see linklist_findall 00427 */ 00428 long linklist_findfirst(t_linklist *x, void **o, long cmpfn(void *, void *), void *cmpdata); 00429 00430 00431 /** 00432 Search the linked list for all items meeting defined criteria. 00433 The items in the list are traversed, calling a specified comparison function on each, 00434 and returning the matches in another linklist. 00435 00436 @ingroup linklist 00437 @param x The linklist instance. 00438 @param out The address to a #t_linklist pointer. 00439 You should initialize the pointer to NULL before calling linklist_findall(). 00440 A new linklist will be created internally by linklist_findall() and returned here. 00441 @param cmpfn The function used to determine a match in the list. 00442 @param cmpdata An argument to be passed to the #t_cmpfn. 00443 This will be passed as the second of the two args to the #t_cmpfn. 00444 The first arg will be the linklist item at each iteration in the list. 00445 00446 @remark The following example assumes you have a linklist called myLinkList, and #t_cmpfn called 00447 myCmpFunction, and some sort of data to match in someCriteria. 00448 @code 00449 t_linklist *results = NULL; 00450 00451 linklist_findall(myLinkList, &results, myCmpFunction, (void *)someCriteria); 00452 // do something here with the 'results' linklist 00453 // then free the results linklist 00454 linklist_chuck(results); 00455 @endcode 00456 00457 @see linklist_match 00458 @see t_cmpfn 00459 @see linklist_findfirst 00460 */ 00461 void linklist_findall(t_linklist *x, t_linklist **out, long cmpfn(void *, void *), void *cmpdata); 00462 00463 00464 /** 00465 Call the named message on every object in the linklist. 00466 The linklist_methodall() function requires that all items in the linklist are 00467 object instances with a valid t_object header. 00468 00469 @ingroup linklist 00470 @param x The linklist instance. 00471 @param s The name of the message to send to the objects. 00472 @param ... Any arguments to be sent with the message. 00473 00474 @remark Internally, this function uses object_method(), meaning that no errors will be 00475 posted if the message name does not exist for the object. It also means that 00476 messages sent methods with #A_GIMME definitions will need to be given a symbol 00477 argument prior to the argc and argv array information. 00478 */ 00479 void linklist_methodall(t_linklist *x, t_symbol *s, ...); 00480 00481 00482 /** 00483 Call the named message on an object specified by index. 00484 The item must be an object instance with a valid t_object header. 00485 00486 @ingroup linklist 00487 @param x The linklist instance. 00488 @param i The index of the item to which to send the message. 00489 @param s The name of the message to send to the objects. 00490 @param ... Any arguments to be sent with the message. 00491 00492 @remark Internally, this function uses object_method(), meaning that no errors will be 00493 posted if the message name does not exist for the object. It also means that 00494 messages sent methods with #A_GIMME definitions will need to be given a symbol 00495 argument prior to the argc and argv array information. 00496 */ 00497 void *linklist_methodindex(t_linklist *x, long i, t_symbol *s, ...); 00498 00499 00500 /** 00501 Sort the linked list. 00502 The items in the list are ordered using a #t_cmpfn function that is passed in as an argument. 00503 00504 @ingroup linklist 00505 @param x The linklist instance. 00506 @param cmpfn The function used to sort the list. 00507 00508 @remark The following is example is a real-world example of sorting a linklist of symbols alphabetically 00509 by first letter only. First the cmpfn is defined, then it is used in a different function 00510 by linklist_sort(). 00511 @code 00512 long myAlphabeticalCmpfn(void *a, void *b) 00513 { 00514 t_symbol *s1 = (t_symbol *)a; 00515 t_symbol *s2 = (t_symbol *)b; 00516 00517 if(s1->s_name[0] < s2->s_name[0]) 00518 return true; 00519 else 00520 return false; 00521 } 00522 00523 void mySortMethod(t_myobj *x) 00524 { 00525 // the linklist was already created and filled with items previously 00526 linklist_sort(x->myLinkList, myAlphabeticalCmpfn); 00527 } 00528 @endcode 00529 */ 00530 void linklist_sort(t_linklist *x, long cmpfn(void *, void *)); 00531 00532 00533 /** 00534 Call the specified function for every item in the linklist. 00535 00536 @ingroup linklist 00537 @param x The linklist instance. 00538 @param fun The function to call, specified as function pointer cast to a Max #method. 00539 @param arg An argument that you would like to pass to the function being called. 00540 00541 @remark The linklist_funall() method will call your function for every item in the list. 00542 It will pass both a pointer to the item in the list, and any argument that you 00543 provide. The following example shows a function that could be called by linklist_funall(). 00544 @code 00545 void myFun(t_object *myObj, void *myArg) 00546 { 00547 // do something with myObj and myArg here 00548 // myObj is the item in the linklist 00549 } 00550 @endcode 00551 */ 00552 void linklist_funall(t_linklist *x, method fun, void *arg); 00553 00554 00555 /** 00556 Call the specified function for every item in the linklist. 00557 The iteration through the list will halt if the function returns a non-zero value. 00558 00559 @ingroup linklist 00560 @param x The linklist instance. 00561 @param fun The function to call, specified as function pointer cast to a Max #method. 00562 @param arg An argument that you would like to pass to the function being called. 00563 00564 @remark The linklist_funall() method will call your function for every item in the list. 00565 It will pass both a pointer to the item in the list, and any argument that you 00566 provide. The following example shows a function that could be called by linklist_funall(). 00567 @code 00568 long myFun(t_symbol *myListItemSymbol, void *myArg) 00569 { 00570 // this function is called by a linklist that contains symbols for its items 00571 if(myListItemSymbol == gensym("")){ 00572 error("empty symbol -- aborting linklist traversal") 00573 return 1; 00574 } 00575 else{ 00576 // do something with the symbol 00577 return 0; 00578 } 00579 } 00580 @endcode 00581 */ 00582 long linklist_funall_break(t_linklist *x, method fun, void *arg); 00583 00584 00585 /** 00586 Call the specified function for an item specified by index. 00587 00588 @ingroup linklist 00589 @param x The linklist instance. 00590 @param i The index of the item to which to send the message. 00591 @param fun The function to call, specified as function pointer cast to a Max #method. 00592 @param arg An argument that you would like to pass to the function being called. 00593 00594 @remark The linklist_funindex() method will call your function for an item in the list. 00595 It will pass both a pointer to the item in the list, and any argument that you 00596 provide. The following example shows a function that could be called by linklist_funindex(). 00597 @code 00598 void myFun(t_object *myObj, void *myArg) 00599 { 00600 // do something with myObj and myArg here 00601 // myObj is the item in the linklist 00602 } 00603 @endcode 00604 */ 00605 void *linklist_funindex(t_linklist *x, long i, method fun, void *arg); 00606 00607 00608 /** 00609 Given an item in the list, replace it with a different value. 00610 00611 @ingroup linklist 00612 @param x The linklist instance. 00613 @param p An item in the list. 00614 @param newp The new value. 00615 @return Always returns NULL. 00616 */ 00617 void *linklist_substitute(t_linklist *x, void *p, void *newp); 00618 00619 00620 /** 00621 Given an item in the list, find the next item. 00622 This provides an means for walking the list. 00623 00624 @ingroup linklist 00625 @param x The linklist instance. 00626 @param p An item in the list. 00627 @param next The address of a pointer to set with the next item in the list. 00628 */ 00629 void *linklist_next(t_linklist *x, void *p, void **next); 00630 00631 00632 /** 00633 Given an item in the list, find the previous item. 00634 This provides an means for walking the list. 00635 00636 @ingroup linklist 00637 @param x The linklist instance. 00638 @param p An item in the list. 00639 @param prev The address of a pointer to set with the previous item in the list. 00640 */ 00641 void *linklist_prev(t_linklist *x, void *p, void **prev); 00642 00643 00644 /** 00645 Return the last item (the tail) in the linked-list. 00646 00647 @ingroup linklist 00648 @param x The linklist instance. 00649 @param item The address of pointer in which to store the last item in the linked-list. 00650 @return always returns NULL 00651 */ 00652 void *linklist_last(t_linklist *x, void **item); 00653 00654 00655 /** 00656 Set the linklist's readonly bit. 00657 00658 By default the readonly bit is 0, indicating that it is threadsafe for both reading and writing. 00659 Setting the readonly bit to 1 will disable the linklist's theadsafety mechanism, increasing 00660 performance but at the expense of threadsafe operation. 00661 Unless you can guarantee the threading context for a linklist's use, you should leave this set to 0. 00662 00663 @ingroup linklist 00664 @param x The linklist instance. 00665 @param readonly A 1 or 0 for setting the readonly bit. 00666 */ 00667 void linklist_readonly(t_linklist *x, long readonly); 00668 00669 00670 /** 00671 Set the linklist's datastore flags. The available flags are enumerated in #e_max_datastore_flags. 00672 These flags control the behavior of the linklist, particularly when removing items from the list 00673 using functions such as linklist_clear(), linklist_deleteindex(), or when freeing the linklist itself. 00674 00675 @ingroup linklist 00676 @param x The linklist instance. 00677 @param flags A valid value from the #e_max_datastore_flags. The default is #OBJ_FLAG_OBJ. 00678 */ 00679 void linklist_flags(t_linklist *x, long flags); 00680 00681 00682 /** 00683 Get the linklist's datastore flags. 00684 00685 @ingroup linklist 00686 @param x The linklist instance. 00687 @return The current state of the linklist flags as enumerated in #e_max_datastore_flags. 00688 */ 00689 long linklist_getflags(t_linklist *x); 00690 00691 00692 /** 00693 A linklist comparison method that determines if two item pointers are equal. 00694 00695 @ingroup linklist 00696 00697 @param a The first item to compare. 00698 @param b The second item to compare. 00699 @return Returns 1 if the items are equal, otherwise 0. 00700 00701 @see t_cmpfn 00702 */ 00703 long linklist_match(void *a, void *b); 00704 00705 00706 #ifdef __cplusplus 00707 } 00708 #endif // __cplusplus 00709 00710 #endif // _LINKLIST_H_ 00711
Copyright © 2008, Cycling '74