OR CMAKE_SYSTEM_NAME MATCHES "Windows" )
SET(DEAL_II_CONSTEXPR_BUG TRUE)
ENDIF()
+
+
+#
+# Intel (at least 14, 15) has a bug where it incorrectly detects multiple
+# matching function candidates and dies during type resolution in a
+# perfectly valid SFINAE scenario. This seems to happen because the templated
+# variant is not discarded (where it should be):
+#
+# error: more than one instance of overloaded function
+# "has_vmult_add<Range, T>::test [with Range=double, T=MyMatrix]"
+# matches the argument list:
+# function template "void has_vmult_add<Range, T>::test<C>(decltype((<expression>))) [with Range=double, T=MyMatrix]"
+# function template "void has_vmult_add<Range, T>::test<C>(decltype((&C::vmult_add<double>))) [with Range=double, T=MyMatrix]"
+# [...]
+#
+# - Matthias Maier, 2015
+#
+
+IF(DEAL_II_WITH_CXX11)
+ PUSH_CMAKE_REQUIRED("${DEAL_II_CXX_VERSION_FLAG}")
+ CHECK_CXX_COMPILER_BUG(
+ "
+ template <typename Range, typename T> struct has_vmult_add
+ {
+ template <typename C>
+ static void test(decltype(&C::vmult_add));
+
+ template <typename C>
+ static void test(decltype(&C::template vmult_add<Range>));
+
+ typedef decltype(test<T>(0)) type;
+ };
+
+ struct MyMatrix
+ {
+ void vmult_add() const;
+ };
+
+ int main()
+ {
+ typedef has_vmult_add<double, MyMatrix>::type test;
+ }
+ "
+ DEAL_II_ICC_SFINAE_BUG
+ )
+
+ENDIF()
#cmakedefine DEAL_II_BOOST_BIND_COMPILER_BUG
#cmakedefine DEAL_II_BIND_NO_CONST_OP_PARENTHESES
#cmakedefine DEAL_II_CONSTEXPR_BUG
+#cmakedefine DEAL_II_ICC_SFINAE_BUG
/***********************************************************************
static std::true_type test(decltype(&C::vmult_add),
decltype(&C::Tvmult_add));
+ // Work around a bug with icc (up to version 15) that fails during type
+ // deduction in an SFINAE scenario
+#ifndef DEAL_II_ICC_SFINAE_BUG
+
template <typename C>
static std::true_type test(decltype(&C::template vmult_add<Range>),
decltype(&C::template Tvmult_add<Range>));
template <typename C>
static std::true_type test(decltype(&C::template vmult_add<Range, Domain>),
decltype(&C::template Tvmult_add<Domain, Range>));
+#endif
public:
// type is std::true_type if Matrix provides vmult_add and Tvmult_add,