/* Heap-allocation free & small memory footprint * std::function alternative with limited capabilities. */ // single-header library /* Copyright (c) 2026 dyknon * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the " Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice * (including the next paragraph) shall be included in all copies * or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifndef INC_THINFUNC_H #define INC_THINFUNC_H namespace tf{ template struct func; template struct func{ virtual R operator()(Args...) const = 0; }; template class anchor; template class bound_anchor; template class anchor{ friend T; public: template (T::*Self), R (T::*Method)(Args...)> using bound_type = bound_anchor (T::*), R (T::*)(Args...), Self, Method>; private: alignas(bound_type) char body[sizeof(bound_type)]; protected: template (T::*Self), R (T::*Method)(Args...)> auto& bind(){ static_assert(sizeof(bound_type) == sizeof(body)); static_assert( (func *)(bound_type *)nullptr == (func *)(bound_type *)nullptr); return *(new (body) bound_type()); } public: template (T::*Self), R (T::*Method)(Args...)> auto& bound(){ return *(bound_type *)body; } func& bound(){ return *(func *)(bound_type *)body; } anchor(const anchor&) = delete; anchor(const anchor&&) = delete; anchor& operator=(const anchor&) = delete; anchor& operator=(const anchor&&) = delete; anchor() = default; }; template< class T, class R, class... Args, anchor (T::*Self), R (T::*Method)(Args...) > class bound_anchor (T::*), R (T::*)(Args...), Self, Method >: public func{ public: bound_anchor(){} bound_anchor(const bound_anchor&) = delete; bound_anchor(const bound_anchor&&) = delete; bound_anchor& operator=(const bound_anchor&) = delete; bound_anchor& operator=(const bound_anchor&&) = delete; virtual R operator()(Args... args) const{ auto offset = (char *)&(((T *)0)->*Self) - (char *)0; T *container = (T *)((char *)this - offset); return (container->*Method)(args...); } }; } // namespace rf #endif //INC_THINFUNC_H