diff options
Diffstat (limited to 'include/stc/ccommon.h')
| -rw-r--r-- | include/stc/ccommon.h | 112 |
1 files changed, 61 insertions, 51 deletions
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 38dc2bd9..1f9ea80d 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -29,18 +29,11 @@ #include <stdbool.h> #include <string.h> #include <assert.h> -#include "priv/altnames.h" -#include "priv/raii.h" typedef long long _llong; #define c_NPOS INTPTR_MAX #define c_ZI PRIiPTR #define c_ZU PRIuPTR -#if defined STC_NDEBUG || defined NDEBUG - #define c_ASSERT(expr) (void)(0) -#else - #define c_ASSERT(expr) assert(expr) -#endif #if defined(_MSC_VER) #pragma warning(disable: 4116 4996) // unnamed type definition in parentheses @@ -64,7 +57,7 @@ typedef long long _llong; #define _c_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \ _14, _15, _16, N, ...) N -#ifdef __cplusplus +#ifdef __cplusplus #include <new> #define _i_alloc(T) static_cast<T*>(i_malloc(c_sizeof(T))) #define _i_new(T, ...) new (_i_alloc(T)) T(__VA_ARGS__) @@ -76,27 +69,35 @@ typedef long long _llong; #define c_new(T, ...) ((T*)memcpy(malloc(sizeof(T)), ((T[]){__VA_ARGS__}), sizeof(T))) #define c_LITERAL(T) (T) #endif +#define c_new_n(T, n) ((T*)malloc(sizeof(T)*(n))) #define c_malloc(sz) malloc(c_i2u(sz)) #define c_calloc(n, sz) calloc(c_i2u(n), c_i2u(sz)) #define c_realloc(p, sz) realloc(p, c_i2u(sz)) #define c_free(p) free(p) #define c_delete(T, ptr) do { T *_tp = ptr; T##_drop(_tp); free(_tp); } while (0) -#define c_static_assert(b) ((int)(0*sizeof(int[(b) ? 1 : -1]))) +#define c_static_assert(...) c_MACRO_OVERLOAD(c_static_assert, __VA_ARGS__) +#define c_static_assert_1(b) ((int)(0*sizeof(int[(b) ? 1 : -1]))) +#define c_static_assert_2(b, m) c_static_assert_1(b) +#if defined STC_NDEBUG || defined NDEBUG + #define c_assert(expr) ((void)0) +#else + #define c_assert(expr) assert(expr) +#endif #define c_container_of(p, C, m) ((C*)((char*)(1 ? (p) : &((C*)0)->m) - offsetof(C, m))) -#define c_const_cast(T, p) ((T)(p) + 0*sizeof((T)0 == (p))) +#define c_const_cast(T, p) ((T)(1 ? (p) : (T)0)) #define c_swap(T, xp, yp) do { T *_xp = xp, *_yp = yp, \ _tv = *_xp; *_xp = *_yp; *_yp = _tv; } while (0) #define c_sizeof (intptr_t)sizeof #define c_strlen(s) (intptr_t)strlen(s) + #define c_strncmp(a, b, ilen) strncmp(a, b, c_i2u(ilen)) #define c_memcpy(d, s, ilen) memcpy(d, s, c_i2u(ilen)) #define c_memmove(d, s, ilen) memmove(d, s, c_i2u(ilen)) #define c_memset(d, val, ilen) memset(d, val, c_i2u(ilen)) #define c_memcmp(a, b, ilen) memcmp(a, b, c_i2u(ilen)) - -#define c_u2i(u) ((intptr_t)((u) + 0*sizeof((u) == 1U))) -#define c_i2u(i) ((size_t)(i) + 0*sizeof((i) == 1)) +#define c_u2i(u) ((intptr_t)(1 ? (u) : (size_t)1)) +#define c_i2u(i) ((size_t)(1 ? (i) : (intptr_t)1)) #define c_LTu(a, b) ((size_t)(a) < (size_t)(b)) // x and y are i_keyraw* type, defaults to i_key*: @@ -116,13 +117,10 @@ typedef long long _llong; #define c_no_clone (1<<2) #define c_no_emplace (1<<3) #define c_no_cmp (1<<4) -#define c_no_hash (1<<5) - +#define c_native_cmp (1<<5) +#define c_no_hash (1<<6) /* Function macros and others */ -#define c_make(C, ...) \ - C##_from_n((C##_raw[])__VA_ARGS__, c_sizeof((C##_raw[])__VA_ARGS__)/c_sizeof(C##_raw)) - #define c_litstrlen(literal) (c_sizeof("" literal) - 1) #define c_arraylen(a) (intptr_t)(sizeof(a)/sizeof 0[a]) @@ -148,14 +146,14 @@ STC_INLINE uint64_t cfasthash(const void* key, intptr_t len) { case 0: return 1; } const uint8_t *x = (const uint8_t*)key; - uint64_t h = *x, n = (uint64_t)len >> 3; + uint64_t h = (uint64_t)*x << 7, n = (uint64_t)len >> 3; len &= 7; while (n--) { memcpy(&u8, x, 8), x += 8; - h += u8*0xc6a4a7935bd1e99d; + h = (h ^ u8)*0xc6a4a7935bd1e99d; } - while (len--) h = (h << 10) - h - *x++; - return c_ROTL(h, 26) ^ h; + while (len--) h = (h ^ *x++)*0x100000001b3; + return h ^ c_ROTL(h, 26); } STC_INLINE uint64_t cstrhash(const char *str) @@ -174,6 +172,16 @@ STC_INLINE char* cstrnstrn(const char *str, const char *needle, return NULL; } +STC_INLINE intptr_t cnextpow2(intptr_t n) { + n--; + n |= n >> 1, n |= n >> 2; + n |= n >> 4, n |= n >> 8; + n |= n >> 16; + #if INTPTR_MAX == INT64_MAX + n |= n >> 32; + #endif + return n + 1; +} /* Control block macros */ #define c_foreach(...) c_MACRO_OVERLOAD(c_foreach, __VA_ARGS__) @@ -196,44 +204,46 @@ STC_INLINE char* cstrnstrn(const char *str, const char *needle, #define c_forrange_1(stop) c_forrange_3(_c_i, 0, stop) #define c_forrange_2(i, stop) c_forrange_3(i, 0, stop) #define c_forrange_3(i, start, stop) \ - for (long long i=start, _end=(long long)(stop); i < _end; ++i) + for (_llong i=start, _end=(_llong)(stop); i < _end; ++i) #define c_forrange_4(i, start, stop, step) \ - for (long long i=start, _inc=step, _end=(long long)(stop) - (_inc > 0) \ + for (_llong i=start, _inc=step, _end=(_llong)(stop) - (_inc > 0) \ ; (_inc > 0) ^ (i > _end); i += _inc) #ifndef __cplusplus + #define c_init(C, ...) \ + C##_from_n((C##_raw[])__VA_ARGS__, c_sizeof((C##_raw[])__VA_ARGS__)/c_sizeof(C##_raw)) #define c_forlist(it, T, ...) \ - for (struct {T* ref; int size, index;} \ - it = {.ref=(T[])__VA_ARGS__, .size=(int)(sizeof((T[])__VA_ARGS__)/sizeof(T))} \ - ; it.index < it.size; ++it.ref, ++it.index) + for (struct {T* ref; int size, index;} \ + it = {.ref=(T[])__VA_ARGS__, .size=(int)(sizeof((T[])__VA_ARGS__)/sizeof(T))} \ + ; it.index < it.size; ++it.ref, ++it.index) #else - #include <initializer_list> - #define c_forlist(it, T, ...) \ - for (struct {std::initializer_list<T> _il; std::initializer_list<T>::iterator data, ref; size_t size, index;} \ - it = {._il=__VA_ARGS__, .data=it._il.begin(), .ref=it.data, .size=it._il.size()} \ - ; it.index < it.size; ++it.ref, ++it.index) + #include <initializer_list> + template <class C, class T> + inline C _from_n(C (*func)(const T[], intptr_t), std::initializer_list<T> il) + { return func(&*il.begin(), il.size()); } + + #define c_init(C, ...) _from_n<C,C##_raw>(C##_from_n, __VA_ARGS__) + #define c_forlist(it, T, ...) \ + for (struct {std::initializer_list<T> _il; std::initializer_list<T>::iterator ref; size_t size, index;} \ + it = {._il=__VA_ARGS__, .ref=it._il.begin(), .size=it._il.size()} \ + ; it.index < it.size; ++it.ref, ++it.index) #endif +#define c_defer(...) \ + for (int _i = 1; _i; _i = 0, __VA_ARGS__) #define c_drop(C, ...) \ do { c_forlist (_i, C*, {__VA_ARGS__}) C##_drop(*_i.ref); } while(0) -#endif // CCOMMON_H_INCLUDED - -#undef STC_API -#undef STC_DEF - -#if !defined(i_static) && !defined(STC_STATIC) && (defined(i_header) || defined(STC_HEADER) || \ - defined(i_implement) || defined(STC_IMPLEMENT)) - #define STC_API extern - #define STC_DEF -#else - #define i_static - #define STC_API static inline - #define STC_DEF static inline -#endif -#if defined(STC_EXTERN) - #define i_extern -#endif -#if defined(i_static) || defined(STC_IMPLEMENT) - #define i_implement +#if defined(__SIZEOF_INT128__) + #define c_umul128(a, b, lo, hi) \ + do { __uint128_t _z = (__uint128_t)(a)*(b); \ + *(lo) = (uint64_t)_z, *(hi) = (uint64_t)(_z >> 64U); } while(0) +#elif defined(_MSC_VER) && defined(_WIN64) + #include <intrin.h> + #define c_umul128(a, b, lo, hi) ((void)(*(lo) = _umul128(a, b, hi))) +#elif defined(__x86_64__) + #define c_umul128(a, b, lo, hi) \ + asm("mulq %3" : "=a"(*(lo)), "=d"(*(hi)) : "a"(a), "rm"(b)) #endif + +#endif // CCOMMON_H_INCLUDED |
