Created
July 9, 2023 21:43
-
-
Save imaami/552127d1d9b22ecd0c4e4158fd17c196 to your computer and use it in GitHub Desktop.
Testing optimization levels
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <errno.h> | |
#include <limits.h> | |
#include <stdbool.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#define stringify_(x) #x | |
#define stringify(x) stringify_(x) | |
#if defined __GNUC__ && !defined __clang__ | |
# define ligma_gcc(...) _Pragma(stringify_(GCC __VA_ARGS__)) | |
#else | |
# define ligma_gcc(...) | |
#endif | |
#define force_inline __attribute__((always_inline)) static inline | |
/** | |
* @brief dstr stands for dumb string. | |
*/ | |
typedef struct dstr | |
{ | |
_Alignas(char *) union | |
{ | |
struct __attribute__((packed)) | |
{ | |
union { | |
char *ptr; //!< String pointer. | |
char const *view; //!< String view. | |
}; | |
unsigned int size; //!< Total heap allocation size. | |
}; | |
char arr[sizeof(char *) + sizeof(unsigned int)]; //!< Array. | |
}; | |
unsigned int len; //!< String length excluding the null terminator. | |
} dstr; | |
#define dstr_get(s_) (__typeof__((s_)->arr[0]) *) \ | |
{ !dstr_is_pointer(s_) ? (s_)->arr : (s_)->ptr } | |
#define is_char_array(x) \ | |
_Generic((__typeof__(x) *){0}, \ | |
char (*)[sizeof(x)]: 1, \ | |
char const (*)[sizeof(x)]: 1, \ | |
default: 0) | |
#define is_string_literal(x) \ | |
__builtin_choose_expr(is_char_array(x), __builtin_constant_p(x), 0) | |
#define safe_string_literal(lit, what) \ | |
__builtin_choose_expr( \ | |
is_string_literal(lit) && sizeof(lit) <= sizeof(what), \ | |
lit, "") | |
#define make_dstr_view_from_literal(src) \ | |
__builtin_choose_expr( \ | |
sizeof(src) <= sizeof(((dstr *)0)->arr), \ | |
(dstr){.arr = {safe_string_literal(src, ((dstr*)0)->arr)}, \ | |
.len = sizeof(src) - 1u}, \ | |
(dstr){.view = src, .size = 0u, .len = sizeof(src) - 1u}) | |
#define make_dstr_view_from_array(src) \ | |
__builtin_choose_expr( \ | |
sizeof(src) <= sizeof(((dstr *)0)->arr), \ | |
make_dstr_from_small_string(src, sizeof(src) - 1u), \ | |
(dstr){.view = src, .size = 0u, .len = sizeof(src) - 1u}) | |
#define make_dstr_view(src) \ | |
__builtin_choose_expr( \ | |
is_string_literal(src), \ | |
make_dstr_view_from_literal(src), \ | |
__builtin_choose_expr( \ | |
is_char_array(src), \ | |
make_dstr_view_from_array(src), \ | |
make_dstr_view_from_decay(src, strlen(src)))) | |
force_inline dstr | |
make_dstr_from_small_string (char const *const src, | |
size_t len) | |
{ | |
dstr d = {.arr = {0}, .len = (unsigned)len}; | |
__builtin_memcpy(&d.arr[0], src, len); | |
return d; | |
} | |
force_inline dstr | |
make_dstr_view_from_decay (char const *const src, | |
size_t len) | |
{ | |
ligma_gcc(diagnostic push) | |
ligma_gcc(diagnostic ignored "-Wstringop-overflow") | |
return !len || len > UINT_MAX - 1u | |
? (dstr){0} | |
: len < sizeof(((dstr *)0)->arr) | |
? make_dstr_from_small_string(src, len) | |
: (dstr){.view = src, .size = 0u, .len = (unsigned)len}; | |
ligma_gcc(diagnostic pop) | |
} | |
force_inline bool | |
dstr_is_empty (dstr const *s) | |
{ | |
return !s->len; | |
} | |
force_inline bool | |
dstr_is_array (dstr const *s) | |
{ | |
return s->len && s->len < sizeof s->arr; | |
} | |
force_inline bool | |
dstr_is_pointer (dstr const *s) | |
{ | |
return s->len >= sizeof s->arr; | |
} | |
force_inline bool | |
dstr_owns_memory (dstr const *s) | |
{ | |
return dstr_is_pointer(s) && s->size; | |
} | |
force_inline void | |
dstr_init (dstr *s) | |
{ | |
s->ptr = NULL; | |
s->size = 0u; | |
s->len = 0u; | |
} | |
force_inline void | |
dstr_fini (dstr *s) | |
{ | |
if (dstr_owns_memory(s)) | |
free(s->ptr); | |
dstr_init(s); | |
} | |
void test (void) | |
{ | |
dstr s = make_dstr_view("short string"); | |
puts(dstr_get(&s)); | |
dstr_fini(&s); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment