2 * Copyright (c) 2007,2008 Mij <mij@bitchx.it>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 * SimCList library. See http://mij.oltrelinux.com/devel/simclist
32 #include <sys/types.h>
34 #ifndef SIMCLIST_NO_DUMPRESTORE
36 # include <sys/time.h> /* list_dump_info_t's struct timeval */
43 /* Be friend of both C90 and C99 compilers */
44 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
45 /* "inline" and "restrict" are keywords */
47 # define inline /* inline */
48 # define restrict /* restrict */
53 * Type representing list hashes.
55 * This is a signed integer value.
57 typedef int32_t list_hash_t;
59 #ifndef SIMCLIST_NO_DUMPRESTORE
61 uint16_t version; /* dump version */
62 struct timeval timestamp; /* when the list has been dumped, seconds since UNIX epoch */
65 list_hash_t list_hash; /* hash of the list when dumped, or 0 if invalid */
67 int consistent; /* 1 if the dump is verified complete/consistent; 0 otherwise */
72 * a comparator of elements.
74 * A comparator of elements is a function that:
75 * -# receives two references to elements a and b
76 * -# returns {<0, 0, >0} if (a > b), (a == b), (a < b) respectively
78 * It is responsability of the function to handle possible NULL values.
80 typedef int (*element_comparator)(const void *a, const void *b);
83 * a seeker of elements.
85 * An element seeker is a function that:
86 * -# receives a reference to an element el
87 * -# receives a reference to some indicator data
88 * -# returns non-0 if the element matches the indicator, 0 otherwise
90 * It is responsability of the function to handle possible NULL values in any
93 typedef int (*element_seeker)(const void *el, const void *indicator);
96 * an element lenght meter.
98 * An element meter is a function that:
99 * -# receives the reference to an element el
100 * -# returns its size in bytes
102 * It is responsability of the function to handle possible NULL values.
104 typedef size_t (*element_meter)(const void *el);
107 * a function computing the hash of elements.
109 * An hash computing function is a function that:
110 * -# receives the reference to an element el
111 * -# returns a hash value for el
113 * It is responsability of the function to handle possible NULL values.
115 typedef list_hash_t (*element_hash_computer)(const void *el);
118 * a function for serializing an element.
120 * A serializer function is one that gets a reference to an element,
121 * and returns a reference to a buffer that contains its serialization
122 * along with the length of this buffer.
123 * It is responsability of the function to handle possible NULL values,
124 * returning a NULL buffer and a 0 buffer length.
126 * These functions have 3 goals:
127 * -# "freeze" and "flatten" the memory representation of the element
128 * -# provide a portable (wrt byte order, or type size) representation of the element, if the dump can be used on different sw/hw combinations
129 * -# possibly extract a compressed representation of the element
131 * @param el reference to the element data
132 * @param serialize_buffer reference to fill with the length of the buffer
133 * @return reference to the buffer with the serialized data
135 typedef void *(*element_serializer)(const void *restrict el, uint32_t *restrict serializ_len);
138 * a function for un-serializing an element.
140 * An unserializer function accomplishes the inverse operation of the
141 * serializer function. An unserializer function is one that gets a
142 * serialized representation of an element and turns it backe to the original
143 * element. The serialized representation is passed as a reference to a buffer
144 * with its data, and the function allocates and returns the buffer containing
145 * the original element, and it sets the length of this buffer into the
146 * integer passed by reference.
148 * @param data reference to the buffer with the serialized representation of the element
149 * @param data_len reference to the location where to store the length of the data in the buffer returned
150 * @return reference to a buffer with the original, unserialized representation of the element
152 typedef void *(*element_unserializer)(const void *restrict data, uint32_t *restrict data_len);
154 /* [private-use] list entry -- olds actual user datum */
155 struct list_entry_s {
158 /* doubly-linked list service references */
159 struct list_entry_s *next;
160 struct list_entry_s *prev;
163 /* [private-use] list attributes */
164 struct list_attributes_s {
165 /* user-set routine for comparing list elements */
166 element_comparator comparator;
167 /* user-set routing for seeking elements */
168 element_seeker seeker;
169 /* user-set routine for determining the length of an element */
172 /* user-set routine for computing the hash of an element */
173 element_hash_computer hasher;
174 /* user-set routine for serializing an element */
175 element_serializer serializer;
176 /* user-set routine for unserializing an element */
177 element_unserializer unserializer;
182 struct list_entry_s *head_sentinel;
183 struct list_entry_s *tail_sentinel;
184 struct list_entry_s *mid;
188 /* array of spare elements */
189 struct list_entry_s **spareels;
190 unsigned int spareelsnum;
192 #ifdef SIMCLIST_WITH_THREADS
193 /* how many threads are currently running */
194 unsigned int threadcount;
197 /* service variables for list iteration */
199 unsigned int iter_pos;
200 struct list_entry_s *iter_curentry;
202 /* list attributes */
203 struct list_attributes_s attrs;
207 * initialize a list object for use.
209 * @param l must point to a user-provided memory location
210 * @return 0 for success. -1 for failure
212 int list_init(list_t *restrict l);
215 * completely remove the list from memory.
217 * This function is the inverse of list_init(). It is meant to be called when
218 * the list is no longer going to be used. Elements and possible memory taken
219 * for internal use are freed.
221 * @param l list to destroy
223 void list_destroy(list_t *restrict l);
226 * set the comparator function for list elements.
228 * Comparator functions are used for searching and sorting. If NULL is passed
229 * as reference to the function, the comparator is disabled.
231 * @param l list to operate
232 * @param comparator_fun pointer to the actual comparator function
233 * @return 0 if the attribute was successfully set; -1 otherwise
235 * @see element_comparator()
237 int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun);
240 * set a seeker function for list elements.
242 * Seeker functions are used for finding elements. If NULL is passed as reference
243 * to the function, the seeker is disabled.
245 * @param l list to operate
246 * @param seeker_fun pointer to the actual seeker function
247 * @return 0 if the attribute was successfully set; -1 otherwise
249 * @see element_seeker()
251 int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun);
254 * require to free element data when list entry is removed (default: don't free).
256 * [ advanced preference ]
258 * By default, when an element is removed from the list, it disappears from
259 * the list by its actual data is not free()d. With this option, every
260 * deletion causes element data to be freed.
262 * It is responsability of this function to correctly handle NULL values, if
263 * NULL elements are inserted into the list.
265 * @param l list to operate
266 * @param metric_fun pointer to the actual metric function
267 * @param copy_data 0: do not free element data (default); non-0: do free
268 * @return 0 if the attribute was successfully set; -1 otherwise
270 * @see element_meter()
271 * @see list_meter_int8_t()
272 * @see list_meter_int16_t()
273 * @see list_meter_int32_t()
274 * @see list_meter_int64_t()
275 * @see list_meter_uint8_t()
276 * @see list_meter_uint16_t()
277 * @see list_meter_uint32_t()
278 * @see list_meter_uint64_t()
279 * @see list_meter_float()
280 * @see list_meter_double()
281 * @see list_meter_string()
283 int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data);
286 * set the element hash computing function for the list elements.
288 * [ advanced preference ]
290 * An hash can be requested depicting the list status at a given time. An hash
291 * only depends on the elements and their order. By default, the hash of an
292 * element is only computed on its reference. With this function, the user can
293 * set a custom function computing the hash of an element. If such function is
294 * provided, the list_hash() function automatically computes the list hash using
295 * the custom function instead of simply referring to element references.
297 * @param l list to operate
298 * @param hash_computer_fun pointer to the actual hash computing function
299 * @return 0 if the attribute was successfully set; -1 otherwise
301 * @see element_hash_computer()
303 int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun);
306 * set the element serializer function for the list elements.
308 * [ advanced preference ]
310 * Serialize functions are used for dumping the list to some persistent
311 * storage. The serializer function is called for each element; it is passed
312 * a reference to the element and a reference to a size_t object. It will
313 * provide (and return) the buffer with the serialization of the element and
314 * fill the size_t object with the length of this serialization data.
316 * @param l list to operate
317 * @param serializer_fun pointer to the actual serializer function
318 * @return 0 if the attribute was successfully set; -1 otherwise
320 * @see element_serializer()
321 * @see list_dump_filedescriptor()
322 * @see list_restore_filedescriptor()
324 int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun);
327 * set the element unserializer function for the list elements.
329 * [ advanced preference ]
331 * Unserialize functions are used for restoring the list from some persistent
332 * storage. The unserializer function is called for each element segment read
333 * from the storage; it is passed the segment and a reference to an integer.
334 * It shall allocate and return a buffer compiled with the resumed memory
335 * representation of the element, and set the integer value to the length of
338 * @param l list to operate
339 * @param unserializer_fun pointer to the actual unserializer function
340 * @return 0 if the attribute was successfully set; -1 otherwise
342 * @see element_unserializer()
343 * @see list_dump_filedescriptor()
344 * @see list_restore_filedescriptor()
346 int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun);
349 * append data at the end of the list.
351 * This function is useful for adding elements with a FIFO/queue policy.
353 * @param l list to operate
354 * @param data pointer to user data to append
356 * @return 1 for success. < 0 for failure
358 int list_append(list_t *restrict l, const void *data);
361 * insert data in the head of the list.
363 * This function is useful for adding elements with a LIFO/Stack policy.
365 * @param l list to operate
366 * @param data pointer to user data to append
368 * @return 1 for success. < 0 for failure
370 int list_prepend(list_t *restrict l, const void *restrict data);
373 * extract the element in the top of the list.
375 * This function is for using a list with a FIFO/queue policy.
377 * @param l list to operate
378 * @return reference to user datum, or NULL on errors
380 void *list_fetch(list_t *restrict l);
383 * retrieve an element at a given position.
385 * @param l list to operate
386 * @param pos [0,size-1] position index of the element wanted
387 * @return reference to user datum, or NULL on errors
389 void *list_get_at(const list_t *restrict l, unsigned int pos);
392 * return the maximum element of the list.
394 * @warning Requires a comparator function to be set for the list.
396 * Returns the maximum element with respect to the comparator function output.
398 * @see list_attributes_comparator()
400 * @param l list to operate
401 * @return the reference to the element, or NULL
403 void *list_get_max(const list_t *restrict l);
406 * return the minimum element of the list.
408 * @warning Requires a comparator function to be set for the list.
410 * Returns the minimum element with respect to the comparator function output.
412 * @see list_attributes_comparator()
414 * @param l list to operate
415 * @return the reference to the element, or NULL
417 void *list_get_min(const list_t *restrict l);
420 * retrieve and remove from list an element at a given position.
422 * @param l list to operate
423 * @param pos [0,size-1] position index of the element wanted
424 * @return reference to user datum, or NULL on errors
426 void *list_extract_at(list_t *restrict l, unsigned int pos);
429 * insert an element at a given position.
431 * @param l list to operate
432 * @param data reference to data to be inserted
433 * @param pos [0,size-1] position index to insert the element at
434 * @return positive value on success. Negative on failure
436 int list_insert_at(list_t *restrict l, const void *data, unsigned int pos);
439 * expunge the first found given element from the list.
441 * Inspects the given list looking for the given element; if the element
442 * is found, it is removed. Only the first occurence is removed.
443 * If a comparator function was not set, elements are compared by reference.
444 * Otherwise, the comparator is used to match the element.
446 * @param l list to operate
447 * @param data reference of the element to search for
448 * @return 0 on success. Negative value on failure
450 * @see list_attributes_comparator()
451 * @see list_delete_at()
453 int list_delete(list_t *restrict l, const void *data);
456 * expunge an element at a given position from the list.
458 * @param l list to operate
459 * @param pos [0,size-1] position index of the element to be deleted
460 * @return 0 on success. Negative value on failure
462 int list_delete_at(list_t *restrict l, unsigned int pos);
465 * expunge an array of elements from the list, given their position range.
467 * @param l list to operate
468 * @param posstart [0,size-1] position index of the first element to be deleted
469 * @param posend [posstart,size-1] position of the last element to be deleted
470 * @return the number of elements successfully removed on success, <0 on error
472 int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend);
475 * clear all the elements off of the list.
477 * The element datums will not be freed.
479 * @see list_delete_range()
482 * @param l list to operate
483 * @return the number of elements removed on success, <0 on error
485 int list_clear(list_t *restrict l);
488 * inspect the number of elements in the list.
490 * @param l list to operate
491 * @return number of elements currently held by the list
493 unsigned int list_size(const list_t *restrict l);
496 * inspect whether the list is empty.
498 * @param l list to operate
499 * @return 0 iff the list is not empty
503 int list_empty(const list_t *restrict l);
506 * find the position of an element in a list.
508 * @warning Requires a comparator function to be set for the list.
510 * Inspects the given list looking for the given element; if the element
511 * is found, its position into the list is returned.
512 * Elements are inspected comparing references if a comparator has not been
513 * set. Otherwise, the comparator is used to find the element.
515 * @param l list to operate
516 * @param data reference of the element to search for
517 * @return position of element in the list, or <0 if not found
519 * @see list_attributes_comparator()
522 int list_locate(const list_t *restrict l, const void *data);
525 * returns an element given an indicator.
527 * @warning Requires a seeker function to be set for the list.
529 * Inspect the given list looking with the seeker if an element matches
530 * an indicator. If such element is found, the reference to the element
533 * @param l list to operate
534 * @param indicator indicator data to pass to the seeker along with elements
535 * @return reference to the element accepted by the seeker, or NULL if none found
537 void *list_seek(list_t *restrict l, const void *indicator);
540 * inspect whether some data is member of the list.
542 * @warning Requires a comparator function to be set for the list.
544 * By default, a per-reference comparison is accomplished. That is,
545 * the data is in list if any element of the list points to the same
547 * A "semantic" comparison is accomplished, otherwise, if a comparator
548 * function has been set previously, with list_attributes_comparator();
549 * in which case, the given data reference is believed to be in list iff
550 * comparator_fun(elementdata, userdata) == 0 for any element in the list.
552 * @param l list to operate
553 * @param data reference to the data to search
554 * @return 0 iff the list does not contain data as an element
556 * @see list_attributes_comparator()
558 int list_contains(const list_t *restrict l, const void *data);
561 * concatenate two lists
563 * Concatenates one list with another, and stores the result into a
564 * user-provided list object, which must be different from both the
565 * lists to concatenate. Attributes from the original lists are not
567 * The destination list referred is threated as virgin room: if it
568 * is an existing list containing elements, memory leaks will happen.
569 * It is OK to specify the same list twice as source, for "doubling"
570 * it in the destination.
572 * @param l1 base list
573 * @param l2 list to append to the base
574 * @param dest reference to the destination list
575 * @return 0 for success, -1 for errors
577 int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest);
580 * sort list elements.
582 * @warning Requires a comparator function to be set for the list.
584 * Sorts the list in ascending or descending order as specified by the versus
585 * flag. The algorithm chooses autonomously what algorithm is best suited for
586 * sorting the list wrt its current status.
588 * @param l list to operate
589 * @param versus positive: order small to big; negative: order big to small
590 * @return 0 iff sorting was successful
592 * @see list_attributes_comparator()
594 int list_sort(list_t *restrict l, int versus);
597 * start an iteration session.
599 * This function prepares the list to be iterated.
601 * @param l list to operate
602 * @return 0 if the list cannot be currently iterated. >0 otherwise
604 * @see list_iterator_stop()
606 int list_iterator_start(list_t *restrict l);
609 * return the next element in the iteration session.
611 * @param l list to operate
612 * @return element datum, or NULL on errors
614 void *list_iterator_next(list_t *restrict l);
617 * inspect whether more elements are available in the iteration session.
619 * @param l list to operate
620 * @return 0 iff no more elements are available.
622 int list_iterator_hasnext(const list_t *restrict l);
625 * end an iteration session.
627 * @param l list to operate
628 * @return 0 iff the iteration session cannot be stopped
630 int list_iterator_stop(list_t *restrict l);
633 * return the hash of the current status of the list.
635 * @param l list to operate
636 * @param hash where the resulting hash is put
638 * @return 0 for success; <0 for failure
640 int list_hash(const list_t *restrict l, list_hash_t *restrict hash);
642 #ifndef SIMCLIST_NO_DUMPRESTORE
644 * get meta informations on a list dump on filedescriptor.
646 * [ advanced function ]
648 * Extracts the meta information from a SimCList dump located in a file
649 * descriptor. The file descriptor must be open and positioned at the
650 * beginning of the SimCList dump block.
652 * @param fd file descriptor to get metadata from
653 * @param info reference to a dump metainformation structure to fill
654 * @return 0 for success; <0 for failure
656 * @see list_dump_filedescriptor()
658 int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info);
661 * get meta informations on a list dump on file.
663 * [ advanced function ]
665 * Extracts the meta information from a SimCList dump located in a file.
667 * @param filename filename of the file to fetch from
668 * @param info reference to a dump metainformation structure to fill
669 * @return 0 for success; <0 for failure
671 * @see list_dump_filedescriptor()
673 int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info);
676 * dump the list into an open, writable file descriptor.
678 * This function "dumps" the list to a persistent storage so it can be
679 * preserved across process terminations.
680 * When called, the file descriptor must be open for writing and positioned
681 * where the serialized data must begin. It writes its serialization of the
682 * list in a form which is portable across different architectures. Dump can
683 * be safely performed on stream-only (non seekable) descriptors. The file
684 * descriptor is not closed at the end of the operations.
686 * To use dump functions, either of these conditions must be satisfied:
687 * -# a metric function has been specified with list_attributes_copy()
688 * -# a serializer function has been specified with list_attributes_serializer()
690 * If a metric function has been specified, each element of the list is dumped
691 * as-is from memory, copying it from its pointer for its length down to the
692 * file descriptor. This might have impacts on portability of the dump to
693 * different architectures.
695 * If a serializer function has been specified, its result for each element is
696 * dumped to the file descriptor.
699 * @param l list to operate
700 * @param fd file descriptor to write to
701 * @param len location to store the resulting length of the dump (bytes), or NULL
703 * @return 0 if successful; -1 otherwise
705 * @see element_serializer()
706 * @see list_attributes_copy()
707 * @see list_attributes_serializer()
709 int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len);
712 * dump the list to a file name.
714 * This function creates a filename and dumps the current content of the list
715 * to it. If the file exists it is overwritten. The number of bytes written to
716 * the file can be returned in a specified argument.
718 * @param l list to operate
719 * @param filename filename to write to
720 * @param len location to store the resulting length of the dump (bytes), or NULL
722 * @return 0 if successful; -1 otherwise
724 * @see list_attributes_copy()
725 * @see element_serializer()
726 * @see list_attributes_serializer()
727 * @see list_dump_filedescriptor()
728 * @see list_restore_file()
730 * This function stores a representation of the list
732 int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len);
735 * restore the list from an open, readable file descriptor to memory.
737 * This function is the "inverse" of list_dump_filedescriptor(). It restores
738 * the list content from a (open, read-ready) file descriptor to memory. An
739 * unserializer might be needed to restore elements from the persistent
740 * representation back into memory-consistent format. List attributes can not
741 * be restored and must be set manually.
743 * @see list_dump_filedescriptor()
744 * @see list_attributes_serializer()
745 * @see list_attributes_unserializer()
747 * @param l list to restore to
748 * @param fd file descriptor to read from.
749 * @param len location to store the length of the dump read (bytes), or NULL
750 * @return 0 if successful; -1 otherwise
752 int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len);
755 * restore the list from a file name.
757 * This function restores the content of a list from a file into memory. It is
758 * the inverse of list_dump_file().
760 * @see element_unserializer()
761 * @see list_attributes_unserializer()
762 * @see list_dump_file()
763 * @see list_restore_filedescriptor()
765 * @param l list to restore to
766 * @param filename filename to read data from
767 * @param len location to store the length of the dump read (bytes), or NULL
768 * @return 0 if successful; -1 otherwise
770 int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len);
773 /* ready-made comparators, meters and hash computers */
774 /* comparator functions */
776 * ready-made comparator for int8_t elements.
777 * @see list_attributes_comparator()
779 int list_comparator_int8_t(const void *a, const void *b);
782 * ready-made comparator for int16_t elements.
783 * @see list_attributes_comparator()
785 int list_comparator_int16_t(const void *a, const void *b);
788 * ready-made comparator for int32_t elements.
789 * @see list_attributes_comparator()
791 int list_comparator_int32_t(const void *a, const void *b);
794 * ready-made comparator for int64_t elements.
795 * @see list_attributes_comparator()
797 int list_comparator_int64_t(const void *a, const void *b);
800 * ready-made comparator for uint8_t elements.
801 * @see list_attributes_comparator()
803 int list_comparator_uint8_t(const void *a, const void *b);
806 * ready-made comparator for uint16_t elements.
807 * @see list_attributes_comparator()
809 int list_comparator_uint16_t(const void *a, const void *b);
812 * ready-made comparator for uint32_t elements.
813 * @see list_attributes_comparator()
815 int list_comparator_uint32_t(const void *a, const void *b);
818 * ready-made comparator for uint64_t elements.
819 * @see list_attributes_comparator()
821 int list_comparator_uint64_t(const void *a, const void *b);
824 * ready-made comparator for float elements.
825 * @see list_attributes_comparator()
827 int list_comparator_float(const void *a, const void *b);
830 * ready-made comparator for double elements.
831 * @see list_attributes_comparator()
833 int list_comparator_double(const void *a, const void *b);
836 * ready-made comparator for string elements.
837 * @see list_attributes_comparator()
839 int list_comparator_string(const void *a, const void *b);
841 /* metric functions */
843 * ready-made metric function for int8_t elements.
844 * @see list_attributes_copy()
846 size_t list_meter_int8_t(const void *el);
849 * ready-made metric function for int16_t elements.
850 * @see list_attributes_copy()
852 size_t list_meter_int16_t(const void *el);
855 * ready-made metric function for int32_t elements.
856 * @see list_attributes_copy()
858 size_t list_meter_int32_t(const void *el);
861 * ready-made metric function for int64_t elements.
862 * @see list_attributes_copy()
864 size_t list_meter_int64_t(const void *el);
867 * ready-made metric function for uint8_t elements.
868 * @see list_attributes_copy()
870 size_t list_meter_uint8_t(const void *el);
873 * ready-made metric function for uint16_t elements.
874 * @see list_attributes_copy()
876 size_t list_meter_uint16_t(const void *el);
879 * ready-made metric function for uint32_t elements.
880 * @see list_attributes_copy()
882 size_t list_meter_uint32_t(const void *el);
885 * ready-made metric function for uint64_t elements.
886 * @see list_attributes_copy()
888 size_t list_meter_uint64_t(const void *el);
891 * ready-made metric function for float elements.
892 * @see list_attributes_copy()
894 size_t list_meter_float(const void *el);
897 * ready-made metric function for double elements.
898 * @see list_attributes_copy()
900 size_t list_meter_double(const void *el);
903 * ready-made metric function for string elements.
904 * @see list_attributes_copy()
906 size_t list_meter_string(const void *el);
910 * ready-made hash function for int8_t elements.
911 * @see list_attributes_hash_computer()
913 list_hash_t list_hashcomputer_int8_t(const void *el);
916 * ready-made hash function for int16_t elements.
917 * @see list_attributes_hash_computer()
919 list_hash_t list_hashcomputer_int16_t(const void *el);
922 * ready-made hash function for int32_t elements.
923 * @see list_attributes_hash_computer()
925 list_hash_t list_hashcomputer_int32_t(const void *el);
928 * ready-made hash function for int64_t elements.
929 * @see list_attributes_hash_computer()
931 list_hash_t list_hashcomputer_int64_t(const void *el);
934 * ready-made hash function for uint8_t elements.
935 * @see list_attributes_hash_computer()
937 list_hash_t list_hashcomputer_uint8_t(const void *el);
940 * ready-made hash function for uint16_t elements.
941 * @see list_attributes_hash_computer()
943 list_hash_t list_hashcomputer_uint16_t(const void *el);
946 * ready-made hash function for uint32_t elements.
947 * @see list_attributes_hash_computer()
949 list_hash_t list_hashcomputer_uint32_t(const void *el);
952 * ready-made hash function for uint64_t elements.
953 * @see list_attributes_hash_computer()
955 list_hash_t list_hashcomputer_uint64_t(const void *el);
958 * ready-made hash function for float elements.
959 * @see list_attributes_hash_computer()
961 list_hash_t list_hashcomputer_float(const void *el);
964 * ready-made hash function for double elements.
965 * @see list_attributes_hash_computer()
967 list_hash_t list_hashcomputer_double(const void *el);
970 * ready-made hash function for string elements.
971 * @see list_attributes_hash_computer()
973 list_hash_t list_hashcomputer_string(const void *el);