/* * Copyright (C) 2024 Mikhail Burakov. This file is part of streamer. * * streamer is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * streamer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with streamer. If not, see . */ #ifndef STREAMER_UTIL_H_ #define STREAMER_UTIL_H_ #define STR_IMPL(x) #x #define STR(x) STR_IMPL(x) #define FROM_HERE __FILE__ ":" STR(__LINE__) " " template struct Defer { Defer(T&& op) : op_{op} {} ~Defer() { op_(); } const T& op_; }; template Defer(T&&) -> Defer; template 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 struct ClassOf; template struct ClassOf { using T = C; }; template inline auto Trampoline(T* head, Args... tail) { using C = ClassOf::T; auto self = static_cast(head); return (self->*fun)(tail...); } #endif // STREAMER_UTIL_H_