#pragma once /* * Copyright (C) 2024 Brett Terpstra * * This program 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. * * This program 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 this program. If not, see . */ #ifndef BLT_META_H #define BLT_META_H #include #include #include #include namespace blt::meta { template, typename... IArgs> struct arg_helper { using First = IFirst; using Next = arg_helper; }; template struct arg_helper { using First = IFirst; using Next = void; }; template<> struct arg_helper<> { using First = void; using Next = void; }; template struct lambda_helper { using Lambda = TheLambda; }; template struct lambda_helper { using Lambda = TheLambda; using Return = IReturn; using Class = IClass; using Args = arg_helper; template explicit lambda_helper(T) {} lambda_helper() = default; }; template lambda_helper(Lambda) -> lambda_helper; // https://stackoverflow.com/questions/66397071/is-it-possible-to-check-if-overloaded-operator-for-type-or-class-exists template class is_streamable { private: template static auto test(int) -> decltype(std::declval() << std::declval(), std::true_type()) { return std::declval(); } template static auto test(...) -> std::false_type { return std::declval(); } public: static constexpr bool value = decltype(test(0))::value; }; template inline constexpr bool is_streamable_v = is_streamable::value; template struct arrow_return { using type = typename std::invoke_result_t), T*>; }; template struct arrow_return { using type = T*; }; // gets the return type for arrow operator template using arrow_return_t = typename arrow_return::type; template struct deref_return { using type = typename std::invoke_result_t; }; template struct deref_return { using type = T&; }; // gets the return type for the reference operator template using deref_return_t = typename deref_return::type; #define BLT_META_MAKE_FUNCTION_CHECK(FUNC, ...)\ template \ class has_func_##FUNC : public std::false_type \ {}; \ template \ class has_func_##FUNC().FUNC(,##__VA_ARGS__))>> : public std::true_type \ {}; \ template \ inline constexpr bool has_func_##FUNC##_v = has_func_##FUNC::value; #define BLT_META_MAKE_MEMBER_CHECK(MEMBER)\ template \ class has_member_##MEMBER : public std::false_type \ {}; \ template \ class has_member_##MEMBER> : public std::true_type \ {}; \ template \ inline constexpr bool has_member_##MEMBER##_v = has_member_##MEMBER::value; } #endif //BLT_GP_META_H