diff --git a/fmt/format.h b/fmt/format.h index 84986c0d..08b1ca09 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -99,6 +99,12 @@ typedef __int64 intmax_t; # define FMT_GCC_EXTENSION #endif +#if defined(__INTEL_COMPILER) +# define FMT_ICC_VERSION __INTEL_COMPILER +#elif defined(__ICL) +# define FMT_ICC_VERSION __ICL +#endif + #if defined(__clang__) && !defined(__INTEL_COMPILER) # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wdocumentation" @@ -212,10 +218,12 @@ typedef __int64 intmax_t; // All compilers which support UDLs also support variadic templates. This // makes the fmt::literals implementation easier. However, an explicit check // for variadic templates is added here just in case. +// For Intel's compiler both it and the system gcc/msc must support UDLs. # define FMT_USE_USER_DEFINED_LITERALS \ FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \ (FMT_HAS_FEATURE(cxx_user_literals) || \ - (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1900) + (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1900) && \ + (!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500) #endif #ifndef FMT_ASSERT diff --git a/support/cmake/cxx11.cmake b/support/cmake/cxx11.cmake index fdda11be..31ea1063 100644 --- a/support/cmake/cxx11.cmake +++ b/support/cmake/cxx11.cmake @@ -63,4 +63,11 @@ check_cxx_source_compiles(" class C { void operator=(const C&); }; int main() { static_assert(!std::is_copy_assignable::value, \"\"); }" SUPPORTS_TYPE_TRAITS) + +# Check if user-defined literals are available +check_cxx_source_compiles(" + void operator\"\" _udl(long double); + int main() {}" + SUPPORTS_USER_DEFINED_LITERALS) + set(CMAKE_REQUIRED_FLAGS ) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3eb5e907..3506b461 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -123,7 +123,11 @@ if (FMT_PEDANTIC) "${CMAKE_CURRENT_SOURCE_DIR}/compile-test" "${CMAKE_CURRENT_BINARY_DIR}/compile-test" --build-generator ${CMAKE_GENERATOR} - --build-makeprogram ${CMAKE_MAKE_PROGRAM}) + --build-makeprogram ${CMAKE_MAKE_PROGRAM} + --build-options + "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" + "-DCPP11_FLAG=${CPP11_FLAG}" + "-DSUPPORTS_USER_DEFINED_LITERALS=${SUPPORTS_USER_DEFINED_LITERALS}") # test if the targets are findable from the build directory add_test(find-package-test ${CMAKE_CTEST_COMMAND} diff --git a/test/compile-test/CMakeLists.txt b/test/compile-test/CMakeLists.txt index 7de4d82c..35a2d296 100644 --- a/test/compile-test/CMakeLists.txt +++ b/test/compile-test/CMakeLists.txt @@ -4,6 +4,7 @@ cmake_minimum_required(VERSION 2.8) include(CheckCXXSourceCompiles) set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/../..) +set(CMAKE_REQUIRED_FLAGS ${CPP11_FLAG}) function (generate_source result fragment) set(${result} " @@ -57,3 +58,14 @@ expect_compile_error("fmt::MemoryWriter() << fmt::pad(42, 5, L' ');") expect_compile_error("fmt::format(\"{}\", L'a';") expect_compile_error("FMT_STATIC_ASSERT(0 > 1, \"oops\");") + +# Make sure that compiler features detected in the header +# match the features detected in CMake. +if (SUPPORTS_USER_DEFINED_LITERALS) + set(supports_udl 1) +else () + set(supports_udl 0) +endif () +expect_compile("#if FMT_USE_USER_DEFINED_LITERALS != ${supports_udl} + # error + #endif")