57 #ifndef SLICE99_ASSERT
60 #define SLICE99_ASSERT assert
63 #ifndef SLICE99_MEMCMP
66 #define SLICE99_MEMCMP memcmp
69 #ifndef SLICE99_MEMCPY
72 #define SLICE99_MEMCPY memcpy
75 #ifndef SLICE99_MEMMOVE
78 #define SLICE99_MEMMOVE memmove
81 #ifndef SLICE99_STRLEN
84 #define SLICE99_STRLEN strlen
87 #ifndef DOXYGEN_IGNORE
90 #define SLICE99_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
92 #define SLICE99_WARN_UNUSED_RESULT
95 #if defined(__GNUC__) && !defined(__clang__)
97 #define SLICE99_CONST __attribute__((const))
98 #define SLICE99_PURE __attribute__((pure))
99 #define SLICE99_ALWAYS_INLINE __attribute__((always_inline))
100 #define SLICE99_FORMAT_HINT(archetype, string_idx, first_to_check) \
101 __attribute__((format(archetype, string_idx, first_to_check)))
105 #define SLICE99_CONST
107 #define SLICE99_ALWAYS_INLINE
108 #define SLICE99_FORMAT_HINT(_archetype, _string_idx, _first_to_check)
117 #define SLICE99_MAJOR 0
122 #define SLICE99_MINOR 7
127 #define SLICE99_PATCH 7
174 #define SLICE99_DEF_TYPED(name, T) \
180 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT name name##_new( \
181 T *ptr, size_t len) { \
182 const Slice99 result = Slice99_new((void *)ptr, sizeof(T), len); \
183 return (name)SLICE99_TO_TYPED(result); \
186 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT name name##_from_ptrdiff( \
187 T *start, T *end) { \
188 const Slice99 result = Slice99_from_ptrdiff((void *)start, (void *)end, sizeof(T)); \
189 return (name)SLICE99_TO_TYPED(result); \
192 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT name name##_empty(void) { \
193 const Slice99 result = Slice99_empty(sizeof(T)); \
194 return (name)SLICE99_TO_TYPED(result); \
197 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT name name##_update_len( \
198 name self, size_t new_len) { \
199 const Slice99 result = Slice99_update_len(SLICE99_TO_UNTYPED(self), new_len); \
200 return (name)SLICE99_TO_TYPED(result); \
203 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT \
204 SLICE99_CONST bool name##_is_empty(name self) { \
205 return Slice99_is_empty(SLICE99_TO_UNTYPED(self)); \
208 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT SLICE99_CONST size_t \
209 name##_size(name self) { \
210 return Slice99_size(SLICE99_TO_UNTYPED(self)); \
213 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT SLICE99_CONST T *name##_get( \
214 name self, ptrdiff_t i) { \
215 return (T *)Slice99_get(SLICE99_TO_UNTYPED(self), i); \
218 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT SLICE99_CONST T *name##_first( \
220 return (T *)Slice99_first(SLICE99_TO_UNTYPED(self)); \
223 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT SLICE99_CONST T *name##_last( \
225 return (T *)Slice99_last(SLICE99_TO_UNTYPED(self)); \
228 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT name name##_sub( \
229 name self, ptrdiff_t start_idx, ptrdiff_t end_idx) { \
230 const Slice99 result = Slice99_sub(SLICE99_TO_UNTYPED(self), start_idx, end_idx); \
231 return (name)SLICE99_TO_TYPED(result); \
234 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT name name##_advance( \
235 name self, ptrdiff_t offset) { \
236 const Slice99 result = Slice99_advance(SLICE99_TO_UNTYPED(self), offset); \
237 return (name)SLICE99_TO_TYPED(result); \
240 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT bool name##_primitive_eq( \
241 name lhs, name rhs) { \
242 return Slice99_primitive_eq(SLICE99_TO_UNTYPED(lhs), SLICE99_TO_UNTYPED(rhs)); \
245 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT bool name##_eq( \
246 name lhs, name rhs, int (*cmp)(const T *, const T *)) { \
248 SLICE99_TO_UNTYPED(lhs), SLICE99_TO_UNTYPED(rhs), \
249 (int (*)(const void *, const void *))cmp); \
252 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT bool \
253 name##_primitive_starts_with(name self, name prefix) { \
254 return Slice99_primitive_starts_with( \
255 SLICE99_TO_UNTYPED(self), SLICE99_TO_UNTYPED(prefix)); \
258 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT bool name##_starts_with( \
259 name self, name prefix, int (*cmp)(const T *, const T *)) { \
260 return Slice99_starts_with( \
261 SLICE99_TO_UNTYPED(self), SLICE99_TO_UNTYPED(prefix), \
262 (int (*)(const void *, const void *))cmp); \
265 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT bool \
266 name##_primitive_ends_with(name self, name postfix) { \
267 return Slice99_primitive_ends_with(SLICE99_TO_UNTYPED(self), SLICE99_TO_UNTYPED(postfix)); \
270 inline static SLICE99_ALWAYS_INLINE SLICE99_WARN_UNUSED_RESULT bool name##_ends_with( \
271 name self, name postfix, int (*cmp)(const T *, const T *)) { \
272 return Slice99_ends_with( \
273 SLICE99_TO_UNTYPED(self), SLICE99_TO_UNTYPED(postfix), \
274 (int (*)(const void *, const void *))cmp); \
277 inline static SLICE99_ALWAYS_INLINE void name##_copy(name self, name other) { \
278 Slice99_copy(SLICE99_TO_UNTYPED(self), SLICE99_TO_UNTYPED(other)); \
281 inline static SLICE99_ALWAYS_INLINE void name##_copy_non_overlapping(name self, name other) { \
282 Slice99_copy_non_overlapping(SLICE99_TO_UNTYPED(self), SLICE99_TO_UNTYPED(other)); \
285 inline static SLICE99_ALWAYS_INLINE void name##_swap( \
286 name self, ptrdiff_t lhs, ptrdiff_t rhs, T *restrict backup) { \
287 Slice99_swap(SLICE99_TO_UNTYPED(self), lhs, rhs, (void *restrict)backup); \
290 inline static SLICE99_ALWAYS_INLINE void name##_swap_with_slice( \
291 name self, name other, T *restrict backup) { \
292 Slice99_swap_with_slice( \
293 SLICE99_TO_UNTYPED(self), SLICE99_TO_UNTYPED(other), (void *restrict)backup); \
296 inline static SLICE99_ALWAYS_INLINE void name##_reverse(name self, T *restrict backup) { \
297 Slice99_reverse(SLICE99_TO_UNTYPED(self), (void *restrict)backup); \
300 inline static SLICE99_ALWAYS_INLINE void name##_split_at( \
301 name self, size_t i, name *restrict lhs, name *restrict rhs) { \
302 SLICE99_ASSERT(lhs); \
303 SLICE99_ASSERT(rhs); \
305 Slice99 lhs_untyped = SLICE99_TO_UNTYPED(*lhs), rhs_untyped = SLICE99_TO_UNTYPED(*rhs); \
307 Slice99_split_at(SLICE99_TO_UNTYPED(self), i, &lhs_untyped, &rhs_untyped); \
309 *lhs = (name)SLICE99_TO_TYPED(lhs_untyped); \
310 *rhs = (name)SLICE99_TO_TYPED(rhs_untyped); \
313 struct slice99_priv_trailing_comma
332 #define SLICE99_TO_TYPED(self) \
333 { .ptr = (self).ptr, .len = (self).len }
352 #define SLICE99_TO_UNTYPED(self) Slice99_new((self).ptr, sizeof(*(self).ptr), (self).len)
357 #define SLICE99_ARRAY_LEN(...) (sizeof(__VA_ARGS__) / sizeof((__VA_ARGS__)[0]))
384 #define SLICE99_APPEND(buffer, obj) \
385 ((void *)((char *)SLICE99_MEMCPY((buffer), &(obj), sizeof(obj)) + sizeof(obj)))
393 #define SLICE99_APPEND_ARRAY(buffer, ptr, len) \
395 ((void *)((char *)SLICE99_MEMCPY((buffer), (ptr), sizeof((ptr)[0]) * (len)) + \
396 sizeof((ptr)[0]) * (len)))
407 #define SLICE99_TO_OCTETS(obj) U8Slice99_new((uint8_t *)&(obj), sizeof(obj))
417 #define Slice99_from_array(...) \
418 Slice99_new((void *)(__VA_ARGS__), sizeof((__VA_ARGS__)[0]), SLICE99_ARRAY_LEN(__VA_ARGS__))
434 #define Slice99_typed_from_array(...) \
435 { .ptr = (__VA_ARGS__), .len = SLICE99_ARRAY_LEN(__VA_ARGS__) }
445 #define Slice99_from_typed_ptr(ptr, len) Slice99_new(ptr, sizeof(*(ptr)), len)
482 inline static SLICE99_WARN_UNUSED_RESULT
Slice99
487 return (
Slice99){.ptr = ptr, .item_size = item_size, .len = len};
515 inline static SLICE99_WARN_UNUSED_RESULT
Slice99
520 const ptrdiff_t diff = (
char *)end - (
char *)start;
525 return Slice99_new(start, item_size, (
size_t)(diff / (ptrdiff_t)item_size));
547 return Slice99_new(
self.ptr,
self.item_size, new_len);
558 return self.len == 0;
567 return self.item_size *
self.len;
578 inline static SLICE99_WARN_UNUSED_RESULT SLICE99_CONST
void *
580 return (
void *)((
char *)
self.ptr + i * (ptrdiff_t)
self.item_size);
614 inline static SLICE99_WARN_UNUSED_RESULT
Slice99
634 return Slice99_sub(
self, offset, (ptrdiff_t)
self.len);
665 inline static SLICE99_WARN_UNUSED_RESULT
bool
674 for (ptrdiff_t i = 0; i < (ptrdiff_t)lhs.
len; i++) {
693 inline static SLICE99_WARN_UNUSED_RESULT
bool
714 inline static SLICE99_WARN_UNUSED_RESULT
bool
719 return self.len < prefix.
len
734 inline static SLICE99_WARN_UNUSED_RESULT
bool
740 self, (ptrdiff_t)
self.len - (ptrdiff_t)postfix.
len, (ptrdiff_t)
self.len),
758 inline static SLICE99_WARN_UNUSED_RESULT
bool
763 return self.len < postfix.
len
767 self, (ptrdiff_t)
self.len - (ptrdiff_t)postfix.
len, (ptrdiff_t)
self.len),
827 for (ptrdiff_t i = 0; i < (ptrdiff_t)
self.len; i++) {
846 for (ptrdiff_t i = 0; i < (ptrdiff_t)
self.len / 2; i++) {
847 Slice99_swap(
self, i, (ptrdiff_t)
self.len - i - 1, backup);
871 *rhs =
Slice99_sub(
self, (ptrdiff_t)i, (ptrdiff_t)
self.len);
970 #define CharSlice99_alloca_c_str(self) CharSlice99_c_str((self), alloca((self).len + 1))
972 #ifndef SLICE99_DISABLE_STDIO
974 #ifndef SLICE99_VSPRINTF
978 #define SLICE99_VSPRINTF vsprintf
981 #ifndef SLICE99_VSNPRINTF
985 #define SLICE99_VSNPRINTF vsnprintf
988 #ifndef SLICE99_SNPRINTF
992 #define SLICE99_SNPRINTF snprintf
995 #ifndef DOXYGEN_IGNORE
999 #define SLICE99_FORMAT_HINT_2_0 SLICE99_FORMAT_HINT(printf, 2, 0)
1000 #define SLICE99_FORMAT_HINT_2_3 SLICE99_FORMAT_HINT(printf, 2, 3)
1001 #define SLICE99_FORMAT_HINT_3_0 SLICE99_FORMAT_HINT(printf, 3, 0)
1002 #define SLICE99_FORMAT_HINT_3_4 SLICE99_FORMAT_HINT(printf, 3, 4)
1021 inline static SLICE99_WARN_UNUSED_RESULT SLICE99_FORMAT_HINT_2_0 CharSlice99
1035 inline static SLICE99_WARN_UNUSED_RESULT SLICE99_FORMAT_HINT_2_3 CharSlice99
1049 inline static SLICE99_WARN_UNUSED_RESULT SLICE99_FORMAT_HINT_3_0 CharSlice99
1060 inline static SLICE99_WARN_UNUSED_RESULT SLICE99_FORMAT_HINT_3_4 CharSlice99
1069 #ifndef DOXYGEN_IGNORE
1071 #undef SLICE99_FORMAT_HINT_2_0
1072 #undef SLICE99_FORMAT_HINT_2_3
1073 #undef SLICE99_FORMAT_HINT_3_0
1074 #undef SLICE99_FORMAT_HINT_3_4
1086 #define CharSlice99_alloca_fmt(fmt, ...) \
1087 CharSlice99_fmt(alloca(SLICE99_SNPRINTF(NULL, 0, (fmt), __VA_ARGS__) + 1), (fmt), __VA_ARGS__)
#define SLICE99_VSPRINTF
Like vsprintf.
Definition: slice99.h:978
static SLICE99_WARN_UNUSED_RESULT SLICE99_FORMAT_HINT_2_3 CharSlice99 CharSlice99_fmt(char out[restrict], const char *restrict fmt,...)
The CharSlice99_vfmt twin.
Definition: slice99.h:1036
static SLICE99_WARN_UNUSED_RESULT Slice99 Slice99_update_len(Slice99 self, size_t new_len)
Updates self with the new length new_len.
Definition: slice99.h:546
static void Slice99_swap(Slice99 self, ptrdiff_t lhs, ptrdiff_t rhs, void *restrict backup)
Swaps the lhs -indexed and rhs -indexed items.
Definition: slice99.h:802
static SLICE99_WARN_UNUSED_RESULT SLICE99_CONST void * Slice99_last(Slice99 self)
Computes a pointer to the last item.
Definition: slice99.h:599
static SLICE99_WARN_UNUSED_RESULT CharSlice99 CharSlice99_from_str(char *str)
The same as Slice99_from_str.
Definition: slice99.h:953
static void Slice99_split_at(Slice99 self, size_t i, Slice99 *restrict lhs, Slice99 *restrict rhs)
Splits self into two parts.
Definition: slice99.h:865
#define SLICE99_ASSERT
Like assert.
Definition: slice99.h:60
static SLICE99_WARN_UNUSED_RESULT SLICE99_CONST size_t Slice99_size(Slice99 self)
Computes a total size in bytes.
Definition: slice99.h:566
static SLICE99_WARN_UNUSED_RESULT bool Slice99_ends_with(Slice99 self, Slice99 postfix, int(*cmp)(const void *, const void *))
Checks whether postfix is a postfix of self with a user-supplied comparator.
Definition: slice99.h:759
#define SLICE99_TO_TYPED(self)
Converts Slice99 to a typed representation.
Definition: slice99.h:332
static SLICE99_WARN_UNUSED_RESULT Slice99 Slice99_new(void *ptr, size_t item_size, size_t len)
Constructs a slice.
Definition: slice99.h:483
#define SLICE99_MEMCMP
Like memcmp.
Definition: slice99.h:66
static SLICE99_WARN_UNUSED_RESULT bool Slice99_primitive_starts_with(Slice99 self, Slice99 prefix)
Checks whether prefix is a prefix of self, byte-by-byte.
Definition: slice99.h:694
static SLICE99_WARN_UNUSED_RESULT SLICE99_FORMAT_HINT_2_0 CharSlice99 CharSlice99_vfmt(char out[restrict], const char *restrict fmt, va_list list)
Prints a formatted string to out and returns the corresponding character slice.
Definition: slice99.h:1022
static void Slice99_reverse(Slice99 self, void *restrict backup)
Reverses the order of items in self.
Definition: slice99.h:843
#define SLICE99_DEF_TYPED(name, T)
Defines the strongly typed slice name containing items of type T.
Definition: slice99.h:174
static void Slice99_swap_with_slice(Slice99 self, Slice99 other, void *restrict backup)
Swaps all the items in self with those in other.
Definition: slice99.h:823
#define SLICE99_VSNPRINTF
Like vsnprintf.
Definition: slice99.h:985
#define SLICE99_MEMCPY
Like memcpy.
Definition: slice99.h:72
#define SLICE99_STRLEN
Like strlen.
Definition: slice99.h:84
static SLICE99_WARN_UNUSED_RESULT bool Slice99_primitive_eq(Slice99 lhs, Slice99 rhs)
Performs a byte-by-byte comparison of lhs with rhs.
Definition: slice99.h:645
static char * CharSlice99_c_str(CharSlice99 self, char out[restrict])
The same as Slice99_c_str.
Definition: slice99.h:960
static SLICE99_WARN_UNUSED_RESULT Slice99 Slice99_from_str(char *str)
Constructs a slice from str.
Definition: slice99.h:497
static SLICE99_WARN_UNUSED_RESULT SLICE99_CONST void * Slice99_get(Slice99 self, ptrdiff_t i)
Computes a pointer to the i -indexed item.
Definition: slice99.h:579
static SLICE99_WARN_UNUSED_RESULT SLICE99_FORMAT_HINT_3_0 CharSlice99 CharSlice99_vnfmt(char out[restrict], size_t bufsz, const char *restrict fmt, va_list list)
The same as CharSlice99_vfmt but writes at most bufsz - 1 characters.
Definition: slice99.h:1050
#define SLICE99_TO_UNTYPED(self)
Converts the typed slice self to Slice99.
Definition: slice99.h:352
static SLICE99_WARN_UNUSED_RESULT bool Slice99_eq(Slice99 lhs, Slice99 rhs, int(*cmp)(const void *, const void *))
Performs a comparison of lhs with rhs with a user-supplied comparator.
Definition: slice99.h:666
static SLICE99_WARN_UNUSED_RESULT bool Slice99_starts_with(Slice99 self, Slice99 prefix, int(*cmp)(const void *, const void *))
Checks whether prefix is a prefix of self with a user-supplied comparator.
Definition: slice99.h:715
static SLICE99_WARN_UNUSED_RESULT Slice99 Slice99_advance(Slice99 self, ptrdiff_t offset)
Advances self by offset items.
Definition: slice99.h:633
static SLICE99_WARN_UNUSED_RESULT SLICE99_CONST void * Slice99_first(Slice99 self)
Computes a pointer to the first item.
Definition: slice99.h:588
static char * Slice99_c_str(Slice99 self, char out[restrict])
Copies self to out and appends '\0' to the end.
Definition: slice99.h:885
static void Slice99_copy_non_overlapping(Slice99 self, Slice99 other)
The same as Slice99_copy except that self and other must be non-overlapping.
Definition: slice99.h:786
static SLICE99_WARN_UNUSED_RESULT Slice99 Slice99_empty(size_t item_size)
Constructs an empty slice.
Definition: slice99.h:535
static SLICE99_WARN_UNUSED_RESULT bool Slice99_primitive_ends_with(Slice99 self, Slice99 postfix)
Checks whether postfix is a postfix of self, byte-by-byte.
Definition: slice99.h:735
static SLICE99_WARN_UNUSED_RESULT SLICE99_FORMAT_HINT_3_4 CharSlice99 CharSlice99_nfmt(char out[restrict], size_t bufsz, const char *restrict fmt,...)
The CharSlice99_vnfmt twin.
Definition: slice99.h:1061
static SLICE99_WARN_UNUSED_RESULT SLICE99_CONST bool Slice99_is_empty(Slice99 self)
Checks whether self is empty or not.
Definition: slice99.h:557
static void Slice99_copy(Slice99 self, Slice99 other)
Copies other to the beginning of self, byte-by-byte.
Definition: slice99.h:777
static SLICE99_WARN_UNUSED_RESULT Slice99 Slice99_from_ptrdiff(void *start, void *end, size_t item_size)
Constructs a slice residing between start (inclusively) and end (exclusively).
Definition: slice99.h:516
#define SLICE99_MEMMOVE
Like memmove.
Definition: slice99.h:78
static SLICE99_WARN_UNUSED_RESULT Slice99 Slice99_sub(Slice99 self, ptrdiff_t start_idx, ptrdiff_t end_idx)
Subslicing self with [start_idx .. end_idx].
Definition: slice99.h:615
A slice of some array.
Definition: slice99.h:455
void * ptr
The pointer to data.
Definition: slice99.h:459
size_t item_size
The size of each item in the array addressed by ptr.
Definition: slice99.h:464
size_t len
The count of items in the array addressed by ptr.
Definition: slice99.h:469