diff options
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_ |