|
|
|
//! Generic pointer slice
|
|
|
|
#ifndef _SLICE_H
|
|
|
|
#define _SLICE_H
|
|
|
|
|
|
|
|
#include <limits.h>
|
|
|
|
|
|
|
|
#include "ints.h"
|
|
|
|
#include "macros.h"
|
|
|
|
|
|
|
|
typedef struct _slice {
|
|
|
|
union {
|
|
|
|
void* ptr;
|
|
|
|
u8* bytes;
|
|
|
|
};
|
|
|
|
usize len;
|
|
|
|
} slice_t;
|
|
|
|
|
|
|
|
#define SLICE_MAX ((struct _slice){ .ptr = AS(UINTPTR_MAX, void*), .len = SIZE_MAX })
|
|
|
|
|
|
|
|
#define SLICE(origin, length) ((struct _slice){ .ptr = ((void*)(origin)), .len = ((usize)(length)) })
|
|
|
|
|
|
|
|
_mixin usize slice_end(const slice_t*pIN slice)
|
|
|
|
{
|
|
|
|
return AS(slice->bytes + slice->len, usize);
|
|
|
|
}
|
|
|
|
|
|
|
|
_mixin usize slice_start(const slice_t*pIN slice)
|
|
|
|
{
|
|
|
|
return AS(slice->bytes, usize);
|
|
|
|
}
|
|
|
|
|
|
|
|
_mixin struct { usize start, end; } slice_sted(const slice_t*pIN slice)
|
|
|
|
{
|
|
|
|
return (var(slice_sted(NULL))){
|
|
|
|
.start = slice_start(slice),
|
|
|
|
.end = slice_end(slice),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// Format string for slices
|
|
|
|
#define SLICE_FORMAT "%lu..%lu"
|
|
|
|
// Expects a pointer to a `slice_t`
|
|
|
|
#define SLICE_FORMAT_ARGS(slice) slice_start(slice), slice_end(slice)
|
|
|
|
|
|
|
|
#define SLICE_STR_MAX_SIZE 42lu
|
|
|
|
usize slice_strn(const slice_t*pIN slice, usize len, char str[static pOUT len]);
|
|
|
|
usize slice_str_sz(const slice_t*pIN slice);
|
|
|
|
// Pointer returned from this function is TLS static and will change on each call.
|
|
|
|
const char* slice_strs(const slice_t*pIN slice);
|
|
|
|
// Pointer returned from this function must be free'd
|
|
|
|
char* slice_str(const slice_t*pIN slice);
|
|
|
|
|
|
|
|
#endif /* _SLICE_H */
|