#pragma once template <class Function> struct strip_signature; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...)> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) const> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) volatile> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) const volatile> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) &> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) const &> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) volatile &> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) const volatile &> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) noexcept> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) const noexcept> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) volatile noexcept> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) const volatile noexcept> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) &noexcept> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) const &noexcept> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) volatile &noexcept> { using type = Return(Args...); }; template <class Return, class Class, class... Args> struct strip_signature<Return (Class::*)(Args...) const volatile &noexcept> { using type = Return(Args...); }; template <class Function> using strip_signature_t = typename strip_signature<Function>::type;