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 *)((char *)SLICE99_MEMCPY((buffer), (ptr), sizeof((ptr)[0]) * (len)) + sizeof((ptr)[0]) * (len)))
406 #define SLICE99_TO_OCTETS(obj) U8Slice99_new((uint8_t *)&(obj), sizeof(obj))
416 #define Slice99_from_array(...) \
417 Slice99_new((void *)(__VA_ARGS__), sizeof((__VA_ARGS__)[0]), SLICE99_ARRAY_LEN(__VA_ARGS__))
433 #define Slice99_typed_from_array(...) \
434 { .ptr = (__VA_ARGS__), .len = SLICE99_ARRAY_LEN(__VA_ARGS__) }
444 #define Slice99_from_typed_ptr(ptr, len) Slice99_new(ptr, sizeof(*(ptr)), len)
481 inline static SLICE99_WARN_UNUSED_RESULT
Slice99
486 return (
Slice99){.ptr = ptr, .item_size = item_size, .len = len};
514 inline static SLICE99_WARN_UNUSED_RESULT
Slice99
519 const ptrdiff_t diff = (
char *)end - (
char *)start;
524 return Slice99_new(start, item_size, (
size_t)(diff / (ptrdiff_t)item_size));
546 return Slice99_new(
self.ptr,
self.item_size, new_len);
557 return self.len == 0;
566 return self.item_size *
self.len;
577 inline static SLICE99_WARN_UNUSED_RESULT SLICE99_CONST
void *
579 return (
void *)((
char *)
self.ptr + i * (ptrdiff_t)
self.item_size);
613 inline static SLICE99_WARN_UNUSED_RESULT
Slice99
633 return Slice99_sub(
self, offset, (ptrdiff_t)
self.len);
664 inline static SLICE99_WARN_UNUSED_RESULT
bool
673 for (ptrdiff_t i = 0; i < (ptrdiff_t)lhs.
len; i++) {
692 inline static SLICE99_WARN_UNUSED_RESULT
bool
713 inline static SLICE99_WARN_UNUSED_RESULT
bool
718 return self.len < prefix.
len
733 inline static SLICE99_WARN_UNUSED_RESULT
bool
739 self, (ptrdiff_t)
self.len - (ptrdiff_t)postfix.
len, (ptrdiff_t)
self.len),
757 inline static SLICE99_WARN_UNUSED_RESULT
bool
762 return self.len < postfix.
len
766 self, (ptrdiff_t)
self.len - (ptrdiff_t)postfix.
len, (ptrdiff_t)
self.len),
826 for (ptrdiff_t i = 0; i < (ptrdiff_t)
self.len; i++) {
845 for (ptrdiff_t i = 0; i < (ptrdiff_t)
self.len / 2; i++) {
846 Slice99_swap(
self, i, (ptrdiff_t)
self.len - i - 1, backup);
870 *rhs =
Slice99_sub(
self, (ptrdiff_t)i, (ptrdiff_t)
self.len);
969 #define CharSlice99_alloca_c_str(self) CharSlice99_c_str((self), alloca((self).len + 1))
971 #ifndef SLICE99_DISABLE_STDIO
973 #ifndef SLICE99_VSPRINTF
977 #define SLICE99_VSPRINTF vsprintf
980 #ifndef SLICE99_VSNPRINTF
984 #define SLICE99_VSNPRINTF vsnprintf
987 #ifndef SLICE99_SNPRINTF
991 #define SLICE99_SNPRINTF snprintf
994 #ifndef DOXYGEN_IGNORE
998 #define SLICE99_FORMAT_HINT_2_0 SLICE99_FORMAT_HINT(printf, 2, 0)
999 #define SLICE99_FORMAT_HINT_2_3 SLICE99_FORMAT_HINT(printf, 2, 3)
1000 #define SLICE99_FORMAT_HINT_3_0 SLICE99_FORMAT_HINT(printf, 3, 0)
1001 #define SLICE99_FORMAT_HINT_3_4 SLICE99_FORMAT_HINT(printf, 3, 4)
1020 inline static SLICE99_WARN_UNUSED_RESULT SLICE99_FORMAT_HINT_2_0 CharSlice99
1034 inline static SLICE99_WARN_UNUSED_RESULT SLICE99_FORMAT_HINT_2_3 CharSlice99
1048 inline static SLICE99_WARN_UNUSED_RESULT SLICE99_FORMAT_HINT_3_0 CharSlice99
1059 inline static SLICE99_WARN_UNUSED_RESULT SLICE99_FORMAT_HINT_3_4 CharSlice99
1068 #ifndef DOXYGEN_IGNORE
1070 #undef SLICE99_FORMAT_HINT_2_0
1071 #undef SLICE99_FORMAT_HINT_2_3
1072 #undef SLICE99_FORMAT_HINT_3_0
1073 #undef SLICE99_FORMAT_HINT_3_4
1085 #define CharSlice99_alloca_fmt(fmt, ...) \
1086 CharSlice99_fmt(alloca(SLICE99_SNPRINTF(NULL, 0, (fmt), __VA_ARGS__) + 1), (fmt), __VA_ARGS__)
#define SLICE99_VSPRINTF
Like vsprintf.
Definition: slice99.h:977
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:1035
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:545
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:801
static SLICE99_WARN_UNUSED_RESULT SLICE99_CONST void * Slice99_last(Slice99 self)
Computes a pointer to the last item.
Definition: slice99.h:598
static SLICE99_WARN_UNUSED_RESULT CharSlice99 CharSlice99_from_str(char *str)
The same as Slice99_from_str.
Definition: slice99.h:952
static void Slice99_split_at(Slice99 self, size_t i, Slice99 *restrict lhs, Slice99 *restrict rhs)
Splits self into two parts.
Definition: slice99.h:864
#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:565
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:758
#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:482
#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:693
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:1021
static void Slice99_reverse(Slice99 self, void *restrict backup)
Reverses the order of items in self.
Definition: slice99.h:842
#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:822
#define SLICE99_VSNPRINTF
Like vsnprintf.
Definition: slice99.h:984
#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:644
static char * CharSlice99_c_str(CharSlice99 self, char out[restrict])
The same as Slice99_c_str.
Definition: slice99.h:959
static SLICE99_WARN_UNUSED_RESULT Slice99 Slice99_from_str(char *str)
Constructs a slice from str.
Definition: slice99.h:496
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:578
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:1049
#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:665
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:714
static SLICE99_WARN_UNUSED_RESULT Slice99 Slice99_advance(Slice99 self, ptrdiff_t offset)
Advances self by offset items.
Definition: slice99.h:632
static SLICE99_WARN_UNUSED_RESULT SLICE99_CONST void * Slice99_first(Slice99 self)
Computes a pointer to the first item.
Definition: slice99.h:587
static char * Slice99_c_str(Slice99 self, char out[restrict])
Copies self to out and appends '\0' to the end.
Definition: slice99.h:884
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:785
static SLICE99_WARN_UNUSED_RESULT Slice99 Slice99_empty(size_t item_size)
Constructs an empty slice.
Definition: slice99.h:534
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:734
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:1060
static SLICE99_WARN_UNUSED_RESULT SLICE99_CONST bool Slice99_is_empty(Slice99 self)
Checks whether self is empty or not.
Definition: slice99.h:556
static void Slice99_copy(Slice99 self, Slice99 other)
Copies other to the beginning of self, byte-by-byte.
Definition: slice99.h:776
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:515
#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:614
A slice of some array.
Definition: slice99.h:454
void * ptr
The pointer to data.
Definition: slice99.h:458
size_t item_size
The size of each item in the array addressed by ptr.
Definition: slice99.h:463
size_t len
The count of items in the array addressed by ptr.
Definition: slice99.h:468