- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
static inline void set0b (const uint8_t at, uint64_t bm[static 4])
{
bm[at / 64] &= ~(1ULL << (at % 64));
}
static inline void set1b (const uint8_t at, uint64_t bm[static 4])
{
bm[at / 64] |= 1ULL << (at % 64);
}
static inline void inv_b (const uint8_t at, uint64_t bm[static 4])
{
bm[at / 64] ^= 1ULL << (at % 64);
}
static inline uint8_t find_empt_pos (const uint64_t bm[static 4])
{
if (bm[0] != UINT64_MAX)
{
return __builtin_ctzll(~bm[0]) + 64 * 0; // __builtin_ctzll - https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
}
if (bm[1] != UINT64_MAX)
{
return __builtin_ctzll(~bm[1]) + 64 * 1;
}
if (bm[2] != UINT64_MAX)
{
return __builtin_ctzll(~bm[2]) + 64 * 2;
}
if (bm[3] != UINT64_MAX)
{
return __builtin_ctzll(~bm[3]) + 64 * 3;
}
fprintf(stderr, "ERROR! No empty space!\n");
exit (-1);
}
static inline uint8_t allocate_ll (uint64_t bm[static 4])
{
uint8_t tmp = find_empt_pos (bm);
set1b (tmp, bm);
return tmp;
}
static inline void inject(const uint8_t prev_p, const uint8_t next_p, const uint8_t at, struct ll_data a[static 256])
{
a[next_p].ll.prev = at;
a[prev_p].ll.next = at;
a[at].ll.prev = prev_p;
a[at].ll.next = next_p;
}
static inline void remove_betw(const uint8_t prev_p, const uint8_t next_p, struct ll_data a[static 256])
{
a[prev_p].ll.next = next_p;
a[next_p].ll.prev = prev_p;
}
static inline void remove_at(const uint8_t at, struct ll_data a[static 256], uint64_t bm[static 4])
{
uint8_t prev_t = a[at].ll.prev;
uint8_t next_t = a[at].ll.next;
set0b (at, bm);
a[at].ll.prev = next_t;
a[at].ll.next = prev_t;
}
void add_elem_next (struct ll_all *a, const uint8_t elm, const int value)
{
uint8_t pos = allocate_ll (a->bm);
inject(elm, a->arr[elm].ll.next, pos, a->arr);
set_elm (pos, value, a->arr);
}
void add_elem_prev (struct ll_all *a, const uint8_t elm, const int value)
{
uint8_t pos = allocate_ll (a->bm);
inject(a->arr[elm].ll.prev, elm, pos, a->arr);
a->arr[pos].data = value;
}
void rem_elem_next (struct ll_all *a, const uint8_t elm)
{
set0b (a->arr[elm].ll.next, a->bm);
remove_betw (elm, a->arr[a->arr[elm].ll.next].ll.next, a->arr);
}
void rem_elem_prev (struct ll_all *a, const uint8_t elm)
{
set0b (a->arr[elm].ll.next, a->bm);
remove_betw (a->arr[a->arr[elm].ll.prev].ll.prev, elm, a->arr);
}