NVMLib  very early alpha
A library to optimally use a Hybrid RAM setup.
list.h
Go to the documentation of this file.
1 
8 #ifndef __NVM_LIST__
9 #define __NVM_LIST__
10 
11 #include <stdlib.h>
12 
13 #define NULL 0
14 #define DECLARE_LIST(VALUE_TYPE)\
15 struct VALUE_TYPE##_list_node {\
16  VALUE_TYPE* ele;\
17  struct VALUE_TYPE##_list_node* next;\
18  struct VALUE_TYPE##_list_node* prev;\
19 };\
20 \
21 struct VALUE_TYPE##_list_head {\
22  struct VALUE_TYPE##_list_node* curr;\
23  struct VALUE_TYPE##_list_node* first;\
24  struct VALUE_TYPE##_list_node* last;\
25 };\
26 typedef struct VALUE_TYPE##_list_node VALUE_TYPE##_list_node;\
27 typedef struct VALUE_TYPE##_list_head VALUE_TYPE##_list_head;\
28 \
29 VALUE_TYPE##_list_head* create_##VALUE_TYPE##_list() {\
30  VALUE_TYPE##_list_head* new_head = (VALUE_TYPE##_list_head*)malloc(sizeof(VALUE_TYPE##_list_head));\
31  new_head->curr = NULL;\
32  new_head->first = NULL;\
33  new_head->last = NULL;\
34 }\
35 \
36 void insert_head_##VALUE_TYPE##_node(VALUE_TYPE* ele, VALUE_TYPE##_list_head* list_head) {\
37  VALUE_TYPE##_list_node* new_node = (VALUE_TYPE##_list_node*)malloc(sizeof(VALUE_TYPE##_list_node));\
38  new_node->ele = ele;\
39  new_node->next = list_head->first;\
40  if (!list_head->first) {\
41  list_head->last = new_node;\
42  list_head->curr = new_node;\
43  } else {\
44  list_head->first->prev = new_node;\
45  }\
46  list_head->first = new_node;\
47 }\
48 \
49 void insert_tail_##VALUE_TYPE##_node(VALUE_TYPE* ele, VALUE_TYPE##_list_head* list_head) {\
50  VALUE_TYPE##_list_node* new_node = (VALUE_TYPE##_list_node*)malloc(sizeof(VALUE_TYPE##_list_node));\
51  new_node->ele = ele;\
52  new_node->prev = list_head->last;\
53  if (!list_head->last) {\
54  list_head->first = new_node;\
55  list_head->curr = new_node;\
56  } else {\
57  list_head->last->next = new_node;\
58  }\
59  list_head->last = new_node;\
60 }\
61 \
62 void insert_after_curr_##VALUE_TYPE##_node(VALUE_TYPE* ele, VALUE_TYPE##_list_head* list_head) {\
63  if (!list_head->curr) {\
64  insert_head_##VALUE_TYPE##_node(ele, list_head);\
65  return;\
66  }\
67  VALUE_TYPE##_list_node* new_node = (VALUE_TYPE##_list_node*)malloc(sizeof(VALUE_TYPE##_list_node));\
68  new_node->ele = ele;\
69  if (list_head->curr->next) {\
70  list_head->curr->next->prev = new_node;\
71  new_node->next = list_head->curr->next;\
72  } else {\
73  list_head->last = new_node;\
74  }\
75  list_head->curr->next = new_node;\
76  new_node->prev = list_head->curr;\
77 }\
78 \
79 void insert_before_curr_##VALUE_TYPE##_node(VALUE_TYPE* ele, VALUE_TYPE##_list_head* list_head) {\
80  if (!list_head->curr) {\
81  insert_tail_##VALUE_TYPE##_node(ele, list_head);\
82  return;\
83  }\
84  VALUE_TYPE##_list_node* new_node = (VALUE_TYPE##_list_node*)malloc(sizeof(VALUE_TYPE##_list_node));\
85  new_node->ele = ele;\
86  if (list_head->curr->prev) {\
87  list_head->curr->prev->next = new_node;\
88  new_node->prev = list_head->curr->prev;\
89  } else {\
90  list_head->first = new_node;\
91  }\
92  list_head->curr->prev = new_node;\
93  new_node->next = list_head->curr;\
94 }\
95 \
96 VALUE_TYPE* access_##VALUE_TYPE##_list_current(VALUE_TYPE##_list_head* list_head) {\
97  return list_head->curr->ele;\
98 }\
99 \
100 void VALUE_TYPE##_list_next_ele(VALUE_TYPE##_list_head* list_head) {\
101  if (list_head->curr) {\
102  list_head->curr = list_head->curr->next;\
103  }\
104 }\
105 \
106 void VALUE_TYPE##_list_prev_ele(VALUE_TYPE##_list_head* list_head) {\
107  if (list_head->curr && list_head->curr->prev) {\
108  list_head->curr = list_head->curr->prev;\
109  } else if (!list_head->curr)\
110  list_head->curr = list_head->last;\
111 }\
112 \
113 void VALUE_TYPE##_list_del_curr(VALUE_TYPE##_list_head* list_head) {\
114  if (list_head->curr) {\
115  if (list_head->curr->prev)\
116  list_head->curr->prev->next = list_head->curr->next;\
117  if (list_head->curr->next)\
118  list_head->curr->next->prev = list_head->curr->prev;\
119  }else {\
120  return;\
121  }\
122  if (list_head->curr->prev) {\
123  list_head->curr = list_head->curr->prev;\
124  } else if (list_head->curr->next) {\
125  list_head->curr = list_head->curr->next;\
126  list_head->first = list_head->curr->next;\
127  } else {\
128  list_head->last = NULL;\
129  }\
130 }\
131 \
132 void VALUE_TYPE##_list_goto_head(VALUE_TYPE##_list_head* list_head) {\
133  list_head->curr = list_head->first;\
134 }\
135 
136 #endif // !__NVM_LIST__