From d1c6f06d92569654016e36e4d7ad33bae61a7635 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Steffen=20M=C3=BCthing?= <muething@dune-project.org>
Date: Thu, 14 Sep 2017 10:26:58 +0200
Subject: [PATCH] [cmake] Re-add cmake tests for standard library features

We recently switched to built-in feature test macros for these, but as I had to
learn, libc++ does not have those macros. So back to the pedestrian way of
doing things...
---
 cmake/modules/CheckCXXFeatures.cmake | 62 ++++++++++++++++++++++++++++
 config.h.cmake                       | 21 ++++++++++
 2 files changed, 83 insertions(+)

diff --git a/cmake/modules/CheckCXXFeatures.cmake b/cmake/modules/CheckCXXFeatures.cmake
index 19c4e60c8..c4075d411 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 e0caa8f58..1af815551 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
 
-- 
GitLab