/** * Lightweight std::invoke() implementation for C++11 and C++14 * * Copyright (c) 2018-2019 by Nathaniel J. McClatchey, San Jose, CA, United States * Copyright (c) 2022 the build2 authors * * Licensed under the simplified (2-clause) BSD License. * You should have received a copy of the license along with this * program. * * This code 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. */ #ifndef LIBBUTL_MINGW_INVOKE_HXX #define LIBBUTL_MINGW_INVOKE_HXX #include // For std::result_of, etc. #include // For std::forward #include // For std::reference_wrapper namespace mingw_stdthread { namespace detail { // For compatibility, implement std::invoke for C++11 and C++14. // template struct Invoker { template inline static typename std::result_of::type invoke (F&& f, Args&&... args) { return std::forward(f)(std::forward(args)...); } }; template struct InvokerHelper; template<> struct InvokerHelper { template inline static auto get (T1&& t1) -> decltype(*std::forward(t1)) { return *std::forward(t1); } template inline static auto get (const std::reference_wrapper& t1) -> decltype(t1.get()) { return t1.get(); } }; template<> struct InvokerHelper { template inline static auto get (T1&& t1) -> decltype(std::forward(t1)) { return std::forward(t1); } }; template<> struct Invoker { template inline static auto invoke (F T::* f, T1&& t1, Args&&... args) -> \ decltype((InvokerHelper::type>::value>::get(std::forward(t1)).*f)(std::forward(args)...)) { return (InvokerHelper::type>::value>::get(std::forward(t1)).*f)(std::forward(args)...); } }; template<> struct Invoker { template inline static auto invoke (F T::* f, T1&& t1, Args&&... args) -> \ decltype(InvokerHelper::type>::value>::get(t1).*f) { return InvokerHelper::type>::value>::get(t1).*f; } }; template struct InvokeResult { typedef Invoker::type>::value, std::is_member_object_pointer::type>::value && (sizeof...(Args) == 1)> invoker; inline static auto invoke (F&& f, Args&&... args) -> decltype(invoker::invoke(std::forward(f), std::forward(args)...)) { return invoker::invoke(std::forward(f), std::forward(args)...); } }; template auto invoke (F&& f, Args&&... args) -> decltype(InvokeResult::invoke(std::forward(f), std::forward(args)...)) { return InvokeResult::invoke(std::forward(f), std::forward(args)...); } } } #endif // LIBBUTL_MINGW_INVOKE_HXX