/* Extracted from https://github.com/facebook/folly/blob/master/folly/functional/Invoke.h */ /* * Copyright 2017-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #if __cpp_lib_is_invocable >= 201703 || (_MSC_VER >= 1911 && _MSVC_LANG > 201402) namespace backports { /* using override */ using std::invoke_result; /* using override */ using std::invoke_result_t; /* using override */ using std::is_invocable; /* using override */ using std::is_invocable_r; /* using override */ using std::is_invocable_r_v; /* using override */ using std::is_invocable_v; /* using override */ using std::is_nothrow_invocable; /* using override */ using std::is_nothrow_invocable_r; /* using override */ using std::is_nothrow_invocable_r_v; /* using override */ using std::is_nothrow_invocable_v; } // namespace backports #else namespace backports { namespace invoke_detail { template struct Bools { using valid_type = bool; static constexpr std::size_t size() { return sizeof...(Bs); } }; template struct Negation : std::bool_constant {}; // Lighter-weight than Conjunction, but evaluates all sub-conditions eagerly. template struct StrictConjunction : std::is_same, Bools<(Ts::value || true)...>> {}; template struct StrictDisjunction : Negation, Bools<(Ts::value && false)...>>> {}; template using invoke_result_ = decltype(std::invoke(std::declval(), std::declval()...)); template struct invoke_nothrow_ : std::bool_constant(), std::declval()...))> {}; // from: http://en.cppreference.com/w/cpp/types/result_of, CC-BY-SA template struct invoke_result {}; template struct invoke_result>, F, Args...> { using type = invoke_result_; }; template struct is_invocable : std::false_type {}; template struct is_invocable>, F, Args...> : std::true_type {}; template struct is_invocable_r : std::false_type {}; template struct is_invocable_r>, R, F, Args...> : std::is_convertible, R> {}; template struct is_nothrow_invocable : std::false_type {}; template struct is_nothrow_invocable>, F, Args...> : invoke_nothrow_ {}; template struct is_nothrow_invocable_r : std::false_type {}; template struct is_nothrow_invocable_r>, R, F, Args...> : StrictConjunction, R>, invoke_nothrow_> {}; } // namespace invoke_detail // mimic: std::invoke_result, C++17 template struct invoke_result : invoke_detail::invoke_result {}; // mimic: std::invoke_result_t, C++17 template using invoke_result_t = typename invoke_result::type; // mimic: std::is_invocable, C++17 template struct is_invocable : invoke_detail::is_invocable {}; // mimic: std::is_invocable_r, C++17 template struct is_invocable_r : invoke_detail::is_invocable_r {}; // mimic: std::is_nothrow_invocable, C++17 template struct is_nothrow_invocable : invoke_detail::is_nothrow_invocable {}; // mimic: std::is_nothrow_invocable_r, C++17 template struct is_nothrow_invocable_r : invoke_detail::is_nothrow_invocable_r {}; template inline constexpr bool is_invocable_v = is_invocable::value; template inline constexpr bool is_invocable_r_v = is_invocable_r::value; template inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable::value; template inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r::value; } // namespace backports #endif