diff --git a/cmake/modules/CheckCXXFeatures.cmake b/cmake/modules/CheckCXXFeatures.cmake index c4075d4114ba40bf2afef3a5edf49f273c359c28..f2c5107095dc9385f2b96d961a5e6e74a8369975 100644 --- a/cmake/modules/CheckCXXFeatures.cmake +++ b/cmake/modules/CheckCXXFeatures.cmake @@ -22,6 +22,9 @@ # :code:`DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION` # True if C++17's class template argument deduction is supported # +# :code:`DUNE_HAVE_CXX_OPTIONAL` +# True if C++17's optional implementation is supported +# # .. cmake_variable:: DISABLE_CXX_VERSION_CHECK # # You may set this variable to TRUE to disable checking for @@ -350,6 +353,21 @@ check_cxx_source_compiles(" " DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION ) + +# support for C++17's optional implementation +check_cxx_source_compiles(" + #include <optional> + #include <string> + + int main() + { + std::optional< std::string > a; + std::string b = a.value_or( \"empty\" ); + } +" DUNE_HAVE_CXX_OPTIONAL + ) + + # find the threading library # Use a copy FindThreads from CMake 3.1 due to its support of pthread if(NOT DEFINED THREADS_PREFER_PTHREAD_FLAG) diff --git a/config.h.cmake b/config.h.cmake index 1af81555145f43c852c42e2a7d6fd7a4aa914bbd..e06c65b735c90eeb0719e47a2892091d60061f91 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -29,6 +29,9 @@ /* does the compiler support C++17's class template argument deduction? */ #cmakedefine DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 1 +/* does the compiler support C++17's optional? */ +#cmakedefine DUNE_HAVE_CXX_OPTIONAL 1 + /* does the compiler support conditionally throwing exceptions in constexpr context? */ #cmakedefine DUNE_SUPPORTS_CXX_THROW_IN_CONSTEXPR 1 diff --git a/dune/common/std/optional.hh b/dune/common/std/optional.hh index 55807184ebd03a610668a6fa311942b307e80872..f31aabb6ce8b3646e752d4c15cc4c3ab2431dee8 100644 --- a/dune/common/std/optional.hh +++ b/dune/common/std/optional.hh @@ -7,12 +7,24 @@ #include <type_traits> #include <utility> +#ifdef DUNE_HAVE_CXX_OPTIONAL +#include <optional> +#endif // #ifdef DUNE_HAVE_CXX_OPTIONAL + + namespace Dune { namespace Std { +#ifdef DUNE_HAVE_CXX_OPTIONAL + // In case of C++ standard >= 17 we forward optionals into our namespace + template< class T > + using optional = std::optional< T >; +#else + // In case of C++ standard < 17 we take the fallback implementation + // nullopt // ------- @@ -414,11 +426,14 @@ namespace Dune return optional< typename std::decay< T >::type >( std::forward< T >( value ) ); } +#endif //#ifdef DUNE_HAVE_CXX_OPTIONAL + } // namespace Std } // namespace Dune +#ifndef DUNE_HAVE_CXX_OPTIONAL namespace std { @@ -447,4 +462,6 @@ namespace std } // namespace std +#endif //#ifndef DUNE_HAVE_CXX_OPTIONAL + #endif // #ifndef DUNE_COMMON_STD_OPTIONAL_HH