mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
klib: Improve klist.h
- Add `kl_shift_at` macro and backing function. This can be used to shift elements at arbitrary positions. `kl_shift` is now defined on top of the new macro. - Change shift/push API, now `kl_push` accepts an object as parameter and `kl_shift` returns the object instead of a status. An assertion against shifting at the end of a list(or empty lists) was added. - Add `kl_iter` and `kl_iter_at` macros. `kl_iter_at` is for starting the iteration at arbitrary positions.
This commit is contained in:
parent
d6ed2b3a39
commit
4f5b250d4e
@ -27,10 +27,12 @@
|
|||||||
#define _AC_KLIST_H
|
#define _AC_KLIST_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
#include "nvim/func_attr.h"
|
#include "nvim/func_attr.h"
|
||||||
|
|
||||||
|
|
||||||
#define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \
|
#define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \
|
||||||
typedef struct { \
|
typedef struct { \
|
||||||
size_t cnt, n, max; \
|
size_t cnt, n, max; \
|
||||||
@ -95,23 +97,27 @@
|
|||||||
kmp_free(name, kl->mp, p); \
|
kmp_free(name, kl->mp, p); \
|
||||||
kmp_free(name, kl->mp, p); \
|
kmp_free(name, kl->mp, p); \
|
||||||
kmp_destroy(name, kl->mp); \
|
kmp_destroy(name, kl->mp); \
|
||||||
xfree(kl); \
|
xfree(kl); \
|
||||||
} \
|
} \
|
||||||
static inline kltype_t *kl_pushp_##name(kl_##name##_t *kl) { \
|
static inline void kl_push_##name(kl_##name##_t *kl, kltype_t d) { \
|
||||||
kl1_##name *q, *p = kmp_alloc(name, kl->mp); \
|
kl1_##name *q, *p = kmp_alloc(name, kl->mp); \
|
||||||
q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \
|
q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \
|
||||||
++kl->size; \
|
++kl->size; \
|
||||||
return &q->data; \
|
q->data = d; \
|
||||||
} \
|
} \
|
||||||
static inline int kl_shift_##name(kl_##name##_t *kl, kltype_t *d) { \
|
static inline kltype_t kl_shift_at_##name(kl_##name##_t *kl, \
|
||||||
|
kl1_##name **n) { \
|
||||||
|
assert((*n)->next); \
|
||||||
kl1_##name *p; \
|
kl1_##name *p; \
|
||||||
if (kl->head->next == 0) return -1; \
|
|
||||||
--kl->size; \
|
--kl->size; \
|
||||||
p = kl->head; kl->head = kl->head->next; \
|
p = *n; \
|
||||||
if (d) *d = p->data; \
|
*n = (*n)->next; \
|
||||||
|
if (p == kl->head) kl->head = *n; \
|
||||||
|
kltype_t d = p->data; \
|
||||||
kmp_free(name, kl->mp, p); \
|
kmp_free(name, kl->mp, p); \
|
||||||
return 0; \
|
return d; \
|
||||||
}
|
} \
|
||||||
|
|
||||||
|
|
||||||
#define kliter_t(name) kl1_##name
|
#define kliter_t(name) kl1_##name
|
||||||
#define klist_t(name) kl_##name##_t
|
#define klist_t(name) kl_##name##_t
|
||||||
@ -122,7 +128,14 @@
|
|||||||
|
|
||||||
#define kl_init(name) kl_init_##name()
|
#define kl_init(name) kl_init_##name()
|
||||||
#define kl_destroy(name, kl) kl_destroy_##name(kl)
|
#define kl_destroy(name, kl) kl_destroy_##name(kl)
|
||||||
#define kl_pushp(name, kl) kl_pushp_##name(kl)
|
#define kl_push(name, kl, d) kl_push_##name(kl, d)
|
||||||
#define kl_shift(name, kl, d) kl_shift_##name(kl, d)
|
#define kl_shift_at(name, kl, node) kl_shift_at_##name(kl, node)
|
||||||
|
#define kl_shift(name, kl) kl_shift_at(name, kl, &kl->head)
|
||||||
#define kl_empty(kl) ((kl)->size == 0)
|
#define kl_empty(kl) ((kl)->size == 0)
|
||||||
|
// Iteration macros. It's ok to modify the list while iterating as long as a
|
||||||
|
// `break` statement is executed before the next iteration.
|
||||||
|
#define kl_iter(name, kl, p) kl_iter_at(name, kl, p, NULL)
|
||||||
|
#define kl_iter_at(name, kl, p, h) \
|
||||||
|
for (kl1_##name *p = h ? h : kl->head; p != kl->tail; p = p->next)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -149,7 +149,7 @@ void event_push(Event event, bool deferred)
|
|||||||
// returns(user hits a key for example). To avoid this scenario, we call
|
// returns(user hits a key for example). To avoid this scenario, we call
|
||||||
// uv_stop when a event is enqueued.
|
// uv_stop when a event is enqueued.
|
||||||
uv_stop(uv_default_loop());
|
uv_stop(uv_default_loop());
|
||||||
*kl_pushp(Event, deferred ? deferred_events : immediate_events) = event;
|
kl_push(Event, deferred ? deferred_events : immediate_events, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void event_process(void)
|
void event_process(void)
|
||||||
@ -159,9 +159,8 @@ void event_process(void)
|
|||||||
|
|
||||||
static void process_events_from(klist_t(Event) *queue)
|
static void process_events_from(klist_t(Event) *queue)
|
||||||
{
|
{
|
||||||
Event event;
|
while (!kl_empty(queue)) {
|
||||||
|
Event event = kl_shift(Event, queue);
|
||||||
while (kl_shift(Event, queue, &event) == 0) {
|
|
||||||
event.handler(event);
|
event.handler(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user