Centralize the MSVC work-around for std::is_permutation

There's currently only one user, but another one is coming up, so apply DRY
and centralize the work-around for the MSVC warning C4996 on use of 3-arg STL
algorithms in one place.

The code is prepared to handle other algorithms with ease, should any more
crop up.

Change-Id: Ia881888d6a2b5286c6d8d823bc2b76788efad624
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2019-07-10 19:46:45 +02:00
parent 4c61544aa8
commit e89b2f72c7
2 changed files with 24 additions and 15 deletions

View File

@ -1001,6 +1001,29 @@ QT_WARNING_DISABLE_MSVC(4530) /* C++ exception handler used, but unwind semantic
# endif
#endif
// Work around MSVC warning about use of 3-arg algorithms
// until we can depend on the C++14 4-arg ones.
//
// These algortithms do NOT check for equal length.
// They need to be treated as if they called the 3-arg version (which they do)!
#ifdef Q_CC_MSVC
# define QT_3ARG_ALG(alg, f1, l1, f2, l2) \
std::alg(f1, l1, f2, l2)
#else
# define QT_3ARG_ALG(alg, f1, l1, f2, l2) \
[&f1, &l1, &f2, &l2]() { \
Q_UNUSED(l2); \
return std::alg(f1, l1, f2); \
}()
#endif
template <typename ForwardIterator1, typename ForwardIterator2>
inline bool qt_is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2)
{
return QT_3ARG_ALG(is_permutation, first1, last1, first2, last2);
}
#undef QT_3ARG_ALG
// this adds const to non-const objects (like std::as_const)
template <typename T>
Q_DECL_CONSTEXPR typename std::add_const<T>::type &qAsConst(T &t) noexcept { return t; }

View File

@ -981,22 +981,8 @@ Q_OUTOFLINE_TEMPLATE bool QHash<Key, T>::operator==(const QHash &other) const
return false;
// Keys in the ranges are equal by construction; this checks only the values.
//
// When using the 3-arg std::is_permutation, MSVC will emit warning C4996,
// passing an unchecked iterator to a Standard Library algorithm. We don't
// want to suppress the warning, and we can't use stdext::make_checked_array_iterator
// because QHash::(const_)iterator does not work with size_t and thus will
// emit more warnings. Use the 4-arg std::is_permutation instead (which
// is supported since MSVC 2015).
//
// ### Qt 6: if C++14 library support is a mandated minimum, remove the ifdef for MSVC.
if (!std::is_permutation(thisEqualRangeStart, it, otherEqualRange.first
#ifdef Q_CC_MSVC
, otherEqualRange.second
#endif
)) {
if (!qt_is_permutation(thisEqualRangeStart, it, otherEqualRange.first, otherEqualRange.second))
return false;
}
}
return true;