diff --git a/cmake/modules/CheckCXXFeatures.cmake b/cmake/modules/CheckCXXFeatures.cmake index 19c4e60c8edea9905b660c269f4ad414f09e6063..c4075d4114ba40bf2afef3a5edf49f273c359c28 100644 --- a/cmake/modules/CheckCXXFeatures.cmake +++ b/cmake/modules/CheckCXXFeatures.cmake @@ -33,6 +33,7 @@ include(CMakePushCheckState) include(CheckCXXCompilerFlag) include(CheckIncludeFileCXX) include(CheckCXXSourceCompiles) +include(CheckCXXSymbolExists) # C++ standard versions that this test knows about set(CXX_VERSIONS 17 14 11) @@ -464,8 +465,69 @@ check_cxx_source_compiles(" " DUNE_SUPPORTS_CXX_THROW_IN_CONSTEXPR ) + +# ****************************************************************************** +# +# Checks for standard library features +# +# While there are __cpp_lib_* feature test macros for all of these, those are +# unfortunately unreliable, as libc++ does not have feature test macros yet. +# +# In order to keep the tests short, they use check_cxx_symbol_exists(). That +# function can only test for macros and linkable symbols, however, so we wrap +# tested types into a call to std::move(). That should be safe, as std::move() +# does not require a complete type. +# +# ****************************************************************************** + # Check whether we have <experimental/type_traits> (for is_detected et. al.) check_include_file_cxx( experimental/type_traits DUNE_HAVE_HEADER_EXPERIMENTAL_TYPE_TRAITS ) + +check_cxx_symbol_exists( + "std::make_unique<int>" + memory + DUNE_HAVE_CXX_MAKE_UNIQUE + ) + +check_cxx_symbol_exists( + "std::move<std::bool_constant<true>>" + "utility;type_traits" + DUNE_HAVE_CXX_BOOL_CONSTANT + ) + +if (NOT DUNE_HAVE_CXX_BOOL_CONSTANT) + check_cxx_symbol_exists( + "std::move<std::experimental::bool_constant<true>>" + "utility;experimental/type_traits" + DUNE_HAVE_CXX_EXPERIMENTAL_BOOL_CONSTANT + ) +endif() + +check_cxx_symbol_exists( + "std::apply<std::negate<int>,std::tuple<int>>" + "functional;tuple" + DUNE_HAVE_CXX_APPLY + ) + +if (NOT DUNE_HAVE_CXX_APPLY) + check_cxx_symbol_exists( + "std::experimental::apply<std::negate<int>,std::tuple<int>>" + "functional;experimental/tuple" + DUNE_HAVE_CXX_EXPERIMENTAL_APPLY + ) +endif() + +check_cxx_symbol_exists( + "std::experimental::make_array<int,int>" + "experimental/array" + DUNE_HAVE_CXX_EXPERIMENTAL_MAKE_ARRAY + ) + +check_cxx_symbol_exists( + "std::move<std::experimental::detected_t<std::decay_t,int>>" + "utility;experimental/type_traits" + DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED + ) diff --git a/config.h.cmake b/config.h.cmake index e0caa8f5894a899687bdc1e87ad88e7a121dc169..1af81555145f43c852c42e2a7d6fd7a4aa914bbd 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -35,6 +35,27 @@ /* does the standard library provide <experimental/type_traits> ? */ #cmakedefine DUNE_HAVE_HEADER_EXPERIMENTAL_TYPE_TRAITS 1 +/* does the standard library provide make_unique() ? */ +#cmakedefine DUNE_HAVE_CXX_MAKE_UNIQUE 1 + +/* does the standard library provide bool_constant ? */ +#cmakedefine DUNE_HAVE_CXX_BOOL_CONSTANT 1 + +/* does the standard library provide experimental::bool_constant ? */ +#cmakedefine DUNE_HAVE_CXX_EXPERIMENTAL_BOOL_CONSTANT 1 + +/* does the standard library provide apply() ? */ +#cmakedefine DUNE_HAVE_CXX_APPLY 1 + +/* does the standard library provide experimental::apply() ? */ +#cmakedefine DUNE_HAVE_CXX_EXPERIMENTAL_APPLY 1 + +/* does the standard library provide experimental::make_array() ? */ +#cmakedefine DUNE_HAVE_CXX_EXPERIMENTAL_MAKE_ARRAY 1 + +/* does the standard library provide experimental::is_detected ? */ +#cmakedefine DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED 1 + /* Define if you have a BLAS library. */ #cmakedefine HAVE_BLAS 1