mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-04 08:15:30 +08:00
qt 6.5.1 original
This commit is contained in:
1
tests/auto/corelib/global/qxp/CMakeLists.txt
Normal file
1
tests/auto/corelib/global/qxp/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
||||
add_subdirectory(function_ref)
|
10
tests/auto/corelib/global/qxp/function_ref/CMakeLists.txt
Normal file
10
tests/auto/corelib/global/qxp/function_ref/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
qt_internal_add_test(tst_qxp_function_ref
|
||||
EXCEPTIONS
|
||||
SOURCES
|
||||
tst_qxp_function_ref.cpp
|
||||
LIBRARIES
|
||||
Qt::Core
|
||||
)
|
@ -0,0 +1,279 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QtCore/qxpfunctional.h>
|
||||
|
||||
#include <QTest>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
// checking dependency q20::remove_cvref_t:
|
||||
#define CHECK(in, out) \
|
||||
static_assert(std::is_same_v<q20::remove_cvref_t< in >, out >)
|
||||
CHECK(int, int);
|
||||
CHECK(const int, int);
|
||||
CHECK(int &, int);
|
||||
CHECK(const int &, int);
|
||||
CHECK(int &&, int);
|
||||
CHECK(const int &&, int);
|
||||
CHECK(int *, int *);
|
||||
CHECK(const int *, const int *);
|
||||
CHECK(int[4], int[4]);
|
||||
CHECK(const int (&)[4], int[4]);
|
||||
#undef CHECK
|
||||
|
||||
template <typename T> constexpr inline bool
|
||||
is_noexcept_function_ref_helper_v = false;
|
||||
template <typename R, typename...Args> constexpr inline bool
|
||||
is_noexcept_function_ref_helper_v<qxp::function_ref<R(Args...) noexcept(true)>> = true;
|
||||
template <typename R, typename...Args> constexpr inline bool
|
||||
is_noexcept_function_ref_helper_v<qxp::function_ref<R(Args...) const noexcept(true)>> = true;
|
||||
|
||||
template <typename T> constexpr inline bool
|
||||
is_noexcept_function_ref_v = is_noexcept_function_ref_helper_v<q20::remove_cvref_t<T>>;
|
||||
|
||||
class tst_qxp_function_ref : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QObject::QObject;
|
||||
|
||||
private Q_SLOTS:
|
||||
void basics();
|
||||
void constOverloads();
|
||||
void constExpr();
|
||||
void voidReturning();
|
||||
void ctad();
|
||||
};
|
||||
|
||||
void tst_qxp_function_ref::basics()
|
||||
{
|
||||
static_assert(std::is_trivially_copyable_v<qxp::function_ref<int(int)>>);
|
||||
static_assert(std::is_trivially_copyable_v<qxp::function_ref<int()>>);
|
||||
static_assert(std::is_trivially_copyable_v<qxp::function_ref<void()>>);
|
||||
|
||||
{
|
||||
Q_CONSTINIT static int invoked = 0;
|
||||
auto lambda = [](int i) noexcept { ++invoked; return i; };
|
||||
const qxp::function_ref<int(int)> f = lambda;
|
||||
QCOMPARE(invoked, 0);
|
||||
QCOMPARE(f(42), 42);
|
||||
QCOMPARE(invoked, 1);
|
||||
|
||||
const int fourtyTwo = 42;
|
||||
|
||||
const qxp::function_ref<int(int) noexcept> f2 = std::move(lambda);
|
||||
QCOMPARE(invoked, 1);
|
||||
QCOMPARE(f2(fourtyTwo), 42);
|
||||
QCOMPARE(invoked, 2);
|
||||
|
||||
int (*fpr)(int) = lambda;
|
||||
|
||||
const qxp::function_ref f3 = fpr;
|
||||
static_assert(!is_noexcept_function_ref_v<decltype(f3)>);
|
||||
QCOMPARE(invoked, 2);
|
||||
QCOMPARE(f3(42), 42);
|
||||
QCOMPARE(invoked, 3);
|
||||
|
||||
int (*fpr2)(int) noexcept = lambda;
|
||||
|
||||
const qxp::function_ref f4 = fpr2;
|
||||
static_assert(is_noexcept_function_ref_v<decltype(f4)>);
|
||||
QCOMPARE(invoked, 3);
|
||||
QCOMPARE(f4(42), 42);
|
||||
QCOMPARE(invoked, 4);
|
||||
}
|
||||
{
|
||||
Q_CONSTINIT static int invoked = 0;
|
||||
auto lambda = [] { ++invoked; return 42; };
|
||||
const qxp::function_ref<int()> f = lambda;
|
||||
QCOMPARE(invoked, 0);
|
||||
QCOMPARE(f(), 42);
|
||||
QCOMPARE(invoked, 1);
|
||||
|
||||
const qxp::function_ref<int()> f2 = std::move(lambda);
|
||||
QCOMPARE(invoked, 1);
|
||||
QCOMPARE(f2(), 42);
|
||||
QCOMPARE(invoked, 2);
|
||||
|
||||
int (*fpr)() = lambda;
|
||||
|
||||
const qxp::function_ref f3 = fpr;
|
||||
static_assert(!is_noexcept_function_ref_v<decltype(f3)>);
|
||||
QCOMPARE(invoked, 2);
|
||||
QCOMPARE(f3(), 42);
|
||||
QCOMPARE(invoked, 3);
|
||||
}
|
||||
{
|
||||
Q_CONSTINIT static int invoked = 0;
|
||||
auto lambda = [] { ++invoked; };
|
||||
const qxp::function_ref<void()> f = lambda;
|
||||
QCOMPARE(invoked, 0);
|
||||
f();
|
||||
QCOMPARE(invoked, 1);
|
||||
|
||||
const qxp::function_ref<void()> f2 = std::move(lambda);
|
||||
QCOMPARE(invoked, 1);
|
||||
f2();
|
||||
QCOMPARE(invoked, 2);
|
||||
|
||||
void (*fpr)() = lambda;
|
||||
|
||||
const qxp::function_ref f3 = fpr;
|
||||
QCOMPARE(invoked, 2);
|
||||
f3();
|
||||
QCOMPARE(invoked, 3);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qxp_function_ref::constOverloads()
|
||||
{
|
||||
auto func_c = [](qxp::function_ref<int() const> callable)
|
||||
{
|
||||
return callable();
|
||||
};
|
||||
auto func_m = [](qxp::function_ref<int() /*mutable*/> callable)
|
||||
{
|
||||
return callable();
|
||||
};
|
||||
|
||||
struct S
|
||||
{
|
||||
int operator()() { return 1; }
|
||||
int operator()() const { return 2; }
|
||||
};
|
||||
S s;
|
||||
QCOMPARE(func_c(s), 2);
|
||||
QCOMPARE(func_m(s), 1);
|
||||
const S cs;
|
||||
QCOMPARE(func_c(cs), 2);
|
||||
#if 0
|
||||
// this should not compile (and doesn't, but currently fails with an error in the impl,
|
||||
// not by failing a constructor constaint → spec issue?).
|
||||
QCOMPARE(func_m(cs), 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_qxp_function_ref::constExpr()
|
||||
{
|
||||
Q_CONSTINIT static int invoked = 0;
|
||||
{
|
||||
Q_CONSTINIT static auto lambda = [] (int i) { ++invoked; return i; };
|
||||
// the function object constructor is constexpr, so this should be constinit:
|
||||
Q_CONSTINIT static qxp::function_ref<int(int)> f = lambda;
|
||||
|
||||
QCOMPARE(invoked, 0);
|
||||
QCOMPARE(f(15), 15);
|
||||
QCOMPARE(invoked, 1);
|
||||
}
|
||||
{
|
||||
constexpr static auto lambda = [] (int i) { ++invoked; return i; };
|
||||
// the function object constructor is constexpr, so this should be constinit:
|
||||
Q_CONSTINIT static qxp::function_ref<int(int) const> f = lambda;
|
||||
|
||||
QCOMPARE(invoked, 1);
|
||||
QCOMPARE(f(51), 51);
|
||||
QCOMPARE(invoked, 2);
|
||||
|
||||
#if 0 // ### should this work?:
|
||||
Q_CONSTINIT static qxp::function_ref<int(int)> f2 = lambda;
|
||||
|
||||
QCOMPARE(invoked, 2);
|
||||
QCOMPARE(f(150), 150);
|
||||
QCOMPARE(invoked, 3);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int i_f_i_nx(int i) noexcept { return i; }
|
||||
void v_f_i_nx(int) noexcept {}
|
||||
int i_f_v_nx() noexcept { return 42; }
|
||||
void v_f_v_nx() noexcept {}
|
||||
|
||||
int i_f_i_ex(int i) { return i; }
|
||||
void v_f_i_ex(int) {}
|
||||
int i_f_v_ex() { return 42; }
|
||||
void v_f_v_ex() {}
|
||||
|
||||
void tst_qxp_function_ref::voidReturning()
|
||||
{
|
||||
// check that "casting" int to void returns works:
|
||||
|
||||
using Fi = qxp::function_ref<void(int)>;
|
||||
using Fv = qxp::function_ref<void()>;
|
||||
|
||||
{
|
||||
Fi fi = i_f_i_nx;
|
||||
fi(42);
|
||||
Fv fv = i_f_v_nx;
|
||||
fv();
|
||||
}
|
||||
|
||||
{
|
||||
Fi fi = i_f_i_ex;
|
||||
fi(42);
|
||||
Fv fv = i_f_v_ex;
|
||||
fv();
|
||||
}
|
||||
|
||||
// now with lambdas
|
||||
|
||||
bool ok = false; // prevent lambdas from decaying to function pointers
|
||||
{
|
||||
auto lambda1 = [&](int i) noexcept { return i + int(ok); };
|
||||
Fi fi = lambda1;
|
||||
fi(42);
|
||||
auto lambda2 = [&]() noexcept { return int(ok); };
|
||||
Fv fv = lambda2;
|
||||
fv();
|
||||
}
|
||||
|
||||
{
|
||||
auto lambda1 = [&](int i) { return i + int(ok); };
|
||||
Fi fi = lambda1;
|
||||
fi(42);
|
||||
auto lambda2 = [&]() { return int(ok); };
|
||||
Fv fv = lambda2;
|
||||
fv();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qxp_function_ref::ctad()
|
||||
{
|
||||
#define CHECK(fun, sig) \
|
||||
do { \
|
||||
qxp::function_ref f = fun; \
|
||||
static_assert(std::is_same_v<decltype(f), \
|
||||
qxp::function_ref<sig>>); \
|
||||
qxp::function_ref f2 = &fun; \
|
||||
static_assert(std::is_same_v<decltype(f2), \
|
||||
qxp::function_ref<sig>>); \
|
||||
} while (false)
|
||||
|
||||
CHECK(i_f_i_nx, int (int) noexcept);
|
||||
CHECK(v_f_i_nx, void(int) noexcept);
|
||||
CHECK(i_f_v_nx, int ( ) noexcept);
|
||||
CHECK(v_f_v_nx, void( ) noexcept);
|
||||
|
||||
CHECK(i_f_i_ex, int (int));
|
||||
CHECK(v_f_i_ex, void(int));
|
||||
CHECK(i_f_v_ex, int ( ));
|
||||
CHECK(v_f_v_ex, void( ));
|
||||
|
||||
#undef CHECK
|
||||
|
||||
#if 0 // no deduction guides for the non-function-pointer case, so no CTAD for lambdas
|
||||
{
|
||||
auto lambda = [](int i) -> int { return i; };
|
||||
qxp::function_ref f = lambda;
|
||||
static_assert(std::is_same_v<decltype(f),
|
||||
qxp::function_ref<int(int)>>);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_qxp_function_ref);
|
||||
|
||||
#include "tst_qxp_function_ref.moc"
|
Reference in New Issue
Block a user