cdcontainers  0.1.1
Library of data containers and collections for C programming language.
list.h
Go to the documentation of this file.
1 // The MIT License (MIT)
2 // Copyright (c) 2017 Maksim Andrianov
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to
6 // deal in the Software without restriction, including without limitation the
7 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 // sell copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 // IN THE SOFTWARE.
27 #ifndef CDCONTAINERS_INCLUDE_CDCONTAINERS_LIST_H
28 #define CDCONTAINERS_INCLUDE_CDCONTAINERS_LIST_H
29 
30 #include <cdcontainers/common.h>
31 #include <cdcontainers/status.h>
32 
33 #include <assert.h>
34 #include <stdarg.h>
35 #include <stdbool.h>
36 #include <stdlib.h>
37 
49 struct cdc_list_node {
52  void *data;
53 };
54 
60 struct cdc_list {
63  size_t size;
65 };
66 
72 struct cdc_list_iter {
75 };
76 
85 };
86 
99 #define CDC_LIST_FOR_EACH(item, list) \
100  for (cdc_list_node * (item) = (list->head); (item); (item) = (item)->next)
101 
102 // Base
114 enum cdc_stat cdc_list_ctor(struct cdc_list **l, struct cdc_data_info *info);
115 
133 enum cdc_stat cdc_list_ctorl(struct cdc_list **l, struct cdc_data_info *info,
134  ...);
135 
143 enum cdc_stat cdc_list_ctorv(struct cdc_list **l, struct cdc_data_info *info,
144  va_list args);
145 
150 void cdc_list_dtor(struct cdc_list *l);
153 // Element access
164 void *cdc_list_get(struct cdc_list *l, size_t index);
165 
175 enum cdc_stat cdc_list_at(struct cdc_list *l, size_t index, void **elem);
176 
182 static inline void *cdc_list_front(struct cdc_list *l)
183 {
184  assert(l != NULL);
185  assert(l->size > 0);
186 
187  return l->head->data;
188 }
189 
195 static inline void *cdc_list_back(struct cdc_list *l)
196 {
197  assert(l != NULL);
198  assert(l->size > 0);
199 
200  return l->tail->data;
201 }
204 // Capacity
214 static inline size_t cdc_list_size(struct cdc_list *l)
215 {
216  assert(l != NULL);
217 
218  return l->size;
219 }
220 
226 static inline bool cdc_list_empty(struct cdc_list *l)
227 {
228  assert(l != NULL);
229 
230  return l->size == 0;
231 }
234 // Modifiers
246 void cdc_list_set(struct cdc_list *l, size_t index, void *value);
247 
255 enum cdc_stat cdc_list_push_back(struct cdc_list *l, void *value);
256 
261 void cdc_list_pop_back(struct cdc_list *l);
262 
270 enum cdc_stat cdc_list_push_front(struct cdc_list *l, void *value);
271 
276 void cdc_list_pop_front(struct cdc_list *l);
277 
288 enum cdc_stat cdc_list_insert(struct cdc_list *l, size_t index, void *value);
289 
297 enum cdc_stat cdc_list_iinsert(struct cdc_list_iter *before, void *value);
298 
304 void cdc_list_erase(struct cdc_list *l, size_t index);
305 
310 void cdc_list_ierase(struct cdc_list_iter *pos);
311 
316 void cdc_list_clear(struct cdc_list *l);
317 
324 void cdc_list_swap(struct cdc_list *a, struct cdc_list *b);
327 // Operations
338 void cdc_list_splice(struct cdc_list_iter *position,
339  struct cdc_list_iter *first, struct cdc_list_iter *last);
340 
347 void cdc_list_ssplice(struct cdc_list_iter *position,
348  struct cdc_list_iter *first);
349 
356 void cdc_list_lsplice(struct cdc_list_iter *position, struct cdc_list *other);
357 
364 void cdc_list_merge(struct cdc_list *l, struct cdc_list *other);
365 
372 void cdc_list_cmerge(struct cdc_list *l, struct cdc_list *other,
373  cdc_binary_pred_fn_t compare);
381 void cdc_list_erase_if(struct cdc_list *l, cdc_unary_pred_fn_t pred);
382 
387 void cdc_list_reverse(struct cdc_list *l);
388 
394 void cdc_list_unique(struct cdc_list *l);
395 
403 void cdc_list_punique(struct cdc_list *l, cdc_binary_pred_fn_t pred);
404 
409 void cdc_list_sort(struct cdc_list *l);
410 
417 void cdc_list_csort(struct cdc_list *l, cdc_binary_pred_fn_t compare);
418 
422 void cdc_list_foreach(struct cdc_list *l, void (*cb)(void *));
425 // Iterators
435 static inline void cdc_list_begin(struct cdc_list *l, struct cdc_list_iter *it)
436 {
437  assert(l != NULL);
438  assert(it != NULL);
439 
440  it->container = l;
441  it->current = l->head;
442 }
443 
449 static inline void cdc_list_end(struct cdc_list *l, struct cdc_list_iter *it)
450 {
451  assert(l != NULL);
452  assert(it != NULL);
453 
454  it->container = l;
455  it->current = NULL;
456 }
457 
463 static inline void cdc_list_rbegin(struct cdc_list *l,
464  struct cdc_list_riter *it)
465 {
466  assert(l != NULL);
467  assert(it != NULL);
468 
469  it->container = l;
470  it->current = l->tail;
471 }
472 
478 static inline void cdc_list_rend(struct cdc_list *l, struct cdc_list_riter *it)
479 {
480  assert(l != NULL);
481  assert(it != NULL);
482 
483  it->container = l;
484  it->current = NULL;
485 }
488 // Iterators
498 static inline void cdc_list_iter_next(struct cdc_list_iter *it)
499 {
500  assert(it != NULL);
501 
502  it->current = it->current->next;
503 }
504 
509 static inline void cdc_list_iter_prev(struct cdc_list_iter *it)
510 {
511  assert(it != NULL);
512 
513  it->current = it->current ? it->current->prev : it->container->tail;
514 }
515 
523 static inline bool cdc_list_iter_has_next(struct cdc_list_iter *it)
524 {
525  assert(it != NULL);
526 
527  return it->current->next != NULL;
528 }
529 
537 static inline bool cdc_list_iter_has_prev(struct cdc_list_iter *it)
538 {
539  assert(it != NULL);
540 
541  return it->current->prev != NULL;
542 }
543 
548 static inline void *cdc_list_iter_data(struct cdc_list_iter *it)
549 {
550  assert(it != NULL);
551 
552  return it->current->data;
553 }
554 
560 static inline void cdc_list_iter_from(struct cdc_list_riter *rit,
561  struct cdc_list_iter *it)
562 {
563  assert(rit != NULL);
564  assert(it != NULL);
565 
566  it->container = rit->container;
567  it->current = rit->current ? rit->current->next : rit->container->head;
568 }
569 
578 static inline bool cdc_list_iter_is_eq(struct cdc_list_iter *it1,
579  struct cdc_list_iter *it2)
580 {
581  assert(it1 != NULL);
582  assert(it2 != NULL);
583 
584  return it1->container == it2->container && it1->current == it2->current;
585 }
586 
591 static inline void cdc_list_riter_next(struct cdc_list_riter *it)
592 {
593  assert(it != NULL);
594 
595  it->current = it->current->prev;
596 }
597 
602 static inline void cdc_list_riter_prev(struct cdc_list_riter *it)
603 {
604  assert(it != NULL);
605 
606  it->current = it->current ? it->current->next : it->container->head;
607 }
608 
617 static inline bool cdc_list_riter_has_next(struct cdc_list_riter *it)
618 {
619  assert(it != NULL);
620 
621  return it->current->prev != NULL;
622 }
623 
633 static inline bool cdc_list_riter_has_prev(struct cdc_list_riter *it)
634 {
635  assert(it != NULL);
636 
637  return it->current->next != NULL;
638 }
639 
644 static inline void *cdc_list_riter_data(struct cdc_list_riter *it)
645 {
646  assert(it != NULL);
647 
648  return it->current->data;
649 }
650 
656 static inline void cdc_list_riter_from(struct cdc_list_iter *it,
657  struct cdc_list_riter *rit)
658 {
659  assert(it != NULL);
660  assert(rit != NULL);
661 
662  rit->container = it->container;
663  rit->current = it->current ? it->current->prev : it->container->tail;
664 }
665 
672 static inline bool cdc_list_riter_is_eq(struct cdc_list_riter *rit1,
673  struct cdc_list_riter *rit2)
674 {
675  assert(rit1 != NULL);
676  assert(rit2 != NULL);
677 
678  return rit1->container == rit2->container && rit1->current == rit2->current;
679 }
682 // Short names
683 #ifdef CDC_USE_SHORT_NAMES
684 typedef struct cdc_list list_t;
685 typedef struct cdc_list_iter list_iter_t;
686 typedef struct cdc_list_riter list_riter_t;
687 
688 // Base
689 #define list_ctor(...) cdc_list_ctor(__VA_ARGS__)
690 #define list_ctorl(...) cdc_list_ctorl(__VA_ARGS__)
691 #define list_ctorv(...) cdc_list_ctorv(__VA_ARGS__)
692 #define list_dtor(...) cdc_list_dtor(__VA_ARGS__)
693 
694 // Element access
695 #define list_at(...) cdc_list_at(__VA_ARGS__)
696 #define list_front(...) cdc_list_front(__VA_ARGS__)
697 #define list_back(...) cdc_list_back(__VA_ARGS__)
698 
699 // Capacity
700 #define list_empty(...) cdc_list_empty(__VA_ARGS__)
701 #define list_size(...) cdc_list_size(__VA_ARGS__)
702 
703 // Modifiers
704 #define list_insert(...) cdc_list_insert(__VA_ARGS__)
705 #define list_iinsert(...) cdc_list_iinsert(__VA_ARGS__)
706 #define list_erase(...) cdc_list_erase(__VA_ARGS__)
707 #define list_ierase(...) cdc_list_ierase(__VA_ARGS__)
708 #define list_clear(...) cdc_list_clear(__VA_ARGS__)
709 #define list_push_back(...) cdc_list_push_back(__VA_ARGS__)
710 #define list_pop_back(...) cdc_list_pop_back(__VA_ARGS__)
711 #define list_push_front(...) cdc_list_push_front(__VA_ARGS__)
712 #define list_pop_front(...) cdc_list_pop_back(__VA_ARGS__)
713 #define list_swap(...) cdc_list_swap(__VA_ARGS__)
714 
715 // Operations
716 #define list_splice(...) cdc_list_splice(__VA_ARGS__)
717 #define list_ssplice(...) cdc_list_ssplice(__VA_ARGS__)
718 #define list_lsplice(...) cdc_list_lsplice(__VA_ARGS__)
719 #define list_merge(...) cdc_list_merge(__VA_ARGS__)
720 #define list_cmerge(...) cdc_list_cmerge(__VA_ARGS__)
721 #define list_erase_if(...) cdc_list_erase_if(__VA_ARGS__)
722 #define list_reverse(...) cdc_list_reverse(__VA_ARGS__)
723 #define list_unique(...) cdc_list_unique(__VA_ARGS__)
724 #define list_punique(...) cdc_list_punique(__VA_ARGS__)
725 #define list_sort(...) cdc_list_sort(__VA_ARGS__)
726 #define list_csort(...) cdc_list_csort(__VA_ARGS__)
727 
728 #define list_foreach(...) cdc_list_foreach(__VA_ARGS__)
729 
730 // Iterators
731 #define list_begin(...) cdc_list_begin(__VA_ARGS__)
732 #define list_end(...) cdc_list_end(__VA_ARGS__)
733 #define list_rbegin(...) cdc_list_rbegin(__VA_ARGS__)
734 #define list_rend(...) cdc_list_rend(__VA_ARGS__)
735 
736 // Iterators
737 #define list_iter_next(...) cdc_list_iter_next(__VA_ARGS__)
738 #define list_iter_prev(...) cdc_list_iter_prev(__VA_ARGS__)
739 #define list_iter_has_next(...) cdc_list_iter_has_next(__VA_ARGS__)
740 #define list_iter_has_prev(...) cdc_list_iter_has_prev(__VA_ARGS__)
741 #define list_iter_data(...) cdc_list_iter_data(__VA_ARGS__)
742 #define list_riter_from(...) cdc_list_riter_from(__VA_ARGS__)
743 #define list_iter_is_eq(...) cdc_list_iter_is_eq(__VA_ARGS__)
744 
745 #define list_riter_next(...) cdc_list_riter_next(__VA_ARGS__)
746 #define list_riter_prev(...) cdc_list_riter_prev(__VA_ARGS__)
747 #define list_riter_has_next(...) cdc_list_riter_has_next(__VA_ARGS__)
748 #define list_riter_has_prev(...) cdc_list_riter_has_prev(__VA_ARGS__)
749 #define list_riter_data(...) cdc_list_riter_data(__VA_ARGS__)
750 #define list_iter_from(...) cdc_list_iter_from(__VA_ARGS__)
751 #define list_riter_is_eq(...) cdc_list_riter_is_eq(__VA_ARGS__)
752 #endif
753 
754 #endif // CDCONTAINERS_INCLUDE_CDCONTAINERS_LIST_H
static bool cdc_list_iter_is_eq(struct cdc_list_iter *it1, struct cdc_list_iter *it2)
Returns false if the iterator |it1| equal to the iterator |it2|, otherwise returns false...
Definition: list.h:578
void cdc_list_splice(struct cdc_list_iter *position, struct cdc_list_iter *first, struct cdc_list_iter *last)
Transfers elements from one container, iterators (first, last] to another container at position befor...
void cdc_list_set(struct cdc_list *l, size_t index, void *value)
Sets an element at index position to the value. The function is not called to free memory...
struct cdc_list_node * prev
Definition: list.h:51
void cdc_list_erase(struct cdc_list *l, size_t index)
Removes an element at index position in the circular arrray.
void cdc_list_lsplice(struct cdc_list_iter *position, struct cdc_list *other)
Transfers all elements from container other to another container at position before iterator position...
The cdc_list_iterator is service struct.
Definition: list.h:72
void cdc_list_reverse(struct cdc_list *l)
Reverses the order of elements in the container.
void * data
Definition: list.h:52
enum cdc_stat cdc_list_push_front(struct cdc_list *l, void *value)
Inserts an element at the beginning of the list.
static void * cdc_list_riter_data(struct cdc_list_riter *it)
Returns a current element.
Definition: list.h:644
struct cdc_list * container
Definition: list.h:73
static bool cdc_list_riter_is_eq(struct cdc_list_riter *rit1, struct cdc_list_riter *rit2)
Returns false if the reverse iterator |rit1| equal to the reverse iterator |rit2|, otherwise returns false.
Definition: list.h:672
static void * cdc_list_back(struct cdc_list *l)
Returns a last element in the list.
Definition: list.h:195
static void * cdc_list_iter_data(struct cdc_list_iter *it)
Returns a current element.
Definition: list.h:548
The cdc_list_riter is service struct.
Definition: list.h:82
static bool cdc_list_empty(struct cdc_list *l)
Checks if the list has no elements.
Definition: list.h:226
static void cdc_list_iter_from(struct cdc_list_riter *rit, struct cdc_list_iter *it)
Сasts reverse iterator to iterator.
Definition: list.h:560
void cdc_list_swap(struct cdc_list *a, struct cdc_list *b)
Swaps lists a and b. This operation is very fast and never fails.
The cdc_list_node is service struct.
Definition: list.h:49
static void cdc_list_end(struct cdc_list *l, struct cdc_list_iter *it)
Initializes the iterator to the end.
Definition: list.h:449
static bool cdc_list_riter_has_next(struct cdc_list_riter *it)
Returns true if there is at least one item ahead of the reverse iterator, i.e. the reverse iterator i...
Definition: list.h:617
struct cdc_list_node * current
Definition: list.h:74
enum cdc_stat cdc_list_iinsert(struct cdc_list_iter *before, void *value)
Inserts an element in front of the item pointed to by the iterator before.
void cdc_list_punique(struct cdc_list *l, cdc_binary_pred_fn_t pred)
Removes all consecutive duplicate elements from the container. Only the first element in each group o...
void cdc_list_foreach(struct cdc_list *l, void(*cb)(void *))
A function |cb| is applied to each item of the list.
size_t size
Definition: list.h:63
static size_t cdc_list_size(struct cdc_list *l)
Returns the number of elements in the list.
Definition: list.h:214
static void cdc_list_begin(struct cdc_list *l, struct cdc_list_iter *it)
Initializes the iterator to the beginning.
Definition: list.h:435
void cdc_list_ssplice(struct cdc_list_iter *position, struct cdc_list_iter *first)
Transfers elements from one container, iterators (first, end] to another container at position before...
void cdc_list_pop_front(struct cdc_list *l)
Removes a first element in the list.
static void cdc_list_riter_prev(struct cdc_list_riter *it)
Advances the reverse iterator to the previous element in the list.
Definition: list.h:602
static void cdc_list_rend(struct cdc_list *l, struct cdc_list_riter *it)
Initializes the reverse iterator to the end.
Definition: list.h:478
struct cdc_list_node * next
Definition: list.h:50
void cdc_list_erase_if(struct cdc_list *l, cdc_unary_pred_fn_t pred)
Removes from the container all elements for which predicate pred returns true.
void cdc_list_unique(struct cdc_list *l)
Removes all consecutive duplicate elements from the container. Only the first element in each group o...
int(* cdc_binary_pred_fn_t)(const void *, const void *)
Definition: common.h:57
int(* cdc_unary_pred_fn_t)(const void *)
Definition: common.h:56
enum cdc_stat cdc_list_push_back(struct cdc_list *l, void *value)
Inserts an element at the end of the list.
cdc_stat
Definition: status.h:24
static bool cdc_list_iter_has_next(struct cdc_list_iter *it)
Returns true if there is at least one element ahead of the iterator, i.e. the iterator is not at the ...
Definition: list.h:523
void cdc_list_pop_back(struct cdc_list *l)
Removes a last element in the list.
struct cdc_data_info * dinfo
Definition: list.h:64
void cdc_list_csort(struct cdc_list *l, cdc_binary_pred_fn_t compare)
Sorts elements in ascending order.
void cdc_list_clear(struct cdc_list *l)
Removes all the elements from the list.
static void cdc_list_rbegin(struct cdc_list *l, struct cdc_list_riter *it)
Initializes the reverse iterator to the beginning.
Definition: list.h:463
static bool cdc_list_iter_has_prev(struct cdc_list_iter *it)
Returns true if there is at least one element behind the iterator, i.e. the iterator is not at the fr...
Definition: list.h:537
enum cdc_stat cdc_list_insert(struct cdc_list *l, size_t index, void *value)
Inserts an element at |index| position in the list. If index is 0, the value is prepended to the list...
static void cdc_list_iter_next(struct cdc_list_iter *it)
Advances the iterator to the next element in the list.
Definition: list.h:498
struct cdc_list_node * tail
Definition: list.h:62
static void * cdc_list_front(struct cdc_list *l)
Returns a first element in the list.
Definition: list.h:182
void * cdc_list_get(struct cdc_list *l, size_t index)
Returns an element at index position index in the list.
void cdc_list_merge(struct cdc_list *l, struct cdc_list *other)
Merges two sorted lists into one. The lists should be sorted into ascending order.
enum cdc_stat cdc_list_ctor(struct cdc_list **l, struct cdc_data_info *info)
Constructs an empty list.
static void cdc_list_riter_from(struct cdc_list_iter *it, struct cdc_list_riter *rit)
Сasts iterator to reverse iterator.
Definition: list.h:656
static void cdc_list_iter_prev(struct cdc_list_iter *it)
Advances the iterator to the previous element in the list.
Definition: list.h:509
void cdc_list_ierase(struct cdc_list_iter *pos)
Removes an element associated with the iterator pos from the list.
The cdc_lisе is service struct.
Definition: list.h:60
enum cdc_stat cdc_list_ctorl(struct cdc_list **l, struct cdc_data_info *info,...)
Constructs a list, initialized by an variable number of pointers. The last pointer must be CDC_END...
void cdc_list_cmerge(struct cdc_list *l, struct cdc_list *other, cdc_binary_pred_fn_t compare)
Merges two sorted lists into one. The lists should be sorted.
The cdc_data_info struct used to initialize contaners.
Definition: common.h:71
enum cdc_stat cdc_list_at(struct cdc_list *l, size_t index, void **elem)
Writes to pointer an element from specified position in the list. Bounds checking is performed...
enum cdc_stat cdc_list_ctorv(struct cdc_list **l, struct cdc_data_info *info, va_list args)
Constructs a list, initialized by args. The last pointer must be CDC_END.
void cdc_list_dtor(struct cdc_list *l)
Destroys the list.
static void cdc_list_riter_next(struct cdc_list_riter *it)
Advances the reverse iterator to the next element in the list.
Definition: list.h:591
struct cdc_list_node * head
Definition: list.h:61
static bool cdc_list_riter_has_prev(struct cdc_list_riter *it)
Returns true if there is at least one item behind the reverse iterator, i.e. the reverse iterator is ...
Definition: list.h:633
void cdc_list_sort(struct cdc_list *l)
Sorts elements in ascending order.