// SPDX-FileCopyrightText: 2018 Kitsune Ral // SPDX-License-Identifier: LGPL-2.1-or-later #pragma once #include namespace Quotient { namespace _impl { template struct fn_traits {}; } /// Determine traits of an arbitrary function/lambda/functor /*! * Doesn't work with generic lambdas and function objects that have * operator() overloaded. * \sa * https://stackoverflow.com/questions/7943525/is-it-possible-to-figure-out-the-parameter-type-and-return-type-of-a-lambda#7943765 */ template struct function_traits : public _impl::fn_traits> {}; // Specialisation for a function template struct function_traits { using return_type = ReturnT; using arg_types = std::tuple; // See also the comment for wrap_in_function() in qt_connection_util.h using function_type = std::function; }; namespace _impl { template struct fn_object_traits; // Specialisation for a lambda function template struct fn_object_traits : function_traits {}; // Specialisation for a const lambda function template struct fn_object_traits : function_traits {}; // Specialisation for function objects with (non-overloaded) operator() // (this includes non-generic lambdas) template struct fn_traits : public fn_object_traits {}; // Specialisation for a member function in a non-functor class template struct fn_traits : function_traits {}; // Specialisation for a const member function template struct fn_traits : function_traits {}; // Specialisation for a constref member function template struct fn_traits : function_traits {}; // Specialisation for a prvalue member function template struct fn_traits : function_traits {}; // Specialisation for a pointer-to-member template struct fn_traits : function_traits {}; // Specialisation for a const pointer-to-member template struct fn_traits : function_traits {}; } // namespace _impl template using fn_return_t = typename function_traits::return_type; template using fn_arg_t = std::tuple_element_t::arg_types>; } // namespace Quotient