diff options
author | Mikhail Burakov <mburakov@mailbox.org> | 2024-11-18 06:34:31 +0100 |
---|---|---|
committer | Mikhail Burakov <mburakov@mailbox.org> | 2024-11-18 06:34:31 +0100 |
commit | 5be09d7edff924e7486d743e9d15edf07f555341 (patch) | |
tree | 064680d394732b0d1c00bfbbbb1ce3d5ed3d6e5e /util.h | |
parent | 8a93cfdc03683eedc270bae957288af853f22a61 (diff) |
WIPnext
Diffstat (limited to 'util.h')
-rw-r--r-- | util.h | 48 |
1 files changed, 41 insertions, 7 deletions
@@ -18,15 +18,49 @@ #ifndef STREAMER_UTIL_H_ #define STREAMER_UTIL_H_ -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) - -#define LENGTH(x) (sizeof(x) / sizeof *(x)) - #define STR_IMPL(x) #x #define STR(x) STR_IMPL(x) +#define FROM_HERE __FILE__ ":" STR(__LINE__) " " + +template <class T> +struct Defer { + Defer(T&& op) : op_{op} {} + ~Defer() { op_(); } + const T& op_; +}; + +template <class T> +Defer(T&&) -> Defer<T>; + +template <auto dflt, auto closer> +struct PodCloser { + struct pointer { + decltype(dflt) value_; + pointer() : value_{dflt} {} + pointer(decltype(nullptr)) : value_{dflt} {} + pointer(decltype(dflt) value) : value_{value} {} + explicit operator bool() const { return value_ != dflt; } + friend bool operator==(pointer, pointer) = default; + operator decltype(dflt)() const { return value_; } + }; + void operator()(const pointer ptr) { + if (ptr.value_ != dflt) closer(ptr.value_); + } +}; + +template <class T> +struct ClassOf; + +template <class R, class C> +struct ClassOf<R C::*> { + using T = C; +}; -#define LOG(x, ...) \ - fprintf(stderr, __FILE__ ":" STR(__LINE__) " " x "\n", ##__VA_ARGS__) +template <auto fun, class T, class... Args> +inline auto Trampoline(T* head, Args... tail) { + using C = ClassOf<decltype(fun)>::T; + auto self = static_cast<C*>(head); + return (self->*fun)(tail...); +} #endif // STREAMER_UTIL_H_ |