mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-14 15:29:31 -06:00
213 lines
3.7 KiB
C
213 lines
3.7 KiB
C
#ifndef GU_SEQ_H_
|
|
#define GU_SEQ_H_
|
|
|
|
#include <gu/mem.h>
|
|
#include <gu/bits.h>
|
|
|
|
|
|
typedef struct GuBuf GuBuf;
|
|
|
|
typedef GuOpaque() GuSeq;
|
|
|
|
GuSeq
|
|
gu_make_seq(size_t elem_size, size_t len, GuPool* pool);
|
|
|
|
#define gu_new_seq(T, N, POOL) \
|
|
gu_make_seq(sizeof(T), (N), (POOL))
|
|
|
|
static inline size_t
|
|
gu_seq_length(GuSeq seq)
|
|
{
|
|
GuWord w = seq.w_;
|
|
size_t tag = gu_tagged_tag(w);
|
|
if (tag == 0) {
|
|
GuWord* p = gu_tagged_ptr(w);
|
|
return (size_t) (p[-1] >> 1);
|
|
}
|
|
return tag;
|
|
}
|
|
|
|
static inline void*
|
|
gu_seq_data(GuSeq seq)
|
|
{
|
|
GuWord w = seq.w_;
|
|
int tag = gu_tagged_tag(w);
|
|
void* ptr = gu_tagged_ptr(w);
|
|
if (tag == 0) {
|
|
GuWord* p = ptr;
|
|
if (p[-1] & 0x1) {
|
|
return *(uint8_t**) ptr;
|
|
}
|
|
}
|
|
return ptr;
|
|
}
|
|
|
|
static inline bool
|
|
gu_seq_is_null(GuSeq seq)
|
|
{
|
|
return (gu_tagged_ptr(seq.w_)) == NULL;
|
|
}
|
|
|
|
|
|
#define gu_seq_index(SEQ, T, I) \
|
|
(&((T*)gu_seq_data(SEQ))[I])
|
|
|
|
#define gu_seq_get(SEQ, T, I) \
|
|
(*gu_seq_index(SEQ, T, I))
|
|
|
|
#define gu_seq_set(SEQ, T, I, V) \
|
|
GU_BEGIN \
|
|
(*gu_seq_index(SEQ, T, I) = (V)); \
|
|
GU_END
|
|
|
|
|
|
|
|
|
|
GuBuf*
|
|
gu_seq_buf(GuSeq seq);
|
|
|
|
GuSeq
|
|
gu_buf_seq(GuBuf* buf);
|
|
|
|
GuBuf*
|
|
gu_make_buf(size_t elem_size, GuPool* pool);
|
|
|
|
#define gu_new_buf(T, POOL) \
|
|
gu_make_buf(sizeof(T), (POOL))
|
|
|
|
size_t
|
|
gu_buf_length(GuBuf* buf);
|
|
|
|
size_t
|
|
gu_buf_avail(GuBuf* buf);
|
|
|
|
void*
|
|
gu_buf_data(GuBuf* buf);
|
|
|
|
#define gu_buf_index(BUF, T, I) \
|
|
(&((T*)gu_buf_data(BUF))[I])
|
|
|
|
#define gu_buf_get(BUF, T, I) \
|
|
(*gu_buf_index(BUF, T, I))
|
|
|
|
#define gu_buf_set(BUF, T, I) \
|
|
GU_BEGIN \
|
|
(*gu_buf_index(BUF, T, I) = (V)); \
|
|
GU_END
|
|
|
|
void
|
|
gu_buf_push_n(GuBuf* buf, const void* elems, size_t n_elems);
|
|
|
|
void*
|
|
gu_buf_extend_n(GuBuf* buf, size_t n_elems);
|
|
|
|
void*
|
|
gu_buf_extend(GuBuf* buf);
|
|
|
|
#define gu_buf_push(BUF, T, VAL) \
|
|
GU_BEGIN \
|
|
((*(T*)gu_buf_extend(BUF)) = (VAL)); \
|
|
GU_END
|
|
|
|
void
|
|
gu_buf_pop_n(GuBuf* buf, size_t n_elems, void* data_out);
|
|
|
|
const void*
|
|
gu_buf_trim_n(GuBuf* buf, size_t n_elems);
|
|
|
|
const void*
|
|
gu_buf_trim(GuBuf* buf);
|
|
|
|
#define gu_buf_pop(BUF, T) \
|
|
(*(T*)gu_buf_trim(BUF))
|
|
|
|
void
|
|
gu_seq_resize_tail(GuSeq seq, ptrdiff_t change);
|
|
|
|
|
|
// Using a buffer as a heap
|
|
void
|
|
gu_buf_heap_push(GuBuf *buf, GuOrder *order, void *value);
|
|
|
|
void
|
|
gu_buf_heap_pop(GuBuf *buf, GuOrder *order, void* data_out);
|
|
|
|
void
|
|
gu_buf_heap_replace(GuBuf *buf, GuOrder *order, void *value, void *data_out);
|
|
|
|
void
|
|
gu_buf_heapify(GuBuf *buf, GuOrder *order);
|
|
|
|
#if 0
|
|
void
|
|
gu_buf_resize_head(GuBuf* buf, ptrdiff_t change);
|
|
|
|
void
|
|
gu_buf_unshift(GuBuf* buf, const void* data, size_t size);
|
|
|
|
void
|
|
gu_buf_shift(GuBuf* buf, size_t size, void* data_out);
|
|
#endif
|
|
|
|
GuSeq
|
|
gu_buf_freeze(GuBuf* buf, GuPool* pool);
|
|
|
|
extern const GuSeq gu_null_seq;
|
|
|
|
#define GU_NULL_SEQ { .w_ = (GuWord)(void*)NULL }
|
|
|
|
typedef GuSeq GuChars;
|
|
typedef GuSeq GuBytes;
|
|
typedef GuBuf GuCharBuf;
|
|
typedef GuBuf GuByteBuf;
|
|
|
|
char*
|
|
gu_chars_str(GuChars chars, GuPool* pool);
|
|
|
|
#endif // GU_SEQ_H_
|
|
|
|
#if defined(GU_OUT_H_) && !defined(GU_SEQ_H_OUT_)
|
|
#define GU_SEQ_H_OUT_
|
|
|
|
GuOut*
|
|
gu_buf_out(GuBuf* buf, GuPool* pool);
|
|
|
|
#endif
|
|
|
|
|
|
#if defined(GU_TYPE_H_) && !defined(GU_SEQ_H_TYPE_)
|
|
#define GU_SEQ_H_TYPE_
|
|
|
|
extern GU_DECLARE_KIND(GuSeq);
|
|
extern GU_DECLARE_KIND(GuBuf);
|
|
|
|
struct GuSeqType {
|
|
GuType_GuOpaque opaque_base;
|
|
GuType* elem_type;
|
|
};
|
|
|
|
typedef const struct GuSeqType GuSeqType, GuType_GuSeq;
|
|
|
|
#define GU_TYPE_INIT_GuSeq(k_, t_, elem_type_) { \
|
|
.opaque_base = GU_TYPE_INIT_GuOpaque(k_, t_, _), \
|
|
.elem_type = elem_type_, \
|
|
}
|
|
|
|
typedef struct GuBufType GuBufType, GuType_GuBuf;
|
|
|
|
struct GuBufType {
|
|
GuType_abstract abstract_base;
|
|
GuType* elem_type;
|
|
};
|
|
|
|
#define GU_TYPE_INIT_GuBuf(KIND, BUF_T, ELEM_T) { \
|
|
.abstract_base = GU_TYPE_INIT_abstract(KIND, BUF_T, _), \
|
|
.elem_type = ELEM_T \
|
|
}
|
|
|
|
extern GU_DECLARE_TYPE(GuChars, GuSeq);
|
|
extern GU_DECLARE_TYPE(GuBytes, GuSeq);
|
|
|
|
#endif
|
|
|