Fix MSVC 2013 compilation issues

This commit is contained in:
Simon Brunel 2017-09-04 00:20:53 +02:00
parent 0682269d8f
commit 931d5d5b13
8 changed files with 72 additions and 18 deletions

7
.gitignore vendored
View File

@ -2,6 +2,11 @@
*.gcda
*.moc
*.o
*.obj
*.exe
*.user
Makefile
Makefile*
moc_*.cpp
moc_*.h
coverage.info
target_wrapper.bat

View File

@ -32,9 +32,13 @@ public:
bool isRejected() const { return m_d->isRejected(); }
bool isPending() const { return m_d->isPending(); }
template <typename TFulfilled, typename TRejected = std::nullptr_t>
template <typename TFulfilled, typename TRejected>
inline typename QtPromisePrivate::PromiseHandler<T, TFulfilled>::Promise
then(const TFulfilled& fulfilled, const TRejected& rejected = nullptr) const;
then(const TFulfilled& fulfilled, const TRejected& rejected) const;
template <typename TFulfilled>
inline typename QtPromisePrivate::PromiseHandler<T, TFulfilled>::Promise
then(TFulfilled&& fulfilled) const;
template <typename TRejected>
inline typename QtPromisePrivate::PromiseHandler<T, std::nullptr_t>::Promise
@ -67,7 +71,7 @@ protected:
};
template <typename T>
class QPromise: public QPromiseBase<T>
class QPromise : public QPromiseBase<T>
{
public:
template <typename F>
@ -82,7 +86,7 @@ private:
};
template <>
class QPromise<void>: public QPromiseBase<void>
class QPromise<void> : public QPromiseBase<void>
{
public:
template <typename F>

View File

@ -122,6 +122,14 @@ QPromiseBase<T>::then(const TFulfilled& fulfilled, const TRejected& rejected) co
return next;
}
template <typename T>
template <typename TFulfilled>
inline typename QtPromisePrivate::PromiseHandler<T, TFulfilled>::Promise
QPromiseBase<T>::then(TFulfilled&& fulfilled) const
{
return then(std::forward<TFulfilled>(fulfilled), nullptr);
}
template <typename T>
template <typename TRejected>
inline typename QtPromisePrivate::PromiseHandler<T, std::nullptr_t>::Promise

View File

@ -508,7 +508,7 @@ private:
template <>
class PromiseData<void> : public PromiseDataBase<void, void()>
{
using Handler = typename PromiseDataBase<void, void()>::Handler;
using Handler = PromiseDataBase<void, void()>::Handler;
public:
void resolve()

View File

@ -16,18 +16,18 @@ using Unqualified = typename std::remove_cv<typename std::remove_reference<T>::t
/*!
* \struct HasCallOperator
* http://stackoverflow.com/a/5839442
* http://stackoverflow.com/a/5117641
*/
template <typename T>
struct HasCallOperator
{
template <class U>
static auto check(const U* u)
-> decltype(&U::operator(), char(0));
template <typename U>
static char check(decltype(&U::operator(), char(0)));
static std::array<char, 2> check(...);
template <typename U>
static char (&check(...))[2];
static const bool value = (sizeof(check((T*)0)) == 1);
static const bool value = (sizeof(check<T>(0)) == 1);
};
/*!

View File

@ -4,6 +4,14 @@
// Qt
#include <QtTest>
#ifdef Q_CC_MSVC
// MSVC calls the copy constructor on std::current_exception AND std::rethrow_exception
// https://stackoverflow.com/a/31820854
#define EXCEPT_CALL_COPY_CTOR 1
#else
#define EXCEPT_CALL_COPY_CTOR 0
#endif
using namespace QtPromise;
class tst_benchmark : public QObject
@ -58,6 +66,35 @@ struct Data : public Logger
Data(int v): Logger(), m_value(v) {}
int value() const { return m_value; }
// MSVC 2013 doesn't support implicit generation of the move constructor and
// operator, so we need to explicitly define these methods and thus the copy
// constructor and operator also need to be explicitly defined (error C2280).
// https://stackoverflow.com/a/26581337
Data(const Data& other)
: Logger(other)
, m_value(other.m_value)
{ }
Data(Data&& other) : Logger(std::forward<Data>(other))
{
qSwap(m_value, other.m_value);
}
Data& operator=(const Data& other)
{
Logger::operator=(other);
m_value = other.m_value;
return *this;
}
Data& operator=(Data&& other)
{
Logger::operator=(std::forward<Data>(other));
qSwap(m_value, other.m_value);
return *this;
}
private:
int m_value;
};
@ -264,7 +301,7 @@ void tst_benchmark::errorReject()
}).wait();
QCOMPARE(Data::logs().ctor, 1);
QCOMPARE(Data::logs().copy, 1); // copy value in std::exception_ptr
QCOMPARE(Data::logs().copy, 1 + EXCEPT_CALL_COPY_CTOR); // copy value in std::exception_ptr
QCOMPARE(Data::logs().move, 0);
QCOMPARE(Data::logs().refs, 0);
}
@ -276,7 +313,7 @@ void tst_benchmark::errorReject()
}).wait();
QCOMPARE(Data::logs().ctor, 1);
QCOMPARE(Data::logs().copy, 1); // copy value to the promise data
QCOMPARE(Data::logs().copy, 1 + EXCEPT_CALL_COPY_CTOR); // copy value to the promise data
QCOMPARE(Data::logs().move, 0);
QCOMPARE(Data::logs().refs, 0);
}
@ -292,7 +329,7 @@ void tst_benchmark::errorThen()
}).wait();
QCOMPARE(Data::logs().ctor, 1);
QCOMPARE(Data::logs().copy, 1); // (initial) copy value in std::exception_ptr
QCOMPARE(Data::logs().copy, 1 + 2 * EXCEPT_CALL_COPY_CTOR); // (initial) copy value in std::exception_ptr
QCOMPARE(Data::logs().move, 0);
QCOMPARE(Data::logs().refs, 0);
QCOMPARE(value, 42);
@ -307,7 +344,7 @@ void tst_benchmark::errorThen()
}).wait();
QCOMPARE(Data::logs().ctor, 1);
QCOMPARE(Data::logs().copy, 1); // (initial) copy value in std::exception_ptr
QCOMPARE(Data::logs().copy, 1 + 4 * EXCEPT_CALL_COPY_CTOR); // (initial) copy value in std::exception_ptr
QCOMPARE(Data::logs().move, 0);
QCOMPARE(Data::logs().refs, 0);
QCOMPARE(value, 42);

View File

@ -262,7 +262,7 @@ void tst_future::fail()
auto input = QPromise<QString>::reject(MyException("bar"));
auto output = input.fail([](const MyException& e) {
return QtConcurrent::run([=]() {
return QString("foo") + e.error();
return QString("foo%1").arg(e.error());
});
});

View File

@ -216,7 +216,7 @@ void tst_requirements::thenOnFulfilled()
// with promises value as its first argument.
QVERIFY(p0.isFulfilled());
QVERIFY(p1.isFulfilled());
QCOMPARE(values, QVector<int>({42}));
QCOMPARE(values, QVector<int>{42});
}
void tst_requirements::thenOnRejected()