github.com/256dpi/max-go@v0.7.0/lib/max/ext_linklist.h (about)

     1  #ifndef _EXT_LINKLIST_H_
     2  #define _EXT_LINKLIST_H_
     3  
     4  #include "ext_prefix.h"
     5  #include "ext_atomic.h"
     6  #include "ext_mess.h"
     7  
     8  #if C74_PRAGMA_STRUCT_PACKPUSH
     9      #pragma pack(push, 2)
    10  #elif C74_PRAGMA_STRUCT_PACK
    11      #pragma pack(2)
    12  #endif
    13  
    14  /** A linklist element. This struct is provided for debugging convenience, 
    15  	but should be considered opaque and is subject to change without notice. 
    16  
    17  	@ingroup linklist
    18  	@see t_linklist
    19  */
    20  typedef struct _llelem
    21  {
    22  	t_object 		*thing;
    23  	struct _llelem	*next;
    24  	struct _llelem	*prev;
    25  	long flags;
    26  	long marked;
    27  } t_llelem;		
    28  
    29  
    30  /** The linklist object. This struct is provided for debugging convenience, 
    31  	but should be considered opaque and is subject to change without notice.
    32  	
    33  	@ingroup linklist
    34  	@see t_llelem
    35  */
    36  typedef struct _linklist
    37  {
    38  	t_object 	ob;
    39  	long		count;
    40  	t_llelem	*head;
    41  	t_llelem	*tail;
    42  	long		readonly;
    43  	void 		*lock;
    44  	t_llelem	*cache;			
    45  	long		flags;
    46  	t_llelem	*pending;		// used to help prevent accessing deleted elements during complex list traversal (methodall, etc) 
    47  	t_uint32_atomic iterating;
    48  	long		sweep;
    49  	long		locktype;
    50  } t_linklist;
    51  
    52  #if C74_PRAGMA_STRUCT_PACKPUSH
    53      #pragma pack(pop)
    54  #elif C74_PRAGMA_STRUCT_PACK
    55      #pragma pack()
    56  #endif
    57  
    58  enum {
    59  	LINKLIST_PRUNE_CHUCK = 0x00000001L	// chucks object rather than deletes it in linklist_prune
    60  };
    61  
    62  /**
    63  	Comparison function pointer type.
    64  	
    65  	Methods that require a comparison function pointer to be passed in use this type.
    66  	It should return <code>true</code> or <code>false</code> depending on the outcome of the 
    67  	comparison of the two linklist items passed in as arguments.
    68  	
    69  	@ingroup datastore
    70  	@see linklist_match()
    71  	@see hashtab_findfirst()
    72  	@see indexmap_sort()
    73  */
    74  typedef long (*t_cmpfn)(void *, void *);
    75  
    76  BEGIN_USING_C_LINKAGE
    77  
    78  /**
    79  	Create a new linklist object.
    80  	You can free the linklist by calling object_free() on the linklist's pointer,
    81  	or by using linklist_chuck().
    82  	
    83  	@ingroup linklist
    84  	@return  Pointer to the new linklist object.
    85  	
    86  	@see				object_free()
    87  	@see				linklist_chuck()
    88  */
    89  t_linklist *linklist_new(void);
    90  
    91  
    92  /** 
    93  	Free a linklist, but don't free the items it contains.
    94  	
    95  	The linklist can contain a variety of different types of data.
    96  	By default, the linklist assumes that all items are max objects with a valid
    97  	#t_object header.
    98  	
    99  	You can alter the linklist's notion of what it contains by using the 
   100  	linklist_flags() method.
   101  	
   102  	When you free the linklist by calling object_free() it then tries to free all of the items it contains.  
   103  	If the linklist is storing a custom type of data, or should otherwise not free the data it contains,
   104  	then call linklist_chuck() to free the object instead of object_free().
   105  	
   106  	@ingroup linklist
   107  	@param	x	The linklist object to be freed.
   108  	@see object_free
   109  */
   110  void linklist_chuck(t_linklist *x); 
   111  
   112  
   113  /**
   114  	Return the number of items in a linklist object.
   115  	
   116  	@ingroup linklist
   117  	
   118  	@param	x	The linklist instance.
   119  	@return		The number of items in the linklist object.
   120  */
   121  t_atom_long linklist_getsize(t_linklist *x);
   122  
   123  
   124  /**
   125  	Return the item stored in a linklist at a specified index.
   126  	
   127  	@ingroup linklist
   128  	
   129  	@param	x		The linklist instance.
   130  	@param	index	The index in the linklist to fetch.  Indices are zero-based.
   131  	@return			The item from the linklist stored at index.  
   132  					If there is no item at the index, <code>NULL</code> is returned
   133  */
   134  void *linklist_getindex(t_linklist *x, long index);
   135  
   136  
   137  // private
   138  t_llelem *linklist_index2ptr(t_linklist *x, long index);
   139  
   140  
   141  // private
   142  long linklist_ptr2index(t_linklist *x, t_llelem *p);
   143  
   144  
   145  /**
   146  	Return an item's index, given the item itself.
   147  	
   148  	@ingroup linklist
   149  	
   150  	@param	x		The linklist instance.
   151  	@param	p		The item pointer to search for in the linklist.
   152  	@return			The index of the item given in the linklist.  
   153  					If the item is not in the linklist #MAX_ERR_GENERIC is returned.
   154  */
   155  t_atom_long linklist_objptr2index(t_linklist *x, void *p);
   156  
   157  
   158  /**
   159  	Add an item to the end of the list.
   160  	
   161  	@ingroup linklist
   162  	
   163  	@param	x		The linklist instance.
   164  	@param	o		The item pointer to append to the linked-list.
   165  	@return			The updated size of the linklist after appending the new item, or -1 if the append failed.
   166  */
   167  t_atom_long linklist_append(t_linklist *x, void *o);
   168  
   169  
   170  /**	Insert an item into the list at the specified index.
   171  	@ingroup linklist
   172  	@param	x		The linklist instance.
   173  	@param	o		The item pointer to insert.
   174  	@param	index	The index at which to insert.  Index 0 is the head of the list.
   175  	@return			The index of the item in the linklist, or -1 if the insert failed.
   176  */
   177  t_atom_long linklist_insertindex(t_linklist *x,  void *o, long index);
   178  
   179  
   180  /**	Insert an item into the list, keeping the list sorted according to a specified comparison function.
   181  	@ingroup		linklist
   182  	@param	x		The linklist instance.
   183  	@param	o		The item pointer to insert.
   184  	@param	cmpfn	A comparison function by which the list should be sorted.
   185  	@return			The index of the new item in the linklist, or -1 if the insert failed.
   186  */
   187  long linklist_insert_sorted(t_linklist *x, void *o, long cmpfn(void *, void *));
   188  
   189  
   190  /**
   191  	Insert an item into the list after another specified item.
   192  	
   193  	@ingroup linklist
   194  	
   195  	@param	x		The linklist instance.
   196  	@param	o		The item pointer to insert.
   197  	@param	objptr	The item pointer after which to insert in the list.
   198  	
   199  	@return			An opaque linklist element.
   200  */
   201  t_llelem *linklist_insertafterobjptr(t_linklist *x, void *o, void *objptr);	// inserts object o after objptr
   202  
   203  
   204  /**
   205  	Insert an item into the list before another specified item.
   206  	
   207  	@ingroup linklist
   208  	
   209  	@param	x		The linklist instance.
   210  	@param	o		The item pointer to insert.
   211  	@param	objptr	The item pointer before which to insert in the list.
   212  	
   213  	@return			An opaque linklist element.
   214  */
   215  t_llelem *linklist_insertbeforeobjptr(t_linklist *x, void *o, void *objptr); // inserts object o before objptr
   216  
   217  
   218  /**
   219  	Move an existing item in the list to a position after another specified item in the list.
   220  	
   221  	@ingroup linklist
   222  	
   223  	@param	x		The linklist instance.
   224  	@param	o		The item pointer to insert.
   225  	@param	objptr	The item pointer after which to move o in the list.
   226  	
   227  	@return			An opaque linklist element.
   228  */
   229  t_llelem *linklist_moveafterobjptr(t_linklist *x, void *o, void *objptr);    // move existing object o after objptr
   230  
   231  
   232  /**
   233  	Move an existing item in the list to a position before another specified item in the list.
   234  	
   235  	@ingroup linklist
   236  	
   237  	@param	x		The linklist instance.
   238  	@param	o		The item pointer to insert.
   239  	@param	objptr	The item pointer before which to move o in the list.
   240  	
   241  	@return			An opaque linklist element.
   242  */
   243  t_llelem *linklist_movebeforeobjptr(t_linklist *x, void *o, void *objptr);   // move existing object o before objptr
   244  
   245  
   246  // private
   247  t_llelem *linklist_insertptr(t_linklist *x,  void *o, t_llelem *p); //inserts before ptr
   248  
   249  
   250  /**
   251  	Remove the item from the list at the specified index and free it.
   252  	
   253  	The linklist can contain a variety of different types of data.
   254  	By default, the linklist assumes that all items are max objects with a valid
   255  	#t_object header.  Thus by default, it frees items by calling object_free() on them.
   256  
   257  	You can alter the linklist's notion of what it contains by using the 
   258  	linklist_flags() method.
   259  
   260  	If you wish to remove an item from the linklist and free it yourself, then you
   261  	should use linklist_chuckptr().
   262  	
   263  	@ingroup linklist
   264  	
   265  	@param	x		The linklist instance.
   266  	@param	index	The index of the item to delete.
   267  	@return			Returns the index number of the item delted, or -1 if the operation failed.
   268  	
   269  	@see			linklist_chuckindex
   270  	@see			linklist_chuckobject
   271  */
   272  t_atom_long linklist_deleteindex(t_linklist *x, long index); 
   273  
   274  
   275  /**
   276  	Remove the item from the list at the specified index.
   277  	
   278  	You are responsible for freeing any memory associated with the item that is
   279  	removed from the linklist.
   280  	
   281  	@ingroup linklist
   282  	
   283  	@param	x		The linklist instance.
   284  	@param	index	The index of the item to remove.
   285  	@return			Returns #MAX_ERR_NONE on successful removal, otherwise returns #MAX_ERR_GENERIC
   286  	
   287  	@see			linklist_deleteindex
   288  	@see			linklist_chuckobject
   289  */
   290  long linklist_chuckindex(t_linklist *x, long index);
   291  
   292  
   293  /**
   294  	Remove the specified item from the list.
   295  	
   296  	You are responsible for freeing any memory associated with the item that is
   297  	removed from the linklist.
   298  	
   299  	@ingroup linklist
   300  	
   301  	@param	x		The linklist instance.
   302  	@param	o		The pointer to the item to remove.
   303  	
   304  	@see			linklist_deleteindex
   305  	@see			linklist_chuckindex
   306  	@see			linklist_deleteobject
   307  */
   308  long linklist_chuckobject(t_linklist *x, void *o);
   309  
   310  
   311  /**
   312  	Delete the specified item from the list.
   313  
   314  	The object is removed from the list and deleted.
   315  	The deletion is done with respect to any flags passed to linklist_flags.
   316  		
   317  	@ingroup linklist
   318  	
   319  	@param	x		The linklist instance.
   320  	@param	o		The pointer to the item to delete.
   321  	
   322  	@see			linklist_deleteindex
   323  	@see			linklist_chuckindex
   324  	@see			linklist_chuckobject
   325  */
   326  long linklist_deleteobject(t_linklist *x, void *o);
   327  
   328  // private
   329  long linklist_deleteptr(t_linklist *x, t_llelem *p);
   330  
   331  
   332  // private
   333  long linklist_chuckptr(t_linklist *x, t_llelem *p); //like delete, but don't free it
   334  
   335  
   336  /**
   337  	Remove and free all items in the list.
   338  	
   339  	Freeing items in the list is subject to the same rules as linklist_deleteindex().
   340  	You can alter the linklist's notion of what it contains, and thus how items are freed,
   341  	by using the linklist_flags() method.	
   342  
   343  	@ingroup	linklist	
   344  	@param		x			The linklist instance.
   345  */
   346  void linklist_clear(t_linklist *x);
   347  
   348  
   349  // private
   350  long linklist_insertnodeindex(t_linklist *x, t_llelem *p, long index);
   351  
   352  // private
   353  t_llelem *linklist_insertnodeptr(t_linklist *x, t_llelem *p1, t_llelem *p2);
   354  
   355  // private
   356  long linklist_appendnode(t_linklist *x, t_llelem *p);
   357  
   358  // private
   359  t_llelem *linklistelem_new(void);
   360  
   361  // private
   362  void linklistelem_free(t_linklist *x, t_llelem *elem);
   363  
   364  
   365  /**
   366  	Retrieve linklist items as an array of pointers.
   367  	
   368  	@ingroup linklist
   369  	
   370  	@param	x		The linklist instance.
   371  	@param	a		The address of the first pointer in the array to fill.
   372  	@param	max		The number of pointers in the array.
   373  	@return			The number of items from the list actually returned in the array.
   374  */
   375  t_atom_long linklist_makearray(t_linklist *x, void **a, long max);
   376  
   377  
   378  /**
   379  	Reverse the order of items in the linked-list.
   380  
   381  	@ingroup linklist	
   382  	@param	x	The linklist instance.
   383  */
   384  void linklist_reverse(t_linklist *x);
   385  
   386  
   387  /**
   388  	Rotate items in the linked list in circular fashion.
   389  
   390  	@ingroup linklist	
   391  	@param	x	The linklist instance.
   392  	@param	i	The number of positions in the list to shift items.
   393  */
   394  void linklist_rotate(t_linklist *x, long i);
   395  
   396  
   397  /**
   398  	Randomize the order of items in the linked-list.
   399  
   400  	@ingroup linklist	
   401  	@param	x	The linklist instance.
   402  */
   403  void linklist_shuffle(t_linklist *x);
   404  
   405  
   406  /**
   407  	Swap the position of two items in the linked-list, specified by index.
   408  
   409  	@ingroup linklist	
   410  	@param	x	The linklist instance.
   411  	@param	a	The index of the first item to swap.
   412  	@param	b	The index of the second item to swap.
   413  */
   414  void linklist_swap(t_linklist *x, long a, long b);
   415  
   416  
   417  /**
   418  	Search the linked list for the first item meeting defined criteria.
   419  	The items in the list are traversed, calling a specified comparison function on each
   420  	until the comparison function returns true.  
   421  
   422  	@ingroup linklist	
   423  	@param	x		The linklist instance.
   424  	@param	o		The address to pointer that will be set with the matching item.
   425  	@param	cmpfn	The function used to determine a match in the list.
   426  	@param	cmpdata	An argument to be passed to the #t_cmpfn.  
   427  					This will be passed as the second of the two args to the #t_cmpfn.  
   428  					The first arg will be the linklist item at each iteration in the list.
   429  	@return			The index of the matching item, or -1 if no match is found.
   430  	
   431  	@remark		The following shows how to manually do what linklist_chuckobject() does.  
   432  	@code
   433  	void *obj;
   434  	long index;
   435  	
   436  	index = linklist_findfirst(x, &obj, #linklist_match, o);
   437  	if(index != -1)
   438  		linklist_chuckindex(x, index);
   439  	@endcode
   440  	
   441  	@see linklist_match
   442  	@see t_cmpfn
   443  	@see linklist_findall
   444  */
   445  t_atom_long linklist_findfirst(t_linklist *x, void **o, long cmpfn(void *, void *), void *cmpdata);
   446  
   447  
   448  /**
   449  	Search the linked list for all items meeting defined criteria.
   450  	The items in the list are traversed, calling a specified comparison function on each,
   451  	and returning the matches in another linklist.
   452  
   453  	@ingroup linklist	
   454  	@param	x		The linklist instance.
   455  	@param	out		The address to a #t_linklist pointer.  
   456  					You should initialize the pointer to NULL before calling linklist_findall(). 
   457  					A new linklist will be created internally by linklist_findall() and returned here.
   458  	@param	cmpfn	The function used to determine a match in the list.
   459  	@param	cmpdata	An argument to be passed to the #t_cmpfn.  
   460  					This will be passed as the second of the two args to the #t_cmpfn.  
   461  					The first arg will be the linklist item at each iteration in the list.
   462  	
   463  	@remark		The following example assumes you have a linklist called myLinkList, and #t_cmpfn called 
   464  	  			myCmpFunction, and some sort of data to match in someCriteria.
   465  	@code
   466  	t_linklist *results = NULL;
   467  	
   468  	linklist_findall(myLinkList, &results, myCmpFunction, (void *)someCriteria);
   469  	// do something here with the 'results' linklist
   470  	// then free the results linklist
   471  	linklist_chuck(results);
   472  	@endcode
   473  	
   474  	@see	linklist_match
   475  	@see	t_cmpfn
   476  	@see	linklist_findfirst
   477  */
   478  void linklist_findall(t_linklist *x, t_linklist **out, long cmpfn(void *, void *), void *cmpdata);
   479  
   480  
   481  /**
   482  	Call the named message on every object in the linklist.  
   483  	The linklist_methodall() function requires that all items in the linklist are
   484  	object instances with a valid t_object header.
   485  
   486  	@ingroup linklist	
   487  	@param	x	The linklist instance.
   488  	@param	s	The name of the message to send to the objects.
   489  	@param	...	Any arguments to be sent with the message.
   490  	
   491  	@remark		Internally, this function uses object_method(), meaning that no errors will be
   492  				posted if the message name does not exist for the object.  It also means that
   493  				messages sent methods with #A_GIMME definitions will need to be given a symbol 
   494  				argument prior to the argc and argv array information.
   495  */
   496  void linklist_methodall(t_linklist *x, t_symbol *s, ...);
   497  
   498  #ifdef C74_X64
   499  #define linklist_methodall(...) C74_VARFUN(linklist_methodall_imp, __VA_ARGS__)
   500  #endif
   501          
   502  void linklist_methodall_imp(void *x, void *sym, void *p1, void *p2, void *p3, void *p4, void *p5, void *p6, void *p7, void *p8);
   503  
   504  
   505  /**
   506  	Call the named message on an object specified by index.  
   507  	The item must be an object instance with a valid t_object header.
   508  
   509  	@ingroup linklist	
   510  	@param	x	The linklist instance.
   511  	@param	i	The index of the item to which to send the message.
   512  	@param	s	The name of the message to send to the objects.
   513  	@param	...	Any arguments to be sent with the message.
   514  	
   515  	@remark		Internally, this function uses object_method(), meaning that no errors will be
   516  				posted if the message name does not exist for the object.  It also means that
   517  				messages sent methods with #A_GIMME definitions will need to be given a symbol 
   518  				argument prior to the argc and argv array information.
   519  */
   520  void *linklist_methodindex(t_linklist *x, t_atom_long i, t_symbol *s, ...);
   521  
   522  #ifdef C74_X64
   523  #define linklist_methodindex(...) C74_VARFUN(linklist_methodindex_imp, __VA_ARGS__)
   524  #endif
   525  
   526  void *linklist_methodindex_imp(void *x, void *i, void *s, void *p1, void *p2, void *p3, void *p4, void *p5, void *p6, void *p7); // 10 arg varfun, so we lose an arg
   527  
   528  
   529  /**
   530  	Sort the linked list.  
   531  	The items in the list are ordered using a #t_cmpfn function that is passed in as an argument.
   532  
   533  	@ingroup linklist	
   534  	@param	x		The linklist instance.
   535  	@param	cmpfn	The function used to sort the list.
   536  	
   537  	@remark		The following is example is a real-world example of sorting a linklist of symbols alphabetically
   538  				by first letter only.  First the cmpfn is defined, then it is used in a different function
   539  				by linklist_sort().
   540  	@code
   541  	long myAlphabeticalCmpfn(void *a, void *b)
   542  	{
   543  		t_symbol *s1 = (t_symbol *)a;
   544  		t_symbol *s2 = (t_symbol *)b;
   545  
   546  		if(s1->s_name[0] < s2->s_name[0])
   547  			return true;
   548  		else
   549  			return false;
   550  	}
   551  	
   552  	void mySortMethod(t_myobj *x)
   553  	{
   554  		// the linklist was already created and filled with items previously 
   555  		linklist_sort(x->myLinkList, myAlphabeticalCmpfn);
   556  	}
   557  	@endcode
   558  */
   559  void linklist_sort(t_linklist *x, long cmpfn(void *, void *));
   560  
   561  
   562  /**
   563  	Call the specified function for every item in the linklist.  
   564  
   565  	@ingroup linklist	
   566  	@param	x		The linklist instance.
   567  	@param	fun		The function to call, specified as function pointer cast to a Max #method.
   568  	@param	arg		An argument that you would like to pass to the function being called.
   569  	
   570  	@remark			The linklist_funall() method will call your function for every item in the list.
   571  					It will pass both a pointer to the item in the list, and any argument that you
   572  					provide.  The following example shows a function that could be called by linklist_funall().
   573  	@code
   574  	void myFun(t_object *myObj, void *myArg)
   575  	{
   576  		// do something with myObj and myArg here
   577  		// myObj is the item in the linklist
   578  	}
   579  	@endcode
   580  */
   581  void linklist_funall(t_linklist *x, method fun, void *arg);
   582  
   583  
   584  /**
   585  	Call the specified function for every item in the linklist.  
   586  	The iteration through the list will halt if the function returns a non-zero value.
   587  
   588  	@ingroup linklist	
   589  	@param	x		The linklist instance.
   590  	@param	fun		The function to call, specified as function pointer cast to a Max #method.
   591  	@param	arg		An argument that you would like to pass to the function being called.
   592  	
   593  	@remark			The linklist_funall() method will call your function for every item in the list.
   594  					It will pass both a pointer to the item in the list, and any argument that you
   595  					provide.  The following example shows a function that could be called by linklist_funall().
   596  	@code
   597  	long myFun(t_symbol *myListItemSymbol, void *myArg)
   598  	{
   599  		// this function is called by a linklist that contains symbols for its items
   600  		if(myListItemSymbol == gensym("")){
   601  			error("empty symbol -- aborting linklist traversal")
   602  			return 1;			
   603  		}
   604  		else{
   605  			// do something with the symbol
   606  			return 0;
   607  		}
   608  	}
   609  	@endcode
   610  */
   611  t_atom_long linklist_funall_break(t_linklist *x, method fun, void *arg);
   612  
   613  
   614  /**
   615  	Call the specified function for an item specified by index.  
   616  
   617  	@ingroup linklist	
   618  	@param	x		The linklist instance.
   619  	@param	i		The index of the item to which to send the message.
   620  	@param	fun		The function to call, specified as function pointer cast to a Max #method.
   621  	@param	arg		An argument that you would like to pass to the function being called.
   622  	
   623  	@remark			The linklist_funindex() method will call your function for an item in the list.
   624  					It will pass both a pointer to the item in the list, and any argument that you
   625  					provide.  The following example shows a function that could be called by linklist_funindex().
   626  	@code
   627  	void myFun(t_object *myObj, void *myArg)
   628  	{
   629  		// do something with myObj and myArg here
   630  		// myObj is the item in the linklist
   631  	}
   632  	@endcode
   633  */
   634  void *linklist_funindex(t_linklist *x, long i, method fun, void *arg);
   635  
   636  
   637  /**
   638  	Given an item in the list, replace it with a different value.
   639  
   640  	@ingroup linklist	
   641  	@param	x		The linklist instance.
   642  	@param	p		An item in the list.
   643  	@param	newp	The new value.
   644  	@return			Always returns NULL.
   645  */
   646  void *linklist_substitute(t_linklist *x, void *p, void *newp);
   647  
   648  
   649  /**
   650  	Given an item in the list, find the next item.
   651  	This provides an means for walking the list.
   652  
   653  	@ingroup linklist	
   654  	@param	x		The linklist instance.
   655  	@param	p		An item in the list.
   656  	@param	next	The address of a pointer to set with the next item in the list.
   657  */
   658  void *linklist_next(t_linklist *x, void *p, void **next);
   659  
   660  
   661  /**
   662  	Given an item in the list, find the previous item.
   663  	This provides an means for walking the list.
   664  
   665  	@ingroup linklist	
   666  	@param	x		The linklist instance.
   667  	@param	p		An item in the list.
   668  	@param	prev	The address of a pointer to set with the previous item in the list.
   669  */
   670  void *linklist_prev(t_linklist *x, void *p, void **prev);
   671  
   672  
   673  /**
   674  	Return the last item (the tail) in the linked-list.
   675  	
   676  	@ingroup linklist
   677  	@param	x		The linklist instance.
   678  	@param	item	The address of pointer in which to store the last item in the linked-list.
   679  	@return 		always returns NULL
   680  */
   681  void *linklist_last(t_linklist *x, void **item);
   682  
   683  
   684  /**
   685  	Set the linklist's readonly bit.
   686  	
   687  	By default the readonly bit is 0, indicating that it is threadsafe for both reading and writing.
   688  	Setting the readonly bit to 1 will disable the linklist's theadsafety mechanism, increasing 
   689  	performance but at the expense of threadsafe operation.  
   690  	Unless you can guarantee the threading context for a linklist's use, you should leave this set to 0.
   691  	
   692  	@ingroup linklist
   693  	@param	x			The linklist instance.
   694  	@param	readonly	A 1 or 0 for setting the readonly bit.
   695  */
   696  void linklist_readonly(t_linklist *x, long readonly);
   697  
   698  
   699  /**
   700  	Set the linklist's datastore flags.  The available flags are enumerated in #e_max_datastore_flags.
   701  	These flags control the behavior of the linklist, particularly when removing items from the list
   702  	using functions such as linklist_clear(), linklist_deleteindex(), or when freeing the linklist itself.
   703  	
   704  	@ingroup linklist
   705  	@param	x			The linklist instance.
   706  	@param	flags	A valid value from the #e_max_datastore_flags.  The default is #OBJ_FLAG_OBJ.
   707  */
   708  void linklist_flags(t_linklist *x, long flags);
   709  
   710  
   711  /**
   712  	Get the linklist's datastore flags.
   713  		
   714  	@ingroup linklist
   715  	@param	x	The linklist instance.
   716  	@return		The current state of the linklist flags as enumerated in #e_max_datastore_flags.
   717  */
   718  t_atom_long linklist_getflags(t_linklist *x);
   719  
   720  
   721  /**
   722  	A linklist comparison method that determines if two item pointers are equal.
   723  	
   724  	@ingroup linklist
   725  	
   726  	@param	a		The first item to compare.
   727  	@param	b		The second item to compare.
   728  	@return			Returns 1 if the items are equal, otherwise 0.
   729  	
   730  	@see			t_cmpfn	
   731  */
   732  long linklist_match(void *a, void *b);
   733  
   734  
   735  END_USING_C_LINKAGE
   736  
   737  #endif // _EXT_LINKLIST_H_
   738