//Initialize a two-way linked list, the element type is tb_long_t, and the full 256 elements will grow automatically tb_list_ref_t list = tb_list_init(256, tb_item_func_long()); if (list) { //Insert some elements tb_list_insert_tail(list, (tb_cpointer_t)1); tb_list_insert_tail(list, (tb_cpointer_t)2); tb_list_insert_tail(list, (tb_cpointer_t)3); tb_list_insert_tail(list, (tb_cpointer_t)4); tb_list_insert_tail(list, (tb_cpointer_t)5); //Iterate through all elements tb_for_all (tb_long_t, item, list) { tb_trace_i("item: %ld", item); } //Iterative traversal of all elements>3 tb_for_all_if (tb_long_t, item, list, item > 3) { tb_trace_i("item: %ld", item); } //Reverse iteration traverses all elements. Note: only containers that support reverse iteration can do this. For example, single chain tb_single_list_t cannot tb_rfor_all (tb_long_t, item, list) { tb_trace_i("item: %ld", item); } //Reverse iteration traverses all elements>3 tb_rfor_all_if (tb_long_t, item, list, item > 3) { tb_trace_i("item: %ld", item); } //Iterative traversal of some elements. It is considered that the head and tail of the iteration are passed in, and all elements are traversed tb_for (tb_long_t, item, tb_iterator_head(list), tb_iterator_tail(list), list) { tb_trace_i("item: %ld", item); } //Exit linked list tb_list_exit(list); }
//Get the header index of the list tb_size_t itor = tb_iterator_head(list); //Get the tail index of the list tb_size_t tail = tb_iterator_tail(list); //Traversal. The element is not deleted here, so the value of tail does not need to be updated in real time for (; itor != tail; itor = tb_iterator_next(list, itor)) { //Get the element corresponding to the index monitor tb_long_t item = (tb_long_t)tb_iterator_item(list, itor); } //To traverse and delete elements, the tail needs to be updated, so the tb_for cannot be used //Tb_for will not update the value of tail for efficiency while (itor != tb_iterator_tail(list, itor)) { //Get the element corresponding to the index monitor tb_long_t item = (tb_long_t)tb_iterator_item(list, itor); if (item > 3) { //Save the next index first to avoid deleting the current element and making the tor invalid tb_size_t next = tb_iterator_next(list, itor); //Use iterator to delete tb_iterator_remove(list, itor); //Or use container to delete // tb_list_remove(list, itor); //Continue to the next itor = next; continue ; } //Continue to the next itor = tb_iterator_next(list, itor); }
//Callback function tb_long_t tb_list_item_func(tb_iterator_ref_t iterator, tb_cpointer_t item, tb_cpointer_t priv); { //If>3, delete it if ((tb_long_t)item > 3) { /*Mark this element for deletion * *Note: *At this time, the container has not been deleted, and some optimizations have been made *To delete one continuous element at a time, which will be much more efficient * *This deletion mode is the fastest, especially for tb_vector_t, a container with continuous memory, which is more efficient *It avoids moving tb_memov memory once every element is deleted * *The name is similar. Vector traversal and deletion use: tb_vector_walk */ return 0; } //Return 1 to continue the next one, and return - 1 to interrupt traversal return 1; } //Traverse all elements and call the callback function for each element tb_remove_if(list, tb_list_item_func, tb_null);
tb_bool_t tb_walk_item_func(tb_iterator_ref_t iterator, tb_pointer_t item, tb_pointer_t priv) { // ... } //Traverse all tb_walk_all(list, tb_walk_item_func, tb_null); //Reverse traverse all tb_rwalk_all(list, tb_walk_item_func, tb_null); //Local traversal through iterator index tb_walk(list, tb_iterator_head(list), tb_iterator_tail(list), tb_walk_item_func, tb_null); //Reverse through iterator index, local traversal tb_rwalk(list, tb_iterator_head(list), tb_iterator_tail(list), tb_walk_item_func, tb_null);
-
Tb_for series: simple logical traversal for small code blocks -
Direct use of iterators: for complex logic traversal of small code blocks -
Container tb_xxx_walk: used for traversing complex code blocks and efficiently deleting elements -
Tb_walk series: for complex code blocks, traversal when deletion is not required
/// the iterator mode type typedef enum __tb_iterator_mode_t { TB_ITERATOR_MODE_FORWARD=1//!<Forward traversal iterator, which is supported by most containers , TB_ITERATOR_MODE_REVERSE=2//!<Reverse traversal iterator, single chain does not support , TB_ITERATOR_MODE_RACCESS=4//!<Random access iterators, linked lists, queues, stacks, etc. are not supported. Vector is the most commonly used , TB_ITERATOR_MODE_MUTABLE=8//!<A mutable iterator. The index value of the same iterator may change due to deleting an element, such as vector , TB_ITERATOR_MODE_READONLY=16//!<Read only access iterator, deletion, replacement and other operations are not available }tb_iterator_mode_t;
//Get iterator access mode tb_size_t tb_iterator_mode(tb_iterator_ref_t iterator); //Get the total number of elements of the container corresponding to the iterator tb_size_t tb_iterator_size(tb_iterator_ref_t iterator); //Get the header index of the iterator tb_size_t tb_iterator_head(tb_iterator_ref_t iterator); //Get the index of the last element of the iterator tb_size_t tb_iterator_last(tb_iterator_ref_t iterator); //Get the tail index of the iterator, which does not point to the actual element, and is generally used to determine the end tb_size_t tb_iterator_tail(tb_iterator_ref_t iterator); //Get the index of the previous element of the iterator tb_size_t tb_iterator_prev(tb_iterator_ref_t iterator, tb_size_t itor); //Get the index of the next element of the iterator tb_size_t tb_iterator_next(tb_iterator_ref_t iterator, tb_size_t itor); //Get the element pointed to by the iterator index tb_pointer_t tb_iterator_item(tb_iterator_ref_t iterator, tb_size_t itor); //Delete the element pointed to by the iterator index tb_void_t tb_iterator_remove(tb_iterator_ref_t iterator, tb_size_t itor); //Copy the element pointed to by the iterator index tb_void_t tb_iterator_copy(tb_iterator_ref_t iterator, tb_size_t itor, tb_cpointer_t item); //Compare the two elements pointed to by the iterator index tb_long_t tb_iterator_comp(tb_iterator_ref_t iterator, tb_cpointer_t ltem, tb_cpointer_t rtem);
//Generate iterator according to a tb_long_t [] array, and size is the number of array elements tb_iterator_t tb_iterator_init_long(tb_long_t* data, tb_size_t size); //Generate iterator according to a tb_size_t [] array, size is the number of array elements tb_iterator_t tb_iterator_init_size(tb_size_t* data, tb_size_t size); //Generate iterator according to a tb_char_t * [] string array, and size is the number of array elements tb_iterator_t tb_iterator_init_str(tb_char_t** data, tb_size_t size); //Generate iterator according to a tb_pointer_t [] pointer array, and size is the number of array elements tb_iterator_t tb_iterator_init_ptr(tb_pointer_t* data, tb_size_t size); //Generate iterator according to a tb_struct_xxxx_t [] structure array, size is the number of array elements, step==sizeof (tb_struct_xxxx_t) tb_iterator_t tb_iterator_init_mem(tb_pointer_t data, tb_size_t size, tb_size_t step);