#pragma once #ifndef C10_UTIL_CPP17_H_ #define C10_UTIL_CPP17_H_ #include #include #include #include #include #if !defined(__clang__) && !defined(_MSC_VER) && defined(__GNUC__) && \ __GNUC__ < 9 #error \ "You're trying to build PyTorch with a too old version of GCC. We need GCC 9 or later." #endif #if defined(__clang__) && __clang_major__ < 9 #error \ "You're trying to build PyTorch with a too old version of Clang. We need Clang 9 or later." #endif #if (defined(_MSC_VER) && (!defined(_MSVC_LANG) || _MSVC_LANG < 201703L)) || \ (!defined(_MSC_VER) && __cplusplus < 201703L) #error You need C++17 to compile PyTorch #endif #if defined(_WIN32) && (defined(min) || defined(max)) #error Macro clash with min and max -- define NOMINMAX when compiling your program on Windows #endif /* * This header adds some polyfills with C++17 functionality */ namespace c10 { // std::is_pod is deprecated in C++20, std::is_standard_layout and // std::is_trivial are introduced in C++11, std::conjunction has been introduced // in C++17. template using is_pod = std::conjunction, std::is_trivial>; template constexpr bool is_pod_v = is_pod::value; namespace guts { #if defined(__cpp_lib_apply) && !defined(__CUDA_ARCH__) && !defined(__HIP__) template C10_HOST_DEVICE inline constexpr decltype(auto) apply(F&& f, Tuple&& t) { return std::apply(std::forward(f), std::forward(t)); } #else // Implementation from http://en.cppreference.com/w/cpp/utility/apply (but // modified) // TODO This is an incomplete implementation of std::apply, not working for // member functions. namespace detail { template C10_HOST_DEVICE constexpr decltype(auto) apply_impl( F&& f, Tuple&& t, std::index_sequence) { return std::forward(f)(std::get(std::forward(t))...); } } // namespace detail template C10_HOST_DEVICE constexpr decltype(auto) apply(F&& f, Tuple&& t) { return detail::apply_impl( std::forward(f), std::forward(t), std::make_index_sequence< std::tuple_size>::value>{}); } #endif } // namespace guts } // namespace c10 #endif // C10_UTIL_CPP17_H_