Add 6.5.0

This commit is contained in:
Stenzek 2023-08-16 00:53:43 +10:00
parent f44f99baad
commit e5c412efff
5247 changed files with 564024 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,20 @@
#ifndef QT_QTCONCURRENT_MODULE_H
#define QT_QTCONCURRENT_MODULE_H
#include <QtConcurrent/QtConcurrentDepends>
#include "qtaskbuilder.h"
#include "qtconcurrentcompilertest.h"
#include "qtconcurrentfilter.h"
#include "qtconcurrentfilterkernel.h"
#include "qtconcurrentfunctionwrappers.h"
#include "qtconcurrentiteratekernel.h"
#include "qtconcurrentmap.h"
#include "qtconcurrentmapkernel.h"
#include "qtconcurrentmedian.h"
#include "qtconcurrentreducekernel.h"
#include "qtconcurrentrun.h"
#include "qtconcurrentrunbase.h"
#include "qtconcurrentstoredfunctioncall.h"
#include "qtconcurrenttask.h"
#include "qtconcurrentthreadengine.h"
#include "qtconcurrentversion.h"
#endif

View File

@ -0,0 +1,4 @@
/* This file was generated by cmake with the info from Concurrent target. */
#ifdef __cplusplus /* create empty PCH in C mode */
# include <QtCore/QtCore>
#endif

View File

@ -0,0 +1 @@
#include "qtconcurrentfilter.h"

View File

@ -0,0 +1 @@
#include "qtconcurrentmap.h"

View File

@ -0,0 +1 @@
#include "qtconcurrentrun.h"

View File

@ -0,0 +1 @@
#include "qtconcurrentversion.h"

View File

@ -0,0 +1,135 @@
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTBASE_QTTASKBUILDER_H
#define QTBASE_QTTASKBUILDER_H
#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
#include <QtConcurrent/qtconcurrentstoredfunctioncall.h>
QT_BEGIN_NAMESPACE
#ifdef Q_QDOC
namespace QtConcurrent {
enum class FutureResult { Ignore };
using InvokeResultType = int;
template <class Task, class ...Args>
class QTaskBuilder
{
public:
[[nodiscard]]
QFuture<InvokeResultType> spawn();
void spawn(FutureResult);
template <class ...ExtraArgs>
[[nodiscard]]
QTaskBuilder<Task, ExtraArgs...> withArguments(ExtraArgs &&...args);
[[nodiscard]]
QTaskBuilder<Task, Args...> &onThreadPool(QThreadPool &newThreadPool);
[[nodiscard]]
QTaskBuilder<Task, Args...> &withPriority(int newPriority);
};
} // namespace QtConcurrent
#else
namespace QtConcurrent {
enum class FutureResult { Ignore };
template <class Task, class ...Args>
class QTaskBuilder
{
public:
[[nodiscard]]
auto spawn()
{
return TaskResolver<std::decay_t<Task>, std::decay_t<Args>...>::run(
std::move(taskWithArgs), startParameters);
}
// We don't want to run with promise when we don't return a QFuture
void spawn(FutureResult)
{
(new StoredFunctionCall<Task, Args...>(std::move(taskWithArgs)))
->start(startParameters);
}
template <class ...ExtraArgs>
[[nodiscard]]
constexpr auto withArguments(ExtraArgs &&...args)
{
static_assert(std::tuple_size_v<TaskWithArgs> == 1,
"This function cannot be invoked if "
"arguments have already been passed.");
static_assert(sizeof...(ExtraArgs) >= 1,
"One or more arguments must be passed.");
// We have to re-create a builder, because the type has changed
return QTaskBuilder<Task, ExtraArgs...>(
startParameters,
std::get<0>(std::move(taskWithArgs)),
std::forward<ExtraArgs>(args)...
);
}
[[nodiscard]]
constexpr auto &onThreadPool(QThreadPool &newThreadPool)
{
startParameters.threadPool = &newThreadPool;
return *this;
}
[[nodiscard]]
constexpr auto &withPriority(int newPriority)
{
startParameters.priority = newPriority;
return *this;
}
protected: // Methods
constexpr explicit QTaskBuilder(Task &&task, Args &&...arguments)
: taskWithArgs{std::forward<Task>(task), std::forward<Args>(arguments)...}
{}
constexpr QTaskBuilder(
const TaskStartParameters &parameters, Task &&task, Args &&...arguments)
: taskWithArgs{std::forward<Task>(task), std::forward<Args>(arguments)...}
, startParameters{parameters}
{}
private: // Methods
// Required for creating a builder from "task" function
template <class T>
friend constexpr auto task(T &&t);
// Required for creating a new builder from "withArguments" function
template <class T, class ...A>
friend class QTaskBuilder;
private: // Data
using TaskWithArgs = DecayedTuple<Task, Args...>;
TaskWithArgs taskWithArgs;
TaskStartParameters startParameters;
};
} // namespace QtConcurrent
#endif // Q_QDOC
QT_END_NAMESPACE
#endif // !defined(QT_NO_CONCURRENT)
#endif //QTBASE_QTTASKBUILDER_H

View File

@ -0,0 +1,10 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_GLOBAL_H
#define QTCONCURRENT_GLOBAL_H
#include <QtCore/qglobal.h>
#include <QtConcurrent/qtconcurrentexports.h>
#endif // include guard

View File

@ -0,0 +1,41 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_COMPILERTEST_H
#define QTCONCURRENT_COMPILERTEST_H
#include <QtConcurrent/qtconcurrent_global.h>
#ifndef QT_NO_CONCURRENT
QT_BEGIN_NAMESPACE
namespace QtPrivate {
template <class T, typename = void>
struct IsIterable : std::false_type {};
template <class T>
struct IsIterable<T, std::void_t<decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end())>>
: std::true_type
{ };
template <class T>
inline constexpr bool IsIterableValue = IsIterable<T>::value;
template <class T, typename = void>
struct IsDereferenceable : std::false_type {};
template <class T>
struct IsDereferenceable<T, std::void_t<decltype(*std::declval<T>())>>
: std::true_type
{ };
template <class T>
inline constexpr bool IsDereferenceableValue = IsDereferenceable<T>::value;
}
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
#endif

View File

@ -0,0 +1,48 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtCore/qglobal.h>
#ifndef QTCONCURRENTEXPORTS_H
#define QTCONCURRENTEXPORTS_H
#if defined(QT_SHARED) || !defined(QT_STATIC)
# if defined(QT_BUILD_CONCURRENT_LIB)
# define Q_CONCURRENT_EXPORT Q_DECL_EXPORT
# else
# define Q_CONCURRENT_EXPORT Q_DECL_IMPORT
# endif
#else
# define Q_CONCURRENT_EXPORT
#endif
#if !defined(QT_BUILD_CONCURRENT_LIB) && !defined(QT_STATIC)
/* outside library → inline decl + defi */
/* static builds treat everything as part of the library, so they never inline */
# define QT_CONCURRENT_INLINE_SINCE(major, minor) inline
# define QT_CONCURRENT_INLINE_IMPL_SINCE(major, minor) 1
#elif defined(QT_CONCURRENT_BUILD_REMOVED_API)
/* inside library, inside removed_api.cpp:
* keep deprecated API non-inline decl;
* remove deprecated API inline decl;
* definition is always available */
# define QT_CONCURRENT_INLINE_SINCE(major, minor) \
QT_IF_DEPRECATED_SINCE(major, minor, inline, /* not inline */)
# define QT_CONCURRENT_INLINE_IMPL_SINCE(major, minor) 1
#else
/* inside library, outside removed_api.cpp:
* keep deprecated API non-inline decl, no defi;
* remove deprecated API inline decl, defi */
# define QT_CONCURRENT_INLINE_SINCE(major, minor) \
QT_IF_DEPRECATED_SINCE(major, minor, inline, /* not inline */)
# define QT_CONCURRENT_INLINE_IMPL_SINCE(major, minor) \
QT_IF_DEPRECATED_SINCE(major, minor, 1, 0)
#endif
#ifdef QT_CONCURRENT_BUILD_REMOVED_API
# define QT_CONCURRENT_REMOVED_SINCE(major, minor) QT_DEPRECATED_SINCE(major, minor)
#else
# define QT_CONCURRENT_REMOVED_SINCE(major, minor) 0
#endif
#endif // QTCONCURRENTEXPORTS_H

View File

@ -0,0 +1,719 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_FILTER_H
#define QTCONCURRENT_FILTER_H
#if 0
#pragma qt_class(QtConcurrentFilter)
#endif
#include <QtConcurrent/qtconcurrent_global.h>
#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
#include <QtConcurrent/qtconcurrentfilterkernel.h>
#include <QtConcurrent/qtconcurrentfunctionwrappers.h>
QT_BEGIN_NAMESPACE
namespace QtConcurrent {
//! [QtConcurrent-1]
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
ThreadEngineStarter<void> filterInternal(QThreadPool *pool, Sequence &sequence,
KeepFunctor &&keep, ReduceFunctor &&reduce)
{
typedef FilterKernel<Sequence, std::decay_t<KeepFunctor>, std::decay_t<ReduceFunctor>>
KernelType;
return startThreadEngine(new KernelType(pool, sequence, std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce)));
}
// filter() on sequences
template <typename Sequence, typename KeepFunctor>
QFuture<void> filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&keep)
{
return filterInternal(pool, sequence, std::forward<KeepFunctor>(keep),
QtPrivate::PushBackWrapper());
}
template <typename Sequence, typename KeepFunctor>
QFuture<void> filter(Sequence &sequence, KeepFunctor &&keep)
{
return filterInternal(QThreadPool::globalInstance(),
sequence, std::forward<KeepFunctor>(keep), QtPrivate::PushBackWrapper());
}
// filteredReduced() on sequences
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
QFuture<ResultType> filteredReduced(QThreadPool *pool,
Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(pool, std::forward<Sequence>(sequence),
std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
}
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
QFuture<ResultType> filteredReduced(Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(
QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce), options);
}
#ifdef Q_QDOC
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
QFuture<ResultType> filteredReduced(QThreadPool *pool,
Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(
pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
#ifdef Q_QDOC
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
QFuture<ResultType> filteredReduced(Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(
QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
#ifndef Q_QDOC
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
QFuture<ResultType> filteredReduced(QThreadPool *pool,
Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(pool, std::forward<Sequence>(sequence),
std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
}
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
QFuture<ResultType> filteredReduced(Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(
QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce), options);
}
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
QFuture<ResultType> filteredReduced(QThreadPool *pool,
Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(
pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
QFuture<ResultType> filteredReduced(Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(
QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
#endif
// filteredReduced() on iterators
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
QFuture<ResultType> filteredReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(pool, begin, end, std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
}
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
QFuture<ResultType> filteredReduced(Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(QThreadPool::globalInstance(), begin, end,
std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
}
#ifdef Q_QDOC
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
QFuture<ResultType> filteredReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(
pool, begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
#ifdef Q_QDOC
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
QFuture<ResultType> filteredReduced(Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(
QThreadPool::globalInstance(), begin, end, std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
#ifndef Q_QDOC
template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
QFuture<ResultType> filteredReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(pool, begin, end, std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
}
template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
QFuture<ResultType> filteredReduced(Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(QThreadPool::globalInstance(), begin, end,
std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
}
template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
QFuture<ResultType> filteredReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(
pool, begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
std::enable_if_t<QtPrivate::isIterator_v<Iterator>, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
QFuture<ResultType> filteredReduced(Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startFilteredReduced<ResultType>(
QThreadPool::globalInstance(), begin, end, std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
#endif
// filtered() on sequences
template <typename Sequence, typename KeepFunctor>
QFuture<typename std::decay_t<Sequence>::value_type> filtered(QThreadPool *pool,Sequence &&sequence,
KeepFunctor &&keep)
{
return startFiltered(pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep));
}
template <typename Sequence, typename KeepFunctor>
QFuture<typename std::decay_t<Sequence>::value_type> filtered(Sequence &&sequence,
KeepFunctor &&keep)
{
return startFiltered(QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
std::forward<KeepFunctor>(keep));
}
// filtered() on iterators
template <typename Iterator, typename KeepFunctor>
QFuture<typename qValueType<Iterator>::value_type> filtered(QThreadPool *pool,
Iterator begin,
Iterator end,
KeepFunctor &&keep)
{
return startFiltered(pool, begin, end, std::forward<KeepFunctor>(keep));
}
template <typename Iterator, typename KeepFunctor>
QFuture<typename qValueType<Iterator>::value_type> filtered(Iterator begin,
Iterator end,
KeepFunctor &&keep)
{
return startFiltered(QThreadPool::globalInstance(), begin, end,
std::forward<KeepFunctor>(keep));
}
// blocking filter() on sequences
template <typename Sequence, typename KeepFunctor>
void blockingFilter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&keep)
{
QFuture<void> future = filter(pool, sequence, std::forward<KeepFunctor>(keep));
future.waitForFinished();
}
template <typename Sequence, typename KeepFunctor>
void blockingFilter(Sequence &sequence, KeepFunctor &&keep)
{
QFuture<void> future = filter(sequence, std::forward<KeepFunctor>(keep));
future.waitForFinished();
}
// blocking filteredReduced() on sequences
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
ResultType blockingFilteredReduced(QThreadPool *pool,
Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = filteredReduced<ResultType>(
pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
ResultType blockingFilteredReduced(Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = filteredReduced<ResultType>(
std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
#ifdef Q_QDOC
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
ResultType blockingFilteredReduced(QThreadPool *pool,
Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = filteredReduced<ResultType>(
pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
#ifdef Q_QDOC
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
ResultType blockingFilteredReduced(Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = filteredReduced<ResultType>(
std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
#ifndef Q_QDOC
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
ResultType blockingFilteredReduced(QThreadPool *pool,
Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = filteredReduced<ResultType>(
pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
ResultType blockingFilteredReduced(Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = filteredReduced<ResultType>(
std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
ResultType blockingFilteredReduced(QThreadPool *pool,
Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = filteredReduced<ResultType>(
pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
ResultType blockingFilteredReduced(Sequence &&sequence,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = filteredReduced<ResultType>(
std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
#endif
// blocking filteredReduced() on iterators
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
ResultType blockingFilteredReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future =
filteredReduced<ResultType>(pool, begin, end, std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
ResultType blockingFilteredReduced(Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future =
filteredReduced<ResultType>(begin, end, std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
#ifdef Q_QDOC
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
ResultType blockingFilteredReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = filteredReduced<ResultType>(
pool, begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
#ifdef Q_QDOC
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
ResultType blockingFilteredReduced(Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = filteredReduced<ResultType>(
begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
#ifndef Q_QDOC
template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
ResultType blockingFilteredReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future =
filteredReduced<ResultType>(pool, begin, end, std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
ResultType blockingFilteredReduced(Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future =
filteredReduced<ResultType>(begin, end, std::forward<KeepFunctor>(keep),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
ResultType blockingFilteredReduced(QThreadPool *pool,
Iterator begin,
Iterator end, KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = filteredReduced<ResultType>(
pool, begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
std::enable_if_t<QtPrivate::isIterator_v<Iterator>, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
ResultType blockingFilteredReduced(Iterator begin,
Iterator end,
KeepFunctor &&keep,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = filteredReduced<ResultType>(
begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
#endif
// blocking filtered() on sequences
template <typename Sequence, typename KeepFunctor>
std::decay_t<Sequence> blockingFiltered(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&keep)
{
return blockingFilteredReduced<std::decay_t<Sequence>>(
pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
QtPrivate::PushBackWrapper(), OrderedReduce);
}
template <typename Sequence, typename KeepFunctor>
std::decay_t<Sequence> blockingFiltered(Sequence &&sequence, KeepFunctor &&keep)
{
return blockingFilteredReduced<std::decay_t<Sequence>>(
QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
std::forward<KeepFunctor>(keep), QtPrivate::PushBackWrapper(), OrderedReduce);
}
// blocking filtered() on iterators
template <typename OutputSequence, typename Iterator, typename KeepFunctor>
OutputSequence blockingFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&keep)
{
return blockingFilteredReduced<OutputSequence>(pool, begin, end,
std::forward<KeepFunctor>(keep),
QtPrivate::PushBackWrapper(), OrderedReduce);
}
template <typename OutputSequence, typename Iterator, typename KeepFunctor>
OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor &&keep)
{
return blockingFilteredReduced<OutputSequence>(QThreadPool::globalInstance(), begin, end,
std::forward<KeepFunctor>(keep),
QtPrivate::PushBackWrapper(), OrderedReduce);
}
} // namespace QtConcurrent
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
#endif

View File

@ -0,0 +1,386 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_FILTERKERNEL_H
#define QTCONCURRENT_FILTERKERNEL_H
#include <QtConcurrent/qtconcurrent_global.h>
#if !defined(QT_NO_CONCURRENT) || defined (Q_QDOC)
#include <QtConcurrent/qtconcurrentiteratekernel.h>
#include <QtConcurrent/qtconcurrentmapkernel.h>
#include <QtConcurrent/qtconcurrentreducekernel.h>
QT_BEGIN_NAMESPACE
namespace QtConcurrent {
template <typename T>
struct qValueType
{
typedef typename T::value_type value_type;
};
template <typename T>
struct qValueType<const T*>
{
typedef T value_type;
};
template <typename T>
struct qValueType<T*>
{
typedef T value_type;
};
// Implementation of filter
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
class FilterKernel : public IterateKernel<typename Sequence::const_iterator, void>
{
typedef ReduceKernel<ReduceFunctor, Sequence, typename Sequence::value_type> Reducer;
typedef IterateKernel<typename Sequence::const_iterator, void> IterateKernelType;
typedef void T;
Sequence reducedResult;
Sequence &sequence;
KeepFunctor keep;
ReduceFunctor reduce;
Reducer reducer;
public:
template <typename Keep = KeepFunctor, typename Reduce = ReduceFunctor>
FilterKernel(QThreadPool *pool, Sequence &_sequence, Keep &&_keep, Reduce &&_reduce)
: IterateKernelType(pool, const_cast<const Sequence &>(_sequence).begin(),
const_cast<const Sequence &>(_sequence).end()), reducedResult(),
sequence(_sequence),
keep(std::forward<Keep>(_keep)),
reduce(std::forward<Reduce>(_reduce)),
reducer(pool, OrderedReduce)
{ }
bool runIteration(typename Sequence::const_iterator it, int index, T *) override
{
IntermediateResults<typename Sequence::value_type> results;
results.begin = index;
results.end = index + 1;
if (std::invoke(keep, *it))
results.vector.append(*it);
reducer.runReduce(reduce, reducedResult, results);
return false;
}
bool runIterations(typename Sequence::const_iterator sequenceBeginIterator, int begin, int end, T *) override
{
IntermediateResults<typename Sequence::value_type> results;
results.begin = begin;
results.end = end;
results.vector.reserve(end - begin);
typename Sequence::const_iterator it = sequenceBeginIterator;
std::advance(it, begin);
for (int i = begin; i < end; ++i) {
if (std::invoke(keep, *it))
results.vector.append(*it);
std::advance(it, 1);
}
reducer.runReduce(reduce, reducedResult, results);
return false;
}
void finish() override
{
reducer.finish(reduce, reducedResult);
sequence = std::move(reducedResult);
}
inline bool shouldThrottleThread() override
{
return IterateKernelType::shouldThrottleThread() || reducer.shouldThrottle();
}
inline bool shouldStartThread() override
{
return IterateKernelType::shouldStartThread() && reducer.shouldStartThread();
}
typedef void ReturnType;
typedef void ResultType;
};
// Implementation of filter-reduce
template <typename ReducedResultType,
typename Iterator,
typename KeepFunctor,
typename ReduceFunctor,
typename Reducer = ReduceKernel<ReduceFunctor,
ReducedResultType,
typename qValueType<Iterator>::value_type> >
class FilteredReducedKernel : public IterateKernel<Iterator, ReducedResultType>
{
ReducedResultType &reducedResult;
KeepFunctor keep;
ReduceFunctor reduce;
Reducer reducer;
typedef IterateKernel<Iterator, ReducedResultType> IterateKernelType;
public:
template<typename Keep = KeepFunctor, typename Reduce = ReduceFunctor>
FilteredReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep,
Reduce &&_reduce, ReduceOptions reduceOption)
: IterateKernelType(pool, begin, end),
reducedResult(this->defaultValue.value),
keep(std::forward<Keep>(_keep)),
reduce(std::forward<Reduce>(_reduce)),
reducer(pool, reduceOption)
{ }
template <typename Keep = KeepFunctor, typename Reduce = ReduceFunctor>
FilteredReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep,
Reduce &&_reduce, ReducedResultType &&initialValue,
ReduceOptions reduceOption)
: IterateKernelType(pool, begin, end, std::forward<ReducedResultType>(initialValue)),
reducedResult(this->defaultValue.value),
keep(std::forward<Keep>(_keep)),
reduce(std::forward<Reduce>(_reduce)),
reducer(pool, reduceOption)
{
}
bool runIteration(Iterator it, int index, ReducedResultType *) override
{
IntermediateResults<typename qValueType<Iterator>::value_type> results;
results.begin = index;
results.end = index + 1;
if (std::invoke(keep, *it))
results.vector.append(*it);
reducer.runReduce(reduce, reducedResult, results);
return false;
}
bool runIterations(Iterator sequenceBeginIterator, int begin, int end, ReducedResultType *) override
{
IntermediateResults<typename qValueType<Iterator>::value_type> results;
results.begin = begin;
results.end = end;
results.vector.reserve(end - begin);
Iterator it = sequenceBeginIterator;
std::advance(it, begin);
for (int i = begin; i < end; ++i) {
if (std::invoke(keep, *it))
results.vector.append(*it);
std::advance(it, 1);
}
reducer.runReduce(reduce, reducedResult, results);
return false;
}
void finish() override
{
reducer.finish(reduce, reducedResult);
}
inline bool shouldThrottleThread() override
{
return IterateKernelType::shouldThrottleThread() || reducer.shouldThrottle();
}
inline bool shouldStartThread() override
{
return IterateKernelType::shouldStartThread() && reducer.shouldStartThread();
}
typedef ReducedResultType ReturnType;
typedef ReducedResultType ResultType;
ReducedResultType *result() override
{
return &reducedResult;
}
};
// Implementation of filter that reports individual results via QFutureInterface
template <typename Iterator, typename KeepFunctor>
class FilteredEachKernel : public IterateKernel<Iterator, typename qValueType<Iterator>::value_type>
{
typedef typename qValueType<Iterator>::value_type T;
typedef IterateKernel<Iterator, T> IterateKernelType;
KeepFunctor keep;
public:
typedef T ReturnType;
typedef T ResultType;
template <typename Keep = KeepFunctor>
FilteredEachKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep)
: IterateKernelType(pool, begin, end), keep(std::forward<Keep>(_keep))
{ }
void start() override
{
if (this->futureInterface)
this->futureInterface->setFilterMode(true);
IterateKernelType::start();
}
bool runIteration(Iterator it, int index, T *) override
{
if (std::invoke(keep, *it))
this->reportResult(&(*it), index);
else
this->reportResult(nullptr, index);
return false;
}
bool runIterations(Iterator sequenceBeginIterator, int begin, int end, T *) override
{
const int count = end - begin;
IntermediateResults<typename qValueType<Iterator>::value_type> results;
results.begin = begin;
results.end = end;
results.vector.reserve(count);
Iterator it = sequenceBeginIterator;
std::advance(it, begin);
for (int i = begin; i < end; ++i) {
if (std::invoke(keep, *it))
results.vector.append(*it);
std::advance(it, 1);
}
this->reportResults(results.vector, begin, count);
return false;
}
};
//! [QtConcurrent-2]
template <typename Iterator, typename KeepFunctor>
inline
ThreadEngineStarter<typename qValueType<Iterator>::value_type>
startFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&functor)
{
return startThreadEngine(new FilteredEachKernel<Iterator, std::decay_t<KeepFunctor>>
(pool, begin, end, std::forward<KeepFunctor>(functor)));
}
//! [QtConcurrent-3]
template <typename Sequence, typename KeepFunctor>
inline decltype(auto) startFiltered(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&functor)
{
using DecayedSequence = std::decay_t<Sequence>;
using DecayedFunctor = std::decay_t<KeepFunctor>;
using SequenceHolderType = SequenceHolder1<DecayedSequence,
FilteredEachKernel<typename DecayedSequence::const_iterator, DecayedFunctor>,
DecayedFunctor>;
return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
std::forward<KeepFunctor>(functor)));
}
//! [QtConcurrent-4]
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
inline ThreadEngineStarter<ResultType> startFilteredReduced(QThreadPool *pool,
Sequence &&sequence,
MapFunctor &&mapFunctor,
ReduceFunctor &&reduceFunctor,
ReduceOptions options)
{
using DecayedSequence = std::decay_t<Sequence>;
using DecayedMapFunctor = std::decay_t<MapFunctor>;
using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
using Iterator = typename DecayedSequence::const_iterator;
using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType,
typename qValueType<Iterator>::value_type>;
using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, DecayedMapFunctor,
DecayedReduceFunctor, Reducer>;
using SequenceHolderType = SequenceHolder2<DecayedSequence, FilteredReduceType,
DecayedMapFunctor, DecayedReduceFunctor>;
return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
std::forward<MapFunctor>(mapFunctor),
std::forward<ReduceFunctor>(reduceFunctor),
options));
}
//! [QtConcurrent-5]
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
inline ThreadEngineStarter<ResultType> startFilteredReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
MapFunctor &&mapFunctor,
ReduceFunctor &&reduceFunctor,
ReduceOptions options)
{
using Reducer = ReduceKernel<std::decay_t<ReduceFunctor>, ResultType,
typename qValueType<Iterator>::value_type>;
using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
std::decay_t<ReduceFunctor>, Reducer>;
return startThreadEngine(
new FilteredReduceType(pool, begin, end, std::forward<MapFunctor>(mapFunctor),
std::forward<ReduceFunctor>(reduceFunctor), options));
}
// Repeat the two functions above, but now with an initial value!
//! [QtConcurrent-6]
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
inline ThreadEngineStarter<ResultType> startFilteredReduced(QThreadPool *pool,
Sequence &&sequence,
MapFunctor &&mapFunctor,
ReduceFunctor &&reduceFunctor,
ResultType &&initialValue,
ReduceOptions options)
{
using DecayedSequence = std::decay_t<Sequence>;
using DecayedMapFunctor = std::decay_t<MapFunctor>;
using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
using Iterator = typename DecayedSequence::const_iterator;
using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType,
typename qValueType<Iterator>::value_type>;
using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, DecayedMapFunctor,
DecayedReduceFunctor, Reducer>;
using SequenceHolderType = SequenceHolder2<DecayedSequence, FilteredReduceType,
DecayedMapFunctor, DecayedReduceFunctor>;
return startThreadEngine(new SequenceHolderType(
pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(mapFunctor),
std::forward<ReduceFunctor>(reduceFunctor), std::forward<ResultType>(initialValue),
options));
}
//! [QtConcurrent-7]
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
inline ThreadEngineStarter<ResultType> startFilteredReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
MapFunctor &&mapFunctor,
ReduceFunctor &&reduceFunctor,
ResultType &&initialValue,
ReduceOptions options)
{
using Reducer = ReduceKernel<std::decay_t<ReduceFunctor>, ResultType,
typename qValueType<Iterator>::value_type>;
using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
std::decay_t<ReduceFunctor>, Reducer>;
return startThreadEngine(
new FilteredReduceType(pool, begin, end, std::forward<MapFunctor>(mapFunctor),
std::forward<ReduceFunctor>(reduceFunctor),
std::forward<ResultType>(initialValue), options));
}
} // namespace QtConcurrent
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
#endif

View File

@ -0,0 +1,179 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_FUNCTIONWRAPPERS_H
#define QTCONCURRENT_FUNCTIONWRAPPERS_H
#include <QtConcurrent/qtconcurrentcompilertest.h>
#include <QtConcurrent/qtconcurrentreducekernel.h>
#include <QtCore/qfuture.h>
#include <tuple>
#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
QT_BEGIN_NAMESPACE
namespace QtPrivate {
struct PushBackWrapper
{
template <class C, class U>
inline void operator()(C &c, const U &u) const
{
return c.push_back(u);
}
template <class C, class U>
inline void operator()(C &c, U &&u) const
{
return c.push_back(u);
}
};
// -- MapResultType
template <class T, class Enable = void>
struct Argument
{
using Type = void;
};
template <class Sequence>
struct Argument<Sequence, typename std::enable_if<IsIterableValue<Sequence>>::type>
{
using Type = std::decay_t<decltype(*std::declval<Sequence>().begin())>;
};
template <class Iterator>
struct Argument<Iterator, typename std::enable_if<IsDereferenceableValue<Iterator>>::type>
{
using Type = std::decay_t<decltype(*std::declval<Iterator>())>;
};
template <class T>
using ArgumentType = typename Argument<T>::Type;
template <class T, class MapFunctor>
struct MapResult
{
static_assert(std::is_invocable_v<std::decay_t<MapFunctor>, ArgumentType<T>>,
"It's not possible to invoke the function with passed argument.");
using Type = std::invoke_result_t<std::decay_t<MapFunctor>, ArgumentType<T>>;
};
template <class T, class MapFunctor>
using MapResultType = typename MapResult<T, MapFunctor>::Type;
// -- ReduceResultType
template <class T>
struct ReduceResultType;
template <class U, class V>
struct ReduceResultType<void(*)(U&,V)>
{
using ResultType = U;
};
template <class T, class C, class U>
struct ReduceResultType<T(C::*)(U)>
{
using ResultType = C;
};
template <class U, class V>
struct ReduceResultType<std::function<void(U&, V)>>
{
using ResultType = U;
};
template <typename R, typename ...A>
struct ReduceResultType<R(*)(A...)>
{
using ResultType = typename std::tuple_element<0, std::tuple<A...>>::type;
};
template <class U, class V>
struct ReduceResultType<void(*)(U&,V) noexcept>
{
using ResultType = U;
};
template <class T, class C, class U>
struct ReduceResultType<T(C::*)(U) noexcept>
{
using ResultType = C;
};
template<class T, class Enable = void>
inline constexpr bool hasCallOperator_v = false;
template<class T>
inline constexpr bool hasCallOperator_v<T, std::void_t<decltype(&T::operator())>> = true;
template<class T, class Enable = void>
inline constexpr bool isIterator_v = false;
template<class T>
inline constexpr bool isIterator_v<T, std::void_t<typename std::iterator_traits<T>::value_type>> =
true;
template <class Callable, class Sequence>
using isInvocable = std::is_invocable<Callable, typename std::decay_t<Sequence>::value_type>;
template <class InitialValueType, class ResultType>
inline constexpr bool isInitialValueCompatible_v = std::conjunction_v<
std::is_convertible<InitialValueType, ResultType>,
std::negation<std::is_same<std::decay_t<InitialValueType>, QtConcurrent::ReduceOption>>>;
template<class Callable, class Enable = void>
struct ReduceResultTypeHelper
{
};
template <class Callable>
struct ReduceResultTypeHelper<Callable,
typename std::enable_if_t<std::is_function_v<std::remove_pointer_t<std::decay_t<Callable>>>
|| std::is_member_function_pointer_v<std::decay_t<Callable>>>>
{
using type = typename QtPrivate::ReduceResultType<std::decay_t<Callable>>::ResultType;
};
template <class Callable>
struct ReduceResultTypeHelper<Callable,
typename std::enable_if_t<!std::is_function_v<std::remove_pointer_t<std::decay_t<Callable>>>
&& hasCallOperator_v<std::decay_t<Callable>>>>
{
using type = std::decay_t<typename QtPrivate::ArgResolver<Callable>::First>;
};
// -- MapSequenceResultType
template <class InputSequence, class MapFunctor>
struct MapSequenceResultType
{
static_assert(std::is_same_v<typename InputSequence::value_type,
QtPrivate::MapResultType<InputSequence, MapFunctor>>,
"Couldn't deduce the output sequence type, you must specify it explicitly.");
typedef InputSequence ResultType;
};
#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
template <template <typename...> class InputSequence, typename MapFunctor, typename ...T>
struct MapSequenceResultType<InputSequence<T...>, MapFunctor>
{
typedef InputSequence<QtPrivate::MapResultType<InputSequence<T...>, MapFunctor>> ResultType;
};
#endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER
} // namespace QtPrivate.
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
#endif

View File

@ -0,0 +1,335 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_ITERATEKERNEL_H
#define QTCONCURRENT_ITERATEKERNEL_H
#include <QtConcurrent/qtconcurrent_global.h>
#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
#include <QtCore/qatomic.h>
#include <QtConcurrent/qtconcurrentmedian.h>
#include <QtConcurrent/qtconcurrentthreadengine.h>
#include <iterator>
QT_BEGIN_NAMESPACE
namespace QtConcurrent {
/*
The BlockSizeManager class manages how many iterations a thread should
reserve and process at a time. This is done by measuring the time spent
in the user code versus the control part code, and then increasing
the block size if the ratio between them is to small. The block size
management is done on the basis of the median of several timing measurements,
and it is done individually for each thread.
*/
class Q_CONCURRENT_EXPORT BlockSizeManager
{
public:
explicit BlockSizeManager(QThreadPool *pool, int iterationCount);
void timeBeforeUser();
void timeAfterUser();
int blockSize();
private:
inline bool blockSizeMaxed()
{
return (m_blockSize >= maxBlockSize);
}
const int maxBlockSize;
qint64 beforeUser;
qint64 afterUser;
Median controlPartElapsed;
Median userPartElapsed;
int m_blockSize;
Q_DISABLE_COPY(BlockSizeManager)
};
template <typename T>
class ResultReporter
{
public:
ResultReporter(ThreadEngine<T> *_threadEngine, T &_defaultValue)
: threadEngine(_threadEngine), defaultValue(_defaultValue)
{
}
void reserveSpace(int resultCount)
{
currentResultCount = resultCount;
resizeList(qMax(resultCount, vector.size()));
}
void reportResults(int begin)
{
const int useVectorThreshold = 4; // Tunable parameter.
if (currentResultCount > useVectorThreshold) {
resizeList(currentResultCount);
threadEngine->reportResults(vector, begin);
} else {
for (int i = 0; i < currentResultCount; ++i)
threadEngine->reportResult(&vector.at(i), begin + i);
}
}
inline T * getPointer()
{
return vector.data();
}
int currentResultCount;
ThreadEngine<T> *threadEngine;
QList<T> vector;
private:
void resizeList(qsizetype size)
{
if constexpr (std::is_default_constructible_v<T>)
vector.resize(size);
else
vector.resize(size, defaultValue);
}
T &defaultValue;
};
template <>
class ResultReporter<void>
{
public:
inline ResultReporter(ThreadEngine<void> *) { }
inline void reserveSpace(int) { }
inline void reportResults(int) { }
inline void * getPointer() { return nullptr; }
};
template<typename T>
struct DefaultValueContainer
{
template<typename U = T>
DefaultValueContainer(U &&_value) : value(std::forward<U>(_value))
{
}
T value;
};
template<>
struct DefaultValueContainer<void>
{
};
inline bool selectIteration(std::bidirectional_iterator_tag)
{
return false; // while
}
inline bool selectIteration(std::forward_iterator_tag)
{
return false; // while
}
inline bool selectIteration(std::random_access_iterator_tag)
{
return true; // for
}
template <typename Iterator, typename T>
class IterateKernel : public ThreadEngine<T>
{
using IteratorCategory = typename std::iterator_traits<Iterator>::iterator_category;
public:
typedef T ResultType;
template<typename U = T, std::enable_if_t<std::is_same_v<U, void>, bool> = true>
IterateKernel(QThreadPool *pool, Iterator _begin, Iterator _end)
: ThreadEngine<U>(pool),
begin(_begin),
end(_end),
current(_begin),
iterationCount(selectIteration(IteratorCategory()) ? std::distance(_begin, _end) : 0),
forIteration(selectIteration(IteratorCategory())),
progressReportingEnabled(true)
{
}
template<typename U = T, std::enable_if_t<!std::is_same_v<U, void>, bool> = true>
IterateKernel(QThreadPool *pool, Iterator _begin, Iterator _end)
: ThreadEngine<U>(pool),
begin(_begin),
end(_end),
current(_begin),
iterationCount(selectIteration(IteratorCategory()) ? std::distance(_begin, _end) : 0),
forIteration(selectIteration(IteratorCategory())),
progressReportingEnabled(true),
defaultValue(U())
{
}
template<typename U = T, std::enable_if_t<!std::is_same_v<U, void>, bool> = true>
IterateKernel(QThreadPool *pool, Iterator _begin, Iterator _end, U &&_defaultValue)
: ThreadEngine<U>(pool),
begin(_begin),
end(_end),
current(_begin),
iterationCount(selectIteration(IteratorCategory()) ? std::distance(_begin, _end) : 0),
forIteration(selectIteration(IteratorCategory())),
progressReportingEnabled(true),
defaultValue(std::forward<U>(_defaultValue))
{
}
virtual ~IterateKernel() { }
virtual bool runIteration(Iterator, int , T *) { return false; }
virtual bool runIterations(Iterator, int, int, T *) { return false; }
void start() override
{
progressReportingEnabled = this->isProgressReportingEnabled();
if (progressReportingEnabled && iterationCount > 0)
this->setProgressRange(0, iterationCount);
}
bool shouldStartThread() override
{
if (forIteration)
return (currentIndex.loadRelaxed() < iterationCount) && !this->shouldThrottleThread();
else // whileIteration
return (iteratorThreads.loadRelaxed() == 0);
}
ThreadFunctionResult threadFunction() override
{
if (forIteration)
return this->forThreadFunction();
else // whileIteration
return this->whileThreadFunction();
}
ThreadFunctionResult forThreadFunction()
{
BlockSizeManager blockSizeManager(ThreadEngineBase::threadPool, iterationCount);
ResultReporter<T> resultReporter = createResultsReporter();
for(;;) {
if (this->isCanceled())
break;
const int currentBlockSize = blockSizeManager.blockSize();
if (currentIndex.loadRelaxed() >= iterationCount)
break;
// Atomically reserve a block of iterationCount for this thread.
const int beginIndex = currentIndex.fetchAndAddRelease(currentBlockSize);
const int endIndex = qMin(beginIndex + currentBlockSize, iterationCount);
if (beginIndex >= endIndex) {
// No more work
break;
}
this->waitForResume(); // (only waits if the qfuture is paused.)
if (shouldStartThread())
this->startThread();
const int finalBlockSize = endIndex - beginIndex; // block size adjusted for possible end-of-range
resultReporter.reserveSpace(finalBlockSize);
// Call user code with the current iteration range.
blockSizeManager.timeBeforeUser();
const bool resultsAvailable = this->runIterations(begin, beginIndex, endIndex, resultReporter.getPointer());
blockSizeManager.timeAfterUser();
if (resultsAvailable)
resultReporter.reportResults(beginIndex);
// Report progress if progress reporting enabled.
if (progressReportingEnabled) {
completed.fetchAndAddAcquire(finalBlockSize);
this->setProgressValue(this->completed.loadRelaxed());
}
if (this->shouldThrottleThread())
return ThrottleThread;
}
return ThreadFinished;
}
ThreadFunctionResult whileThreadFunction()
{
if (iteratorThreads.testAndSetAcquire(0, 1) == false)
return ThreadFinished;
ResultReporter<T> resultReporter = createResultsReporter();
resultReporter.reserveSpace(1);
while (current != end) {
// The following two lines breaks support for input iterators according to
// the sgi docs: dereferencing prev after calling ++current is not allowed
// on input iterators. (prev is dereferenced inside user.runIteration())
Iterator prev = current;
++current;
int index = currentIndex.fetchAndAddRelaxed(1);
iteratorThreads.testAndSetRelease(1, 0);
this->waitForResume(); // (only waits if the qfuture is paused.)
if (shouldStartThread())
this->startThread();
const bool resultAavailable = this->runIteration(prev, index, resultReporter.getPointer());
if (resultAavailable)
resultReporter.reportResults(index);
if (this->shouldThrottleThread())
return ThrottleThread;
if (iteratorThreads.testAndSetAcquire(0, 1) == false)
return ThreadFinished;
}
return ThreadFinished;
}
private:
ResultReporter<T> createResultsReporter()
{
if constexpr (!std::is_same_v<T, void>)
return ResultReporter<T>(this, defaultValue.value);
else
return ResultReporter<T>(this);
}
public:
const Iterator begin;
const Iterator end;
Iterator current;
QAtomicInt currentIndex;
QAtomicInt iteratorThreads;
QAtomicInt completed;
const int iterationCount;
const bool forIteration;
bool progressReportingEnabled;
DefaultValueContainer<ResultType> defaultValue;
};
} // namespace QtConcurrent
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
#endif

View File

@ -0,0 +1,823 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_MAP_H
#define QTCONCURRENT_MAP_H
#if 0
#pragma qt_class(QtConcurrentMap)
#endif
#include <QtConcurrent/qtconcurrent_global.h>
#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
#include <QtConcurrent/qtconcurrentmapkernel.h>
#include <QtConcurrent/qtconcurrentreducekernel.h>
#include <QtConcurrent/qtconcurrentfunctionwrappers.h>
QT_BEGIN_NAMESPACE
namespace QtConcurrent {
// map() on sequences
template <typename Sequence, typename MapFunctor>
QFuture<void> map(QThreadPool *pool, Sequence &&sequence, MapFunctor &&map)
{
return startMap(pool, sequence.begin(), sequence.end(), std::forward<MapFunctor>(map));
}
template <typename Sequence, typename MapFunctor>
QFuture<void> map(Sequence &&sequence, MapFunctor &&map)
{
return startMap(QThreadPool::globalInstance(), sequence.begin(), sequence.end(),
std::forward<MapFunctor>(map));
}
// map() on iterators
template <typename Iterator, typename MapFunctor>
QFuture<void> map(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&map)
{
return startMap(pool, begin, end, std::forward<MapFunctor>(map));
}
template <typename Iterator, typename MapFunctor>
QFuture<void> map(Iterator begin, Iterator end, MapFunctor &&map)
{
return startMap(QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map));
}
// mappedReduced() for sequences.
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
QFuture<ResultType> mappedReduced(QThreadPool *pool,
Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
(pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce), options);
}
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
QFuture<ResultType> mappedReduced(Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
(QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce), options);
}
#ifdef Q_QDOC
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
QFuture<ResultType> mappedReduced(QThreadPool *pool,
Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>(
pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
#ifdef Q_QDOC
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
QFuture<ResultType> mappedReduced(Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
(QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
template <typename Sequence, typename MapFunctor, typename ReduceFunctor,
std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
QFuture<ResultType> mappedReduced(QThreadPool *pool,
Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
(pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce), options);
}
template <typename Sequence, typename MapFunctor, typename ReduceFunctor,
std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
QFuture<ResultType> mappedReduced(Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
(QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce), options);
}
#ifdef Q_QDOC
template <typename Sequence, typename MapFunctor, typename ReduceFunctor, typename ResultType,
typename InitialValueType>
#else
template <typename Sequence, typename MapFunctor, typename ReduceFunctor, typename InitialValueType,
std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
QFuture<ResultType> mappedReduced(QThreadPool *pool,
Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>(
pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
#ifdef Q_QDOC
template <typename Sequence, typename MapFunctor, typename ReduceFunctor, typename ResultType,
typename InitialValueType>
#else
template <typename Sequence, typename MapFunctor, typename ReduceFunctor, typename InitialValueType,
std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
QFuture<ResultType> mappedReduced(Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
(QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
// mappedReduced() for iterators
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
QFuture<ResultType> mappedReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
(pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
options);
}
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
QFuture<ResultType> mappedReduced(Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
(QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce), options);
}
#ifdef Q_QDOC
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
QFuture<ResultType> mappedReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
(pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
#ifdef Q_QDOC
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
QFuture<ResultType> mappedReduced(Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
(QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
QFuture<ResultType> mappedReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>(
pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
options);
}
template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
QFuture<ResultType> mappedReduced(Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
(QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce), options);
}
#ifdef Q_QDOC
template <typename Iterator, typename MapFunctor, typename ReduceFunctor, typename ResultType,
typename InitialValueType>
#else
template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
QFuture<ResultType> mappedReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
(pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
#ifdef Q_QDOC
template <typename Iterator, typename MapFunctor, typename ReduceFunctor, typename ResultType,
typename InitialValueType>
#else
template<typename Iterator, typename MapFunctor, typename ReduceFunctor,
std::enable_if_t<QtPrivate::isIterator_v<Iterator>, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
QFuture<ResultType> mappedReduced(Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
(QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
}
// mapped() for sequences
template <typename Sequence, typename MapFunctor>
QFuture<QtPrivate::MapResultType<Sequence, MapFunctor>> mapped(
QThreadPool *pool,
Sequence &&sequence,
MapFunctor &&map)
{
return startMapped<QtPrivate::MapResultType<Sequence, MapFunctor>>(
pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map));
}
template <typename Sequence, typename MapFunctor>
QFuture<QtPrivate::MapResultType<Sequence, MapFunctor>> mapped(
Sequence &&sequence,
MapFunctor &&map)
{
return startMapped<QtPrivate::MapResultType<Sequence, MapFunctor>>
(QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
std::forward<MapFunctor>(map));
}
// mapped() for iterator ranges.
template <typename Iterator, typename MapFunctor>
QFuture<QtPrivate::MapResultType<Iterator, MapFunctor>> mapped(
QThreadPool *pool,
Iterator begin,
Iterator end,
MapFunctor &&map)
{
return startMapped<QtPrivate::MapResultType<Iterator, MapFunctor>>(
pool, begin, end, std::forward<MapFunctor>(map));
}
template <typename Iterator, typename MapFunctor>
QFuture<QtPrivate::MapResultType<Iterator, MapFunctor>> mapped(
Iterator begin,
Iterator end,
MapFunctor &&map)
{
return startMapped<QtPrivate::MapResultType<Iterator, MapFunctor>>
(QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map));
}
// blockingMap() for sequences
template <typename Sequence, typename MapFunctor>
void blockingMap(QThreadPool *pool, Sequence &&sequence, MapFunctor map)
{
QFuture<void> future =
startMap(pool, sequence.begin(), sequence.end(), std::forward<MapFunctor>(map));
future.waitForFinished();
}
template <typename Sequence, typename MapFunctor>
void blockingMap(Sequence &&sequence, MapFunctor &&map)
{
QFuture<void> future = startMap(QThreadPool::globalInstance(), sequence.begin(), sequence.end(),
std::forward<MapFunctor>(map));
future.waitForFinished();
}
// blockingMap() for iterator ranges
template <typename Iterator, typename MapFunctor>
void blockingMap(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&map)
{
QFuture<void> future = startMap(pool, begin, end, map);
future.waitForFinished();
}
template <typename Iterator, typename MapFunctor>
void blockingMap(Iterator begin, Iterator end, MapFunctor &&map)
{
QFuture<void> future = startMap(QThreadPool::globalInstance(), begin, end,
std::forward<MapFunctor>(map));
future.waitForFinished();
}
// blockingMappedReduced() for sequences
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
ResultType blockingMappedReduced(QThreadPool *pool,
Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future =
mappedReduced<ResultType>(pool, std::forward<Sequence>(sequence),
std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
ResultType blockingMappedReduced(Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future =
mappedReduced<ResultType>(std::forward<Sequence>(sequence),
std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
#ifdef Q_QDOC
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
ResultType blockingMappedReduced(QThreadPool *pool,
Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = mappedReduced<ResultType>(
pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
#ifdef Q_QDOC
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
ResultType blockingMappedReduced(Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = mappedReduced<ResultType>(
std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
template <typename MapFunctor, typename ReduceFunctor, typename Sequence,
std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
ResultType blockingMappedReduced(QThreadPool *pool,
Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future =
mappedReduced<ResultType>(pool, std::forward<Sequence>(sequence),
std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
template <typename MapFunctor, typename ReduceFunctor, typename Sequence,
std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
ResultType blockingMappedReduced(Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future =
mappedReduced<ResultType>(std::forward<Sequence>(sequence),
std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
#ifdef Q_QDOC
template <typename MapFunctor, typename ReduceFunctor, typename Sequence, typename ResultType,
typename InitialValueType>
#else
template <typename MapFunctor, typename ReduceFunctor, typename Sequence, typename InitialValueType,
std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
ResultType blockingMappedReduced(QThreadPool *pool,
Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = mappedReduced<ResultType>(
pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
#ifdef Q_QDOC
template <typename MapFunctor, typename ReduceFunctor, typename Sequence, typename ResultType,
typename InitialValueType>
#else
template<typename MapFunctor, typename ReduceFunctor, typename Sequence, typename InitialValueType,
std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
ResultType blockingMappedReduced(Sequence &&sequence,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = mappedReduced<ResultType>(
std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
// blockingMappedReduced() for iterator ranges
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
ResultType blockingMappedReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future =
mappedReduced<ResultType>(pool, begin, end, std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
ResultType blockingMappedReduced(Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future =
mappedReduced<ResultType>(begin, end, std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
#ifdef Q_QDOC
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
ResultType blockingMappedReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = mappedReduced<ResultType>(
pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)),
options);
return future.takeResult();
}
#ifdef Q_QDOC
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType>
#else
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
ResultType blockingMappedReduced(Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = mappedReduced<ResultType>(
begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)),
options);
return future.takeResult();
}
template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
ResultType blockingMappedReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future =
mappedReduced<ResultType>(pool, begin, end, std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
ResultType blockingMappedReduced(Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future =
mappedReduced<ResultType>(begin, end, std::forward<MapFunctor>(map),
std::forward<ReduceFunctor>(reduce), options);
return future.takeResult();
}
#ifdef Q_QDOC
template <typename Iterator, typename MapFunctor, typename ReduceFunctor, typename ResultType,
typename InitialValueType>
#else
template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
ResultType blockingMappedReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = mappedReduced<ResultType>(
pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
#ifdef Q_QDOC
template <typename Iterator, typename MapFunctor, typename ReduceFunctor, typename ResultType,
typename InitialValueType>
#else
template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
std::enable_if_t<QtPrivate::isIterator_v<Iterator>, int> = 0,
typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
typename InitialValueType,
std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
int> = 0>
#endif
ResultType blockingMappedReduced(Iterator begin,
Iterator end,
MapFunctor &&map,
ReduceFunctor &&reduce,
InitialValueType &&initialValue,
ReduceOptions options = ReduceOptions(UnorderedReduce
| SequentialReduce))
{
QFuture<ResultType> future = mappedReduced<ResultType>(
begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
ResultType(std::forward<InitialValueType>(initialValue)), options);
return future.takeResult();
}
// mapped() for sequences with a different putput sequence type.
template <typename OutputSequence, typename InputSequence, typename MapFunctor>
OutputSequence blockingMapped(QThreadPool *pool, InputSequence &&sequence, MapFunctor &&map)
{
return blockingMappedReduced<OutputSequence>(pool, std::forward<InputSequence>(sequence),
std::forward<MapFunctor>(map),
QtPrivate::PushBackWrapper(), OrderedReduce);
}
template <typename OutputSequence, typename InputSequence, typename MapFunctor>
OutputSequence blockingMapped(InputSequence &&sequence, MapFunctor &&map)
{
return blockingMappedReduced<OutputSequence>(
QThreadPool::globalInstance(), std::forward<InputSequence>(sequence),
std::forward<MapFunctor>(map), QtPrivate::PushBackWrapper(), OrderedReduce);
}
template <typename MapFunctor, typename InputSequence>
auto blockingMapped(QThreadPool *pool, InputSequence &&sequence, MapFunctor &&map)
{
using OutputSequence = typename QtPrivate::MapSequenceResultType<std::decay_t<InputSequence>,
MapFunctor>::ResultType;
return blockingMappedReduced<OutputSequence>(pool, std::forward<InputSequence>(sequence),
std::forward<MapFunctor>(map),
QtPrivate::PushBackWrapper(), OrderedReduce);
}
template <typename MapFunctor, typename InputSequence>
auto blockingMapped(InputSequence &&sequence, MapFunctor &&map)
{
using OutputSequence = typename QtPrivate::MapSequenceResultType<std::decay_t<InputSequence>,
MapFunctor>::ResultType;
return blockingMappedReduced<OutputSequence>(QThreadPool::globalInstance(),
std::forward<InputSequence>(sequence),
std::forward<MapFunctor>(map),
QtPrivate::PushBackWrapper(), OrderedReduce);
}
// mapped() for iterator ranges
template <typename Sequence, typename Iterator, typename MapFunctor>
Sequence blockingMapped(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&map)
{
return blockingMappedReduced<Sequence>(pool, begin, end, std::forward<MapFunctor>(map),
QtPrivate::PushBackWrapper(), OrderedReduce);
}
template <typename Sequence, typename Iterator, typename MapFunctor>
Sequence blockingMapped(Iterator begin, Iterator end, MapFunctor &&map)
{
return blockingMappedReduced<Sequence>(QThreadPool::globalInstance(), begin, end,
std::forward<MapFunctor>(map),
QtPrivate::PushBackWrapper(), OrderedReduce);
}
template <typename Iterator, typename MapFunctor>
auto blockingMapped(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&map)
{
using OutputSequence = QtPrivate::MapResultType<Iterator, MapFunctor>;
return blockingMappedReduced<OutputSequence>(pool, begin, end, std::forward<MapFunctor>(map),
QtPrivate::PushBackWrapper(), OrderedReduce);
}
template <typename Iterator, typename MapFunctor>
auto blockingMapped(Iterator begin, Iterator end, MapFunctor &&map)
{
using OutputSequence = QtPrivate::MapResultType<Iterator, MapFunctor>;
return blockingMappedReduced<OutputSequence>(QThreadPool::globalInstance(), begin, end,
std::forward<MapFunctor>(map),
QtPrivate::PushBackWrapper(), OrderedReduce);
}
} // namespace QtConcurrent
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
#endif

View File

@ -0,0 +1,327 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_MAPKERNEL_H
#define QTCONCURRENT_MAPKERNEL_H
#include <QtConcurrent/qtconcurrent_global.h>
#if !defined(QT_NO_CONCURRENT) || defined (Q_QDOC)
#include <QtConcurrent/qtconcurrentiteratekernel.h>
#include <QtConcurrent/qtconcurrentreducekernel.h>
#include <QtConcurrent/qtconcurrentfunctionwrappers.h>
QT_BEGIN_NAMESPACE
namespace QtConcurrent {
// map kernel, works with both parallel-for and parallel-while
template <typename Iterator, typename MapFunctor>
class MapKernel : public IterateKernel<Iterator, void>
{
MapFunctor map;
public:
typedef void ReturnType;
template <typename F = MapFunctor>
MapKernel(QThreadPool *pool, Iterator begin, Iterator end, F &&_map)
: IterateKernel<Iterator, void>(pool, begin, end), map(std::forward<F>(_map))
{ }
bool runIteration(Iterator it, int, void *) override
{
std::invoke(map, *it);
return false;
}
bool runIterations(Iterator sequenceBeginIterator, int beginIndex, int endIndex, void *) override
{
Iterator it = sequenceBeginIterator;
std::advance(it, beginIndex);
for (int i = beginIndex; i < endIndex; ++i) {
runIteration(it, i, nullptr);
std::advance(it, 1);
}
return false;
}
};
template <typename ReducedResultType,
typename Iterator,
typename MapFunctor,
typename ReduceFunctor,
typename Reducer = ReduceKernel<ReduceFunctor,
ReducedResultType,
QtPrivate::MapResultType<Iterator, MapFunctor>>>
class MappedReducedKernel : public IterateKernel<Iterator, ReducedResultType>
{
ReducedResultType &reducedResult;
MapFunctor map;
ReduceFunctor reduce;
Reducer reducer;
using IntermediateResultsType = QtPrivate::MapResultType<Iterator, MapFunctor>;
public:
typedef ReducedResultType ReturnType;
template<typename F1 = MapFunctor, typename F2 = ReduceFunctor>
MappedReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, F1 &&_map, F2 &&_reduce,
ReduceOptions reduceOptions)
: IterateKernel<Iterator, ReducedResultType>(pool, begin, end),
reducedResult(this->defaultValue.value),
map(std::forward<F1>(_map)),
reduce(std::forward<F2>(_reduce)),
reducer(pool, reduceOptions)
{ }
template<typename F1 = MapFunctor, typename F2 = ReduceFunctor>
MappedReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, F1 &&_map, F2 &&_reduce,
ReducedResultType &&initialValue, ReduceOptions reduceOptions)
: IterateKernel<Iterator, ReducedResultType>(pool, begin, end,
std::forward<ReducedResultType>(initialValue)),
reducedResult(this->defaultValue.value),
map(std::forward<F1>(_map)),
reduce(std::forward<F2>(_reduce)),
reducer(pool, reduceOptions)
{
}
bool runIteration(Iterator it, int index, ReducedResultType *) override
{
IntermediateResults<IntermediateResultsType> results;
results.begin = index;
results.end = index + 1;
results.vector.append(std::invoke(map, *it));
reducer.runReduce(reduce, reducedResult, results);
return false;
}
bool runIterations(Iterator sequenceBeginIterator, int beginIndex, int endIndex, ReducedResultType *) override
{
IntermediateResults<IntermediateResultsType> results;
results.begin = beginIndex;
results.end = endIndex;
results.vector.reserve(endIndex - beginIndex);
Iterator it = sequenceBeginIterator;
std::advance(it, beginIndex);
for (int i = beginIndex; i < endIndex; ++i) {
results.vector.append(std::invoke(map, *it));
std::advance(it, 1);
}
reducer.runReduce(reduce, reducedResult, results);
return false;
}
void finish() override
{
reducer.finish(reduce, reducedResult);
}
bool shouldThrottleThread() override
{
return IterateKernel<Iterator, ReducedResultType>::shouldThrottleThread() || reducer.shouldThrottle();
}
bool shouldStartThread() override
{
return IterateKernel<Iterator, ReducedResultType>::shouldStartThread() && reducer.shouldStartThread();
}
typedef ReducedResultType ResultType;
ReducedResultType *result() override
{
return &reducedResult;
}
};
template <typename Iterator, typename MapFunctor>
class MappedEachKernel : public IterateKernel<Iterator, QtPrivate::MapResultType<Iterator, MapFunctor>>
{
MapFunctor map;
using T = QtPrivate::MapResultType<Iterator, MapFunctor>;
public:
template <typename F = MapFunctor>
MappedEachKernel(QThreadPool *pool, Iterator begin, Iterator end, F &&_map)
: IterateKernel<Iterator, T>(pool, begin, end), map(std::forward<F>(_map))
{ }
bool runIteration(Iterator it, int, T *result) override
{
*result = std::invoke(map, *it);
return true;
}
bool runIterations(Iterator sequenceBeginIterator, int beginIndex, int endIndex, T *results) override
{
Iterator it = sequenceBeginIterator;
std::advance(it, beginIndex);
for (int i = beginIndex; i < endIndex; ++i) {
runIteration(it, i, results + (i - beginIndex));
std::advance(it, 1);
}
return true;
}
};
//! [qtconcurrentmapkernel-1]
template <typename Iterator, typename Functor>
inline ThreadEngineStarter<void> startMap(QThreadPool *pool, Iterator begin,
Iterator end, Functor &&functor)
{
return startThreadEngine(new MapKernel<Iterator, std::decay_t<Functor>>(
pool, begin, end, std::forward<Functor>(functor)));
}
//! [qtconcurrentmapkernel-2]
template <typename T, typename Iterator, typename Functor>
inline ThreadEngineStarter<T> startMapped(QThreadPool *pool, Iterator begin,
Iterator end, Functor &&functor)
{
return startThreadEngine(new MappedEachKernel<Iterator, std::decay_t<Functor>>(
pool, begin, end, std::forward<Functor>(functor)));
}
/*
The SequnceHolder class is used to hold a reference to the
sequence we are working on.
*/
template <typename Sequence, typename Base, typename Functor>
struct SequenceHolder1 : private QtPrivate::SequenceHolder<Sequence>, public Base
{
template<typename S = Sequence, typename F = Functor>
SequenceHolder1(QThreadPool *pool, S &&_sequence, F &&functor)
: QtPrivate::SequenceHolder<Sequence>(std::forward<S>(_sequence)),
Base(pool, this->sequence.cbegin(), this->sequence.cend(), std::forward<F>(functor))
{ }
void finish() override
{
Base::finish();
// Clear the sequence to make sure all temporaries are destroyed
// before finished is signaled.
this->sequence = Sequence();
}
};
//! [qtconcurrentmapkernel-3]
template <typename T, typename Sequence, typename Functor>
inline ThreadEngineStarter<T> startMapped(QThreadPool *pool, Sequence &&sequence,
Functor &&functor)
{
using DecayedSequence = std::decay_t<Sequence>;
using DecayedFunctor = std::decay_t<Functor>;
using SequenceHolderType = SequenceHolder1<
DecayedSequence,
MappedEachKernel<typename DecayedSequence::const_iterator, DecayedFunctor>,
DecayedFunctor>;
return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
std::forward<Functor>(functor)));
}
//! [qtconcurrentmapkernel-4]
template <typename IntermediateType, typename ResultType, typename Sequence, typename MapFunctor,
typename ReduceFunctor>
inline ThreadEngineStarter<ResultType> startMappedReduced(QThreadPool *pool,
Sequence &&sequence,
MapFunctor &&mapFunctor,
ReduceFunctor &&reduceFunctor,
ReduceOptions options)
{
using DecayedSequence = std::decay_t<Sequence>;
using DecayedMapFunctor = std::decay_t<MapFunctor>;
using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
using Iterator = typename DecayedSequence::const_iterator;
using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType, IntermediateType>;
using MappedReduceType = MappedReducedKernel<ResultType, Iterator, DecayedMapFunctor,
DecayedReduceFunctor, Reducer>;
using SequenceHolderType = SequenceHolder2<DecayedSequence, MappedReduceType, DecayedMapFunctor,
DecayedReduceFunctor>;
return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
std::forward<MapFunctor>(mapFunctor),
std::forward<ReduceFunctor>(reduceFunctor),
options));
}
//! [qtconcurrentmapkernel-5]
template <typename IntermediateType, typename ResultType, typename Iterator, typename MapFunctor,
typename ReduceFunctor>
inline ThreadEngineStarter<ResultType> startMappedReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
MapFunctor &&mapFunctor,
ReduceFunctor &&reduceFunctor,
ReduceOptions options)
{
using Reducer =
ReduceKernel<std::decay_t<ReduceFunctor>, std::decay_t<ResultType>, IntermediateType>;
using MappedReduceType = MappedReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
std::decay_t<ReduceFunctor>, Reducer>;
return startThreadEngine(new MappedReduceType(pool, begin, end,
std::forward<MapFunctor>(mapFunctor),
std::forward<ReduceFunctor>(reduceFunctor),
options));
}
//! [qtconcurrentmapkernel-6]
template <typename IntermediateType, typename ResultType, typename Sequence, typename MapFunctor,
typename ReduceFunctor>
inline ThreadEngineStarter<ResultType> startMappedReduced(QThreadPool *pool,
Sequence &&sequence,
MapFunctor &&mapFunctor,
ReduceFunctor &&reduceFunctor,
ResultType &&initialValue,
ReduceOptions options)
{
using DecayedSequence = std::decay_t<Sequence>;
using DecayedMapFunctor = std::decay_t<MapFunctor>;
using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
using Iterator = typename DecayedSequence::const_iterator;
using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType, IntermediateType>;
using MappedReduceType = MappedReducedKernel<ResultType, Iterator, DecayedMapFunctor,
DecayedReduceFunctor, Reducer>;
using SequenceHolderType = SequenceHolder2<DecayedSequence, MappedReduceType, DecayedMapFunctor,
DecayedReduceFunctor>;
return startThreadEngine(
new SequenceHolderType(pool, std::forward<Sequence>(sequence),
std::forward<MapFunctor>(mapFunctor),
std::forward<ReduceFunctor>(reduceFunctor),
std::forward<ResultType>(initialValue), options));
}
//! [qtconcurrentmapkernel-7]
template <typename IntermediateType, typename ResultType, typename Iterator, typename MapFunctor,
typename ReduceFunctor>
inline ThreadEngineStarter<ResultType> startMappedReduced(QThreadPool *pool,
Iterator begin,
Iterator end,
MapFunctor &&mapFunctor,
ReduceFunctor &&reduceFunctor,
ResultType &&initialValue,
ReduceOptions options)
{
using Reducer = ReduceKernel<std::decay_t<ReduceFunctor>, ResultType, IntermediateType>;
using MappedReduceType = MappedReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
std::decay_t<ReduceFunctor>, Reducer>;
return startThreadEngine(new MappedReduceType(pool, begin, end,
std::forward<MapFunctor>(mapFunctor),
std::forward<ReduceFunctor>(reduceFunctor),
std::forward<ResultType>(initialValue), options));
}
} // namespace QtConcurrent
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
#endif

View File

@ -0,0 +1,90 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_MEDIAN_H
#define QTCONCURRENT_MEDIAN_H
#include <QtConcurrent/qtconcurrent_global.h>
#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
#include <algorithm>
#include <cstring>
QT_BEGIN_NAMESPACE
namespace QtConcurrent {
class Median
{
public:
enum { BufferSize = 7 };
Median()
: currentMedian(), currentIndex(0), valid(false), dirty(true)
{
std::fill_n(values, static_cast<int>(BufferSize), 0.0);
}
void reset()
{
std::fill_n(values, static_cast<int>(BufferSize), 0.0);
currentIndex = 0;
valid = false;
dirty = true;
}
void addValue(double value)
{
++currentIndex;
if (currentIndex == BufferSize) {
currentIndex = 0;
valid = true;
}
// Only update the cached median value when we have to, that
// is when the new value is on then other side of the median
// compared to the current value at the index.
const double currentIndexValue = values[currentIndex];
if ((currentIndexValue > currentMedian && currentMedian > value)
|| (currentMedian > currentIndexValue && value > currentMedian)) {
dirty = true;
}
values[currentIndex] = value;
}
bool isMedianValid() const
{
return valid;
}
double median()
{
if (dirty) {
dirty = false;
double sorted[BufferSize];
::memcpy(&sorted, &values, sizeof(sorted));
std::sort(sorted, sorted + static_cast<int>(BufferSize));
currentMedian = sorted[BufferSize / 2];
}
return currentMedian;
}
private:
double values[BufferSize];
double currentMedian;
int currentIndex;
bool valid;
bool dirty;
};
} // namespace QtConcurrent
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
#endif

View File

@ -0,0 +1,237 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_REDUCEKERNEL_H
#define QTCONCURRENT_REDUCEKERNEL_H
#include <QtConcurrent/qtconcurrent_global.h>
#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
#include <QtCore/qatomic.h>
#include <QtCore/qlist.h>
#include <QtCore/qmap.h>
#include <QtCore/qmutex.h>
#include <QtCore/qthread.h>
#include <QtCore/qthreadpool.h>
#include <mutex>
QT_BEGIN_NAMESPACE
namespace QtPrivate {
template<typename Sequence>
struct SequenceHolder
{
SequenceHolder(const Sequence &s) : sequence(s) { }
SequenceHolder(Sequence &&s) : sequence(std::move(s)) { }
Sequence sequence;
};
}
namespace QtConcurrent {
/*
The ReduceQueueStartLimit and ReduceQueueThrottleLimit constants
limit the reduce queue size for MapReduce. When the number of
reduce blocks in the queue exceeds ReduceQueueStartLimit,
MapReduce won't start any new threads, and when it exceeds
ReduceQueueThrottleLimit running threads will be stopped.
*/
#ifdef Q_QDOC
enum ReduceQueueLimits {
ReduceQueueStartLimit = 20,
ReduceQueueThrottleLimit = 30
};
#else
enum {
ReduceQueueStartLimit = 20,
ReduceQueueThrottleLimit = 30
};
#endif
// IntermediateResults holds a block of intermediate results from a
// map or filter functor. The begin/end offsets indicates the origin
// and range of the block.
template <typename T>
class IntermediateResults
{
public:
int begin, end;
QList<T> vector;
};
enum ReduceOption {
UnorderedReduce = 0x1,
OrderedReduce = 0x2,
SequentialReduce = 0x4
// ParallelReduce = 0x8
};
Q_DECLARE_FLAGS(ReduceOptions, ReduceOption)
#ifndef Q_QDOC
Q_DECLARE_OPERATORS_FOR_FLAGS(ReduceOptions)
#endif
// supports both ordered and out-of-order reduction
template <typename ReduceFunctor, typename ReduceResultType, typename T>
class ReduceKernel
{
typedef QMap<int, IntermediateResults<T> > ResultsMap;
const ReduceOptions reduceOptions;
QMutex mutex;
int progress, resultsMapSize;
const int threadCount;
ResultsMap resultsMap;
bool canReduce(int begin) const
{
return (((reduceOptions & UnorderedReduce)
&& progress == 0)
|| ((reduceOptions & OrderedReduce)
&& progress == begin));
}
void reduceResult(ReduceFunctor &reduce,
ReduceResultType &r,
const IntermediateResults<T> &result)
{
for (int i = 0; i < result.vector.size(); ++i) {
std::invoke(reduce, r, result.vector.at(i));
}
}
void reduceResults(ReduceFunctor &reduce,
ReduceResultType &r,
ResultsMap &map)
{
typename ResultsMap::iterator it = map.begin();
while (it != map.end()) {
reduceResult(reduce, r, it.value());
++it;
}
}
public:
ReduceKernel(QThreadPool *pool, ReduceOptions _reduceOptions)
: reduceOptions(_reduceOptions), progress(0), resultsMapSize(0),
threadCount(pool->maxThreadCount())
{ }
void runReduce(ReduceFunctor &reduce,
ReduceResultType &r,
const IntermediateResults<T> &result)
{
std::unique_lock<QMutex> locker(mutex);
if (!canReduce(result.begin)) {
++resultsMapSize;
resultsMap.insert(result.begin, result);
return;
}
if (reduceOptions & UnorderedReduce) {
// UnorderedReduce
progress = -1;
// reduce this result
locker.unlock();
reduceResult(reduce, r, result);
locker.lock();
// reduce all stored results as well
while (!resultsMap.isEmpty()) {
ResultsMap resultsMapCopy = resultsMap;
resultsMap.clear();
locker.unlock();
reduceResults(reduce, r, resultsMapCopy);
locker.lock();
resultsMapSize -= resultsMapCopy.size();
}
progress = 0;
} else {
// reduce this result
locker.unlock();
reduceResult(reduce, r, result);
locker.lock();
// OrderedReduce
progress += result.end - result.begin;
// reduce as many other results as possible
typename ResultsMap::iterator it = resultsMap.begin();
while (it != resultsMap.end()) {
if (it.value().begin != progress)
break;
locker.unlock();
reduceResult(reduce, r, it.value());
locker.lock();
--resultsMapSize;
progress += it.value().end - it.value().begin;
it = resultsMap.erase(it);
}
}
}
// final reduction
void finish(ReduceFunctor &reduce, ReduceResultType &r)
{
reduceResults(reduce, r, resultsMap);
}
inline bool shouldThrottle()
{
std::lock_guard<QMutex> locker(mutex);
return (resultsMapSize > (ReduceQueueThrottleLimit * threadCount));
}
inline bool shouldStartThread()
{
std::lock_guard<QMutex> locker(mutex);
return (resultsMapSize <= (ReduceQueueStartLimit * threadCount));
}
};
template <typename Sequence, typename Base, typename Functor1, typename Functor2>
struct SequenceHolder2 : private QtPrivate::SequenceHolder<Sequence>, public Base
{
template<typename S = Sequence, typename F1 = Functor1, typename F2 = Functor2>
SequenceHolder2(QThreadPool *pool, S &&_sequence, F1 &&functor1, F2 &&functor2,
ReduceOptions reduceOptions)
: QtPrivate::SequenceHolder<Sequence>(std::forward<S>(_sequence)),
Base(pool, this->sequence.cbegin(), this->sequence.cend(),
std::forward<F1>(functor1), std::forward<F2>(functor2), reduceOptions)
{ }
template<typename InitialValueType, typename S = Sequence,
typename F1 = Functor1, typename F2 = Functor2>
SequenceHolder2(QThreadPool *pool, S &&_sequence, F1 &&functor1, F2 &&functor2,
InitialValueType &&initialValue, ReduceOptions reduceOptions)
: QtPrivate::SequenceHolder<Sequence>(std::forward<S>(_sequence)),
Base(pool, this->sequence.cbegin(), this->sequence.cend(),
std::forward<F1>(functor1), std::forward<F2>(functor2),
std::forward<InitialValueType>(initialValue), reduceOptions)
{ }
void finish() override
{
Base::finish();
// Clear the sequence to make sure all temporaries are destroyed
// before finished is signaled.
this->sequence = Sequence();
}
};
} // namespace QtConcurrent
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
#endif

View File

@ -0,0 +1,91 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_RUN_H
#define QTCONCURRENT_RUN_H
#if 0
#pragma qt_class(QtConcurrentRun)
#endif
#include <QtConcurrent/qtconcurrentcompilertest.h>
#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
#include <QtConcurrent/qtconcurrentrunbase.h>
#include <QtConcurrent/qtconcurrentstoredfunctioncall.h>
QT_BEGIN_NAMESPACE
#ifdef Q_QDOC
typedef int Function;
namespace QtConcurrent {
template <typename T>
QFuture<T> run(Function function, ...);
template <typename T>
QFuture<T> run(QThreadPool *pool, Function function, ...);
} // namespace QtConcurrent
#else
namespace QtConcurrent {
template <class Function, class ...Args>
[[nodiscard]]
auto run(QThreadPool *pool, Function &&f, Args &&...args)
{
DecayedTuple<Function, Args...> tuple { std::forward<Function>(f),
std::forward<Args>(args)... };
return TaskResolver<std::decay_t<Function>, std::decay_t<Args>...>::run(
std::move(tuple), TaskStartParameters { pool });
}
template <class Function, class ...Args>
[[nodiscard]]
auto run(QThreadPool *pool, std::reference_wrapper<const Function> &&functionWrapper,
Args &&...args)
{
return run(pool, std::forward<const Function>(functionWrapper.get()),
std::forward<Args>(args)...);
}
template <class Function, class ...Args>
[[nodiscard]]
auto run(Function &&f, Args &&...args)
{
return run(QThreadPool::globalInstance(), std::forward<Function>(f),
std::forward<Args>(args)...);
}
// overload with a Promise Type hint, takes thread pool
template <class PromiseType, class Function, class ...Args>
[[nodiscard]]
auto run(QThreadPool *pool, Function &&f, Args &&...args)
{
return (new StoredFunctionCallWithPromise<Function, PromiseType, Args...>(
std::forward<Function>(f), std::forward<Args>(args)...))->start(pool);
}
// overload with a Promise Type hint, uses global thread pool
template <class PromiseType, class Function, class ...Args>
[[nodiscard]]
auto run(Function &&f, Args &&...args)
{
return run<PromiseType>(QThreadPool::globalInstance(), std::forward<Function>(f),
std::forward<Args>(args)...);
}
} //namespace QtConcurrent
#endif // Q_QDOC
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
#endif

View File

@ -0,0 +1,108 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_RUNBASE_H
#define QTCONCURRENT_RUNBASE_H
#include <QtConcurrent/qtconcurrent_global.h>
#ifndef QT_NO_CONCURRENT
#include <QtCore/qfuture.h>
#include <QtCore/qrunnable.h>
#include <QtCore/qthreadpool.h>
#include <type_traits>
#include <utility>
QT_BEGIN_NAMESPACE
#ifndef Q_QDOC
namespace QtConcurrent {
template <typename T>
struct SelectSpecialization
{
template <class Normal, class Void>
struct Type { typedef Normal type; };
};
template <>
struct SelectSpecialization<void>
{
template <class Normal, class Void>
struct Type { typedef Void type; };
};
struct TaskStartParameters
{
QThreadPool *threadPool = QThreadPool::globalInstance();
int priority = 0;
};
template <typename T>
class RunFunctionTaskBase : public QRunnable
{
public:
QFuture<T> start()
{
return start(TaskStartParameters());
}
QFuture<T> start(const TaskStartParameters &parameters)
{
promise.setThreadPool(parameters.threadPool);
promise.setRunnable(this);
promise.reportStarted();
QFuture<T> theFuture = promise.future();
if (parameters.threadPool) {
parameters.threadPool->start(this, parameters.priority);
} else {
promise.reportCanceled();
promise.reportFinished();
delete this;
}
return theFuture;
}
// For backward compatibility
QFuture<T> start(QThreadPool *pool) { return start({pool, 0}); }
void run() override
{
if (promise.isCanceled()) {
promise.reportFinished();
return;
}
#ifndef QT_NO_EXCEPTIONS
try {
#endif
runFunctor();
#ifndef QT_NO_EXCEPTIONS
} catch (QException &e) {
promise.reportException(e);
} catch (...) {
promise.reportException(QUnhandledException(std::current_exception()));
}
#endif
promise.reportFinished();
}
protected:
virtual void runFunctor() = 0;
QFutureInterface<T> promise;
};
} //namespace QtConcurrent
#endif //Q_QDOC
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
#endif

View File

@ -0,0 +1,230 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_STOREDFUNCTIONCALL_H
#define QTCONCURRENT_STOREDFUNCTIONCALL_H
#include <QtConcurrent/qtconcurrent_global.h>
#ifndef QT_NO_CONCURRENT
#include <QtConcurrent/qtconcurrentrunbase.h>
#include <QtCore/qpromise.h>
#include <type_traits>
QT_BEGIN_NAMESPACE
#ifndef Q_QDOC
namespace QtConcurrent {
template<typename...>
struct NonMemberFunctionResolver;
template <class Function, class PromiseType, class... Args>
struct NonMemberFunctionResolver<Function, PromiseType, Args...>
{
using Type = std::tuple<std::decay_t<Function>, QPromise<PromiseType> &, std::decay_t<Args>...>;
static_assert(std::is_invocable_v<std::decay_t<Function>, QPromise<PromiseType> &, std::decay_t<Args>...>,
"It's not possible to invoke the function with passed arguments.");
static_assert(std::is_void_v<std::invoke_result_t<std::decay_t<Function>, QPromise<PromiseType> &, std::decay_t<Args>...>>,
"The function must return void type.");
static constexpr void invoke(std::decay_t<Function> function, QPromise<PromiseType> &promise,
std::decay_t<Args>... args)
{
std::invoke(function, promise, args...);
}
static Type initData(Function &&f, QPromise<PromiseType> &promise, Args &&...args)
{
return Type { std::forward<Function>(f), std::ref(promise), std::forward<Args>(args)... };
}
};
template<typename...>
struct MemberFunctionResolver;
template <typename Function, typename PromiseType, typename Arg, typename ... Args>
struct MemberFunctionResolver<Function, PromiseType, Arg, Args...>
{
using Type = std::tuple<std::decay_t<Function>, std::decay_t<Arg>, QPromise<PromiseType> &, std::decay_t<Args>...>;
static_assert(std::is_invocable_v<std::decay_t<Function>, std::decay_t<Arg>, QPromise<PromiseType> &, std::decay_t<Args>...>,
"It's not possible to invoke the function with passed arguments.");
static_assert(std::is_void_v<std::invoke_result_t<std::decay_t<Function>, std::decay_t<Arg>, QPromise<PromiseType> &, std::decay_t<Args>...>>,
"The function must return void type.");
static constexpr void invoke(std::decay_t<Function> function, std::decay_t<Arg> object,
QPromise<PromiseType> &promise, std::decay_t<Args>... args)
{
std::invoke(function, object, promise, args...);
}
static Type initData(Function &&f, QPromise<PromiseType> &promise, Arg &&fa, Args &&...args)
{
return Type { std::forward<Function>(f), std::forward<Arg>(fa), std::ref(promise), std::forward<Args>(args)... };
}
};
template <class IsMember, class Function, class PromiseType, class... Args>
struct FunctionResolverHelper;
template <class Function, class PromiseType, class... Args>
struct FunctionResolverHelper<std::false_type, Function, PromiseType, Args...>
: public NonMemberFunctionResolver<Function, PromiseType, Args...>
{
};
template <class Function, class PromiseType, class... Args>
struct FunctionResolverHelper<std::true_type, Function, PromiseType, Args...>
: public MemberFunctionResolver<Function, PromiseType, Args...>
{
};
template <class Function, class PromiseType, class... Args>
struct FunctionResolver
: public FunctionResolverHelper<typename std::is_member_function_pointer<
std::decay_t<Function>>::type, Function, PromiseType, Args...>
{
};
template <class Function, class ...Args>
struct InvokeResult
{
static_assert(std::is_invocable_v<std::decay_t<Function>, std::decay_t<Args>...>,
"It's not possible to invoke the function with passed arguments.");
using Type = std::invoke_result_t<std::decay_t<Function>, std::decay_t<Args>...>;
};
template <class Function, class ...Args>
using InvokeResultType = typename InvokeResult<Function, Args...>::Type;
template <class ...Types>
using DecayedTuple = std::tuple<std::decay_t<Types>...>;
template <class Function, class ...Args>
struct StoredFunctionCall : public RunFunctionTaskBase<InvokeResultType<Function, Args...>>
{
StoredFunctionCall(DecayedTuple<Function, Args...> &&_data)
: data(std::move(_data))
{}
protected:
void runFunctor() override
{
constexpr auto invoke = [] (std::decay_t<Function> function,
std::decay_t<Args>... args) -> auto {
return std::invoke(function, args...);
};
if constexpr (std::is_void_v<InvokeResultType<Function, Args...>>) {
std::apply(invoke, std::move(data));
} else {
auto result = std::apply(invoke, std::move(data));
using T = InvokeResultType<Function, Args...>;
if constexpr (std::is_move_constructible_v<T>)
this->promise.reportAndMoveResult(std::move(result));
else if constexpr (std::is_copy_constructible_v<T>)
this->promise.reportResult(result);
}
}
private:
DecayedTuple<Function, Args...> data;
};
template <class Function, class PromiseType, class ...Args>
struct StoredFunctionCallWithPromise : public RunFunctionTaskBase<PromiseType>
{
using Resolver = FunctionResolver<Function, PromiseType, Args...>;
using DataType = typename Resolver::Type;
StoredFunctionCallWithPromise(Function &&f, Args &&...args)
: prom(this->promise),
data(std::move(Resolver::initData(std::forward<Function>(f), std::ref(prom),
std::forward<Args>(args)...)))
{}
StoredFunctionCallWithPromise(DecayedTuple<Function, Args...> &&_data)
: StoredFunctionCallWithPromise(std::move(_data),
std::index_sequence_for<std::decay_t<Function>, std::decay_t<Args>...>())
{}
protected:
void runFunctor() override
{
std::apply(Resolver::invoke, std::move(data));
}
private:
// helper to pack back the tuple into parameter pack
template<std::size_t... Is>
StoredFunctionCallWithPromise(DecayedTuple<Function, Args...> &&_data,
std::index_sequence<Is...>)
: StoredFunctionCallWithPromise(std::move(std::get<Is>(_data))...)
{}
QPromise<PromiseType> prom;
DataType data;
};
template<typename...>
struct NonPromiseTaskResolver;
template <typename Function, typename ... Args>
struct NonPromiseTaskResolver<Function, Args...>
{
using TaskWithArgs = DecayedTuple<Function, Args...>;
static auto run(TaskWithArgs &&args, const TaskStartParameters &startParameters) {
return (new StoredFunctionCall<Function, Args...>(std::move(args)))
->start(startParameters);
}
};
template<typename...>
struct PromiseTaskResolver;
template <typename Function, typename ... Args>
struct PromiseTaskResolver<Function, Args...>
{
static_assert(QtPrivate::ArgResolver<Function>::IsPromise::value,
"The first argument of passed callable object isn't a QPromise<T> & type. "
"Did you intend to pass a callable which takes a QPromise<T> & type as a first argument? "
"Otherwise it's not possible to invoke the function with passed arguments.");
using TaskWithArgs = DecayedTuple<Function, Args...>;
static auto run(TaskWithArgs &&args, const TaskStartParameters &startParameters) {
using PromiseType = typename QtPrivate::ArgResolver<Function>::PromiseType;
return (new StoredFunctionCallWithPromise<Function, PromiseType, Args...>(std::move(args)))
->start(startParameters);
}
};
template <class IsDirectlyInvocable, class Function, class... Args>
struct TaskResolverHelper;
template <class Function, class... Args>
struct TaskResolverHelper<std::true_type, Function, Args...>
: public NonPromiseTaskResolver<Function, Args...>
{
};
template <class Function, class... Args>
struct TaskResolverHelper<std::false_type, Function, Args...>
: public PromiseTaskResolver<Function, Args...>
{
};
template <class Function, class... Args>
struct TaskResolver : public TaskResolverHelper<typename std::is_invocable<std::decay_t<Function>,
std::decay_t<Args>...>::type, Function, Args...>
{
};
} //namespace QtConcurrent
#endif // Q_QDOC
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
#endif

View File

@ -0,0 +1,39 @@
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENTTASK_H
#define QTCONCURRENTTASK_H
#if !defined(QT_NO_CONCURRENT)
#include <QtConcurrent/qtaskbuilder.h>
QT_BEGIN_NAMESPACE
#ifdef Q_QDOC
namespace QtConcurrent {
template <class Task>
[[nodiscard]]
QTaskBuilder<Task> task(Task &&task);
} // namespace QtConcurrent
#else
namespace QtConcurrent {
template <class Task>
[[nodiscard]]
constexpr auto task(Task &&t) { return QTaskBuilder(std::forward<Task>(t)); }
} // namespace QtConcurrent
#endif // Q_QDOC
QT_END_NAMESPACE
#endif // !defined(QT_NO_CONCURRENT)
#endif // QTCONCURRENTTASK_H

View File

@ -0,0 +1,224 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_THREADENGINE_H
#define QTCONCURRENT_THREADENGINE_H
#include <QtConcurrent/qtconcurrent_global.h>
#if !defined(QT_NO_CONCURRENT) ||defined(Q_QDOC)
#include <QtCore/qthreadpool.h>
#include <QtCore/qfuture.h>
#include <QtCore/qdebug.h>
#include <QtCore/qexception.h>
#include <QtCore/qwaitcondition.h>
#include <QtCore/qatomic.h>
#include <QtCore/qsemaphore.h>
QT_BEGIN_NAMESPACE
namespace QtConcurrent {
// The ThreadEngineBarrier counts worker threads, and allows one
// thread to wait for all others to finish. Tested for its use in
// QtConcurrent, requires more testing for use as a general class.
class ThreadEngineBarrier
{
private:
// The thread count is maintained as an integer in the count atomic
// variable. The count can be either positive or negative - a negative
// count signals that a thread is waiting on the barrier.
QAtomicInt count;
QSemaphore semaphore;
public:
ThreadEngineBarrier();
void acquire();
int release();
void wait();
int currentCount();
bool releaseUnlessLast();
};
enum ThreadFunctionResult { ThrottleThread, ThreadFinished };
// The ThreadEngine controls the threads used in the computation.
// Can be run in three modes: single threaded, multi-threaded blocking
// and multi-threaded asynchronous.
// The code for the single threaded mode is
class Q_CONCURRENT_EXPORT ThreadEngineBase: public QRunnable
{
public:
// Public API:
ThreadEngineBase(QThreadPool *pool);
virtual ~ThreadEngineBase();
void startSingleThreaded();
void startThread();
bool isCanceled();
void waitForResume();
bool isProgressReportingEnabled();
void setProgressValue(int progress);
void setProgressRange(int minimum, int maximum);
void acquireBarrierSemaphore();
void reportIfSuspensionDone() const;
protected: // The user overrides these:
virtual void start() {}
virtual void finish() {}
virtual ThreadFunctionResult threadFunction() { return ThreadFinished; }
virtual bool shouldStartThread() { return !shouldThrottleThread(); }
virtual bool shouldThrottleThread()
{
return futureInterface ? (futureInterface->isSuspending() || futureInterface->isSuspended())
: false;
}
private:
bool startThreadInternal();
void startThreads();
void threadExit();
bool threadThrottleExit();
void run() override;
virtual void asynchronousFinish() = 0;
#ifndef QT_NO_EXCEPTIONS
void handleException(const QException &exception);
#endif
protected:
QFutureInterfaceBase *futureInterface;
QThreadPool *threadPool;
ThreadEngineBarrier barrier;
QtPrivate::ExceptionStore exceptionStore;
QBasicMutex mutex;
};
template <typename T>
class ThreadEngine : public ThreadEngineBase
{
public:
typedef T ResultType;
ThreadEngine(QThreadPool *pool) : ThreadEngineBase(pool) {}
virtual T *result() { return nullptr; }
QFutureInterface<T> *futureInterfaceTyped()
{
return static_cast<QFutureInterface<T> *>(futureInterface);
}
// Runs the user algorithm using a single thread.
T *startSingleThreaded()
{
ThreadEngineBase::startSingleThreaded();
return result();
}
// Runs the user algorithm using multiple threads.
// Does not block, returns a future.
QFuture<T> startAsynchronously()
{
futureInterface = new QFutureInterface<T>();
// reportStart() must be called before starting threads, otherwise the
// user algorithm might finish while reportStart() is running, which
// is very bad.
futureInterface->reportStarted();
QFuture<T> future = QFuture<T>(futureInterfaceTyped());
start();
acquireBarrierSemaphore();
threadPool->start(this);
return future;
}
void asynchronousFinish() override
{
finish();
futureInterfaceTyped()->reportFinished(result());
delete futureInterfaceTyped();
delete this;
}
void reportResult(const T *_result, int index = -1)
{
if (futureInterface)
futureInterfaceTyped()->reportResult(_result, index);
}
void reportResults(const QList<T> &_result, int index = -1, int count = -1)
{
if (futureInterface)
futureInterfaceTyped()->reportResults(_result, index, count);
}
};
// The ThreadEngineStarter class ecapsulates the return type
// from the thread engine.
// Depending on how the it is used, it will run
// the engine in either blocking mode or asynchronous mode.
template <typename T>
class ThreadEngineStarterBase
{
public:
ThreadEngineStarterBase(ThreadEngine<T> *_threadEngine)
: threadEngine(_threadEngine) { }
inline ThreadEngineStarterBase(const ThreadEngineStarterBase &other)
: threadEngine(other.threadEngine) { }
QFuture<T> startAsynchronously()
{
return threadEngine->startAsynchronously();
}
operator QFuture<T>()
{
return startAsynchronously();
}
protected:
ThreadEngine<T> *threadEngine;
};
// We need to factor out the code that dereferences the T pointer,
// with a specialization where T is void. (code that dereferences a void *
// won't compile)
template <typename T>
class ThreadEngineStarter : public ThreadEngineStarterBase<T>
{
typedef ThreadEngineStarterBase<T> Base;
typedef ThreadEngine<T> TypedThreadEngine;
public:
ThreadEngineStarter(TypedThreadEngine *eng)
: Base(eng) { }
};
// Full template specialization where T is void.
template <>
class ThreadEngineStarter<void> : public ThreadEngineStarterBase<void>
{
public:
ThreadEngineStarter(ThreadEngine<void> *_threadEngine)
: ThreadEngineStarterBase<void>(_threadEngine) {}
};
//! [qtconcurrentthreadengine-1]
template <typename ThreadEngine>
inline ThreadEngineStarter<typename ThreadEngine::ResultType> startThreadEngine(ThreadEngine *threadEngine)
{
return ThreadEngineStarter<typename ThreadEngine::ResultType>(threadEngine);
}
} // namespace QtConcurrent
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
#endif

View File

@ -0,0 +1,9 @@
/* This file was generated by syncqt. */
#ifndef QT_QTCONCURRENT_VERSION_H
#define QT_QTCONCURRENT_VERSION_H
#define QTCONCURRENT_VERSION_STR "6.5.0"
#define QTCONCURRENT_VERSION 0x060500
#endif // QT_QTCONCURRENT_VERSION_H

View File

@ -0,0 +1,277 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTANIMATION_P_H
#define QABSTRACTANIMATION_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API.
// This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qbasictimer.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qtimer.h>
#include <QtCore/qelapsedtimer.h>
#include <private/qobject_p.h>
#include <private/qproperty_p.h>
#include <qabstractanimation.h>
QT_REQUIRE_CONFIG(animation);
QT_BEGIN_NAMESPACE
class QAnimationGroup;
class QAbstractAnimation;
class QAbstractAnimationPrivate : public QObjectPrivate
{
public:
QAbstractAnimationPrivate();
virtual ~QAbstractAnimationPrivate();
static QAbstractAnimationPrivate *get(QAbstractAnimation *q)
{
return q->d_func();
}
Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QAbstractAnimationPrivate, QAbstractAnimation::State,
state, QAbstractAnimation::Stopped)
void setState(QAbstractAnimation::State state);
void setDirection(QAbstractAnimation::Direction direction)
{
q_func()->setDirection(direction);
}
void emitDirectionChanged() { emit q_func()->directionChanged(direction); }
Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QAbstractAnimationPrivate, QAbstractAnimation::Direction,
direction, &QAbstractAnimationPrivate::setDirection,
&QAbstractAnimationPrivate::emitDirectionChanged,
QAbstractAnimation::Forward)
void setCurrentTime(int msecs) { q_func()->setCurrentTime(msecs); }
Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QAbstractAnimationPrivate, int, totalCurrentTime,
&QAbstractAnimationPrivate::setCurrentTime, 0)
int currentTime = 0;
Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QAbstractAnimationPrivate, int, loopCount, 1)
void emitCurrentLoopChanged() { emit q_func()->currentLoopChanged(currentLoop); }
Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QAbstractAnimationPrivate, int, currentLoop, nullptr,
&QAbstractAnimationPrivate::emitCurrentLoopChanged, 0)
bool deleteWhenStopped = false;
bool hasRegisteredTimer = false;
bool isPause = false;
bool isGroup = false;
QAnimationGroup *group = nullptr;
private:
Q_DECLARE_PUBLIC(QAbstractAnimation)
};
class QUnifiedTimer;
class QDefaultAnimationDriver : public QAnimationDriver
{
Q_OBJECT
public:
explicit QDefaultAnimationDriver(QUnifiedTimer *timer);
~QDefaultAnimationDriver() override;
protected:
void timerEvent(QTimerEvent *e) override;
private Q_SLOTS:
void startTimer();
void stopTimer();
private:
QBasicTimer m_timer;
QUnifiedTimer *m_unified_timer;
};
class Q_CORE_EXPORT QAnimationDriverPrivate : public QObjectPrivate
{
public:
QAnimationDriverPrivate();
~QAnimationDriverPrivate() override;
QElapsedTimer timer;
bool running = false;
};
class Q_CORE_EXPORT QAbstractAnimationTimer : public QObject
{
Q_OBJECT
public:
QAbstractAnimationTimer();
~QAbstractAnimationTimer() override;
virtual void updateAnimationsTime(qint64 delta) = 0;
virtual void restartAnimationTimer() = 0;
virtual int runningAnimationCount() = 0;
bool isRegistered = false;
bool isPaused = false;
int pauseDuration = 0;
};
class Q_CORE_EXPORT QUnifiedTimer : public QObject
{
Q_OBJECT
private:
QUnifiedTimer();
public:
~QUnifiedTimer() override;
static QUnifiedTimer *instance();
static QUnifiedTimer *instance(bool create);
static void startAnimationTimer(QAbstractAnimationTimer *timer);
static void stopAnimationTimer(QAbstractAnimationTimer *timer);
static void pauseAnimationTimer(QAbstractAnimationTimer *timer, int duration);
static void resumeAnimationTimer(QAbstractAnimationTimer *timer);
//defines the timing interval. Default is DEFAULT_TIMER_INTERVAL
void setTimingInterval(int interval);
/*
this allows to have a consistent timer interval at each tick from the timer
not taking the real time that passed into account.
*/
void setConsistentTiming(bool consistent) { consistentTiming = consistent; }
//these facilitate fine-tuning of complex animations
void setSlowModeEnabled(bool enabled) { slowMode = enabled; }
void setSlowdownFactor(qreal factor) { slowdownFactor = factor; }
void installAnimationDriver(QAnimationDriver *driver);
void uninstallAnimationDriver(QAnimationDriver *driver);
bool canUninstallAnimationDriver(QAnimationDriver *driver);
void restart();
void maybeUpdateAnimationsToCurrentTime();
void updateAnimationTimers();
//useful for profiling/debugging
int runningAnimationCount();
void registerProfilerCallback(void (*cb)(qint64));
void startAnimationDriver();
void stopAnimationDriver();
qint64 elapsed() const;
protected:
void timerEvent(QTimerEvent *) override;
private Q_SLOTS:
void startTimers();
void stopTimer();
private:
friend class QDefaultAnimationDriver;
friend class QAnimationDriver;
QAnimationDriver *driver;
QDefaultAnimationDriver defaultDriver;
QBasicTimer pauseTimer;
QElapsedTimer time;
qint64 lastTick;
int timingInterval;
int currentAnimationIdx;
bool insideTick;
bool insideRestart;
bool consistentTiming;
bool slowMode;
bool startTimersPending;
bool stopTimerPending;
bool allowNegativeDelta;
// This factor will be used to divide the DEFAULT_TIMER_INTERVAL at each tick
// when slowMode is enabled. Setting it to 0 or higher than DEFAULT_TIMER_INTERVAL (16)
// stops all animations.
qreal slowdownFactor;
QList<QAbstractAnimationTimer*> animationTimers, animationTimersToStart;
QList<QAbstractAnimationTimer*> pausedAnimationTimers;
void localRestart();
int closestPausedAnimationTimerTimeToFinish();
void (*profilerCallback)(qint64);
qint64 driverStartTime; // The time the animation driver was started
qint64 temporalDrift; // The delta between animation driver time and wall time.
};
class QAnimationTimer : public QAbstractAnimationTimer
{
Q_OBJECT
private:
QAnimationTimer();
public:
~QAnimationTimer() override;
static QAnimationTimer *instance();
static QAnimationTimer *instance(bool create);
static void registerAnimation(QAbstractAnimation *animation, bool isTopLevel);
static void unregisterAnimation(QAbstractAnimation *animation);
/*
this is used for updating the currentTime of all animations in case the pause
timer is active or, otherwise, only of the animation passed as parameter.
*/
static void ensureTimerUpdate();
/*
this will evaluate the need of restarting the pause timer in case there is still
some pause animations running.
*/
static void updateAnimationTimer();
void restartAnimationTimer() override;
void updateAnimationsTime(qint64 delta) override;
//useful for profiling/debugging
int runningAnimationCount() override { return animations.size(); }
private Q_SLOTS:
void startAnimations();
void stopTimer();
private:
qint64 lastTick;
int currentAnimationIdx;
bool insideTick;
bool startAnimationPending;
bool stopTimerPending;
QList<QAbstractAnimation*> animations, animationsToStart;
// this is the count of running animations that are not a group neither a pause animation
int runningLeafAnimations;
QList<QAbstractAnimation*> runningPauseAnimations;
void registerRunningAnimation(QAbstractAnimation *animation);
void unregisterRunningAnimation(QAbstractAnimation *animation);
int closestPauseAnimationTimeToFinish();
};
QT_END_NAMESPACE
#endif //QABSTRACTANIMATION_P_H

View File

@ -0,0 +1,41 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTEVENTDISPATCHER_P_H
#define QABSTRACTEVENTDISPATCHER_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "QtCore/qabstracteventdispatcher.h"
#include "private/qobject_p.h"
QT_BEGIN_NAMESPACE
Q_AUTOTEST_EXPORT qsizetype qGlobalPostedEventsCount();
class Q_CORE_EXPORT QAbstractEventDispatcherPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QAbstractEventDispatcher)
public:
inline QAbstractEventDispatcherPrivate()
{ }
~QAbstractEventDispatcherPrivate() override;
QList<QAbstractNativeEventFilter *> eventFilters;
static int allocateTimerId();
static void releaseTimerId(int id);
};
QT_END_NAMESPACE
#endif // QABSTRACTEVENTDISPATCHER_P_H

View File

@ -0,0 +1,244 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTFILEENGINE_P_H
#define QABSTRACTFILEENGINE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
#include "QtCore/qfile.h"
#include "QtCore/qdir.h"
#include <optional>
#ifdef open
#error qabstractfileengine_p.h must be included before any header file that defines open
#endif
QT_BEGIN_NAMESPACE
class QVariant;
class QAbstractFileEngineIterator;
class QAbstractFileEnginePrivate;
class Q_CORE_EXPORT QAbstractFileEngine
{
public:
enum FileFlag {
//perms (overlaps the QFile::Permission)
ReadOwnerPerm = 0x4000, WriteOwnerPerm = 0x2000, ExeOwnerPerm = 0x1000,
ReadUserPerm = 0x0400, WriteUserPerm = 0x0200, ExeUserPerm = 0x0100,
ReadGroupPerm = 0x0040, WriteGroupPerm = 0x0020, ExeGroupPerm = 0x0010,
ReadOtherPerm = 0x0004, WriteOtherPerm = 0x0002, ExeOtherPerm = 0x0001,
//types
LinkType = 0x10000,
FileType = 0x20000,
DirectoryType = 0x40000,
BundleType = 0x80000,
//flags
HiddenFlag = 0x0100000,
LocalDiskFlag = 0x0200000,
ExistsFlag = 0x0400000,
RootFlag = 0x0800000,
Refresh = 0x1000000,
//masks
PermsMask = 0x0000FFFF,
TypesMask = 0x000F0000,
FlagsMask = 0x0FF00000,
FileInfoAll = FlagsMask | PermsMask | TypesMask
};
Q_DECLARE_FLAGS(FileFlags, FileFlag)
enum FileName {
DefaultName,
BaseName,
PathName,
AbsoluteName,
AbsolutePathName,
AbsoluteLinkTarget,
CanonicalName,
CanonicalPathName,
BundleName,
JunctionName,
NFileNames // Must be last.
};
enum FileOwner {
OwnerUser,
OwnerGroup
};
enum FileTime {
AccessTime,
BirthTime,
MetadataChangeTime,
ModificationTime
};
virtual ~QAbstractFileEngine();
virtual bool open(QIODevice::OpenMode openMode,
std::optional<QFile::Permissions> permissions = std::nullopt);
virtual bool close();
virtual bool flush();
virtual bool syncToDisk();
virtual qint64 size() const;
virtual qint64 pos() const;
virtual bool seek(qint64 pos);
virtual bool isSequential() const;
virtual bool remove();
virtual bool copy(const QString &newName);
virtual bool rename(const QString &newName);
virtual bool renameOverwrite(const QString &newName);
virtual bool link(const QString &newName);
virtual bool mkdir(const QString &dirName, bool createParentDirectories,
std::optional<QFile::Permissions> permissions = std::nullopt) const;
virtual bool rmdir(const QString &dirName, bool recurseParentDirectories) const;
virtual bool setSize(qint64 size);
virtual bool caseSensitive() const;
virtual bool isRelativePath() const;
virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const;
virtual FileFlags fileFlags(FileFlags type=FileInfoAll) const;
virtual bool setPermissions(uint perms);
virtual QByteArray id() const;
virtual QString fileName(FileName file=DefaultName) const;
virtual uint ownerId(FileOwner) const;
virtual QString owner(FileOwner) const;
virtual bool setFileTime(const QDateTime &newDate, FileTime time);
virtual QDateTime fileTime(FileTime time) const;
virtual void setFileName(const QString &file);
virtual int handle() const;
virtual bool cloneTo(QAbstractFileEngine *target);
bool atEnd() const;
uchar *map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags);
bool unmap(uchar *ptr);
typedef QAbstractFileEngineIterator Iterator;
virtual Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames);
virtual Iterator *endEntryList();
virtual qint64 read(char *data, qint64 maxlen);
virtual qint64 readLine(char *data, qint64 maxlen);
virtual qint64 write(const char *data, qint64 len);
QFile::FileError error() const;
QString errorString() const;
enum Extension {
AtEndExtension,
FastReadLineExtension,
MapExtension,
UnMapExtension
};
class ExtensionOption
{};
class ExtensionReturn
{};
class MapExtensionOption : public ExtensionOption {
public:
qint64 offset;
qint64 size;
QFile::MemoryMapFlags flags;
};
class MapExtensionReturn : public ExtensionReturn {
public:
uchar *address;
};
class UnMapExtensionOption : public ExtensionOption {
public:
uchar *address;
};
virtual bool extension(Extension extension, const ExtensionOption *option = nullptr, ExtensionReturn *output = nullptr);
virtual bool supportsExtension(Extension extension) const;
// Factory
static QAbstractFileEngine *create(const QString &fileName);
protected:
void setError(QFile::FileError error, const QString &str);
QAbstractFileEngine();
QAbstractFileEngine(QAbstractFileEnginePrivate &);
QScopedPointer<QAbstractFileEnginePrivate> d_ptr;
private:
Q_DECLARE_PRIVATE(QAbstractFileEngine)
Q_DISABLE_COPY_MOVE(QAbstractFileEngine)
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractFileEngine::FileFlags)
class Q_CORE_EXPORT QAbstractFileEngineHandler
{
public:
QAbstractFileEngineHandler();
virtual ~QAbstractFileEngineHandler();
virtual QAbstractFileEngine *create(const QString &fileName) const = 0;
};
class QAbstractFileEngineIteratorPrivate;
class Q_CORE_EXPORT QAbstractFileEngineIterator
{
public:
QAbstractFileEngineIterator(QDir::Filters filters, const QStringList &nameFilters);
virtual ~QAbstractFileEngineIterator();
virtual QString next() = 0;
virtual bool hasNext() const = 0;
QString path() const;
QStringList nameFilters() const;
QDir::Filters filters() const;
virtual QString currentFileName() const = 0;
virtual QFileInfo currentFileInfo() const;
virtual QString currentFilePath() const;
protected:
enum EntryInfoType {
};
virtual QVariant entryInfo(EntryInfoType type) const;
private:
Q_DISABLE_COPY_MOVE(QAbstractFileEngineIterator)
friend class QDirIterator;
friend class QDirIteratorPrivate;
void setPath(const QString &path);
QScopedPointer<QAbstractFileEngineIteratorPrivate> d;
};
class QAbstractFileEnginePrivate
{
public:
inline QAbstractFileEnginePrivate()
: fileError(QFile::UnspecifiedError)
{
}
inline virtual ~QAbstractFileEnginePrivate() { }
QFile::FileError fileError;
QString errorString;
QAbstractFileEngine *q_ptr;
Q_DECLARE_PUBLIC(QAbstractFileEngine)
};
QAbstractFileEngine *qt_custom_file_engine_handler_create(const QString &path);
QT_END_NAMESPACE
#endif // QABSTRACTFILEENGINE_P_H

View File

@ -0,0 +1,176 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTITEMMODEL_P_H
#define QABSTRACTITEMMODEL_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of QAbstractItemModel*. This header file may change from version
// to version without notice, or even be removed.
//
// We mean it.
//
//
#include "QtCore/qabstractitemmodel.h"
#include "QtCore/private/qobject_p.h"
#include "QtCore/qstack.h"
#include "QtCore/qset.h"
#include "QtCore/qhash.h"
QT_BEGIN_NAMESPACE
QT_REQUIRE_CONFIG(itemmodel);
class QPersistentModelIndexData
{
public:
QPersistentModelIndexData() {}
QPersistentModelIndexData(const QModelIndex &idx) : index(idx) {}
QModelIndex index;
QAtomicInt ref;
static QPersistentModelIndexData *create(const QModelIndex &index);
static void destroy(QPersistentModelIndexData *data);
};
class Q_CORE_EXPORT QAbstractItemModelPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QAbstractItemModel)
public:
QAbstractItemModelPrivate();
~QAbstractItemModelPrivate();
void removePersistentIndexData(QPersistentModelIndexData *data);
void movePersistentIndexes(const QList<QPersistentModelIndexData *> &indexes, int change, const QModelIndex &parent,
Qt::Orientation orientation);
void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last);
void rowsInserted(const QModelIndex &parent, int first, int last);
void rowsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
void rowsRemoved(const QModelIndex &parent, int first, int last);
void columnsAboutToBeInserted(const QModelIndex &parent, int first, int last);
void columnsInserted(const QModelIndex &parent, int first, int last);
void columnsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
void columnsRemoved(const QModelIndex &parent, int first, int last);
static QAbstractItemModel *staticEmptyModel();
static bool variantLessThan(const QVariant &v1, const QVariant &v2);
void itemsAboutToBeMoved(const QModelIndex &srcParent, int srcFirst, int srcLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation);
void itemsMoved(const QModelIndex &srcParent, int srcFirst, int srcLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation orientation);
bool allowMove(const QModelIndex &srcParent, int srcFirst, int srcLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation orientation);
// ugly hack for QTreeModel, see QTBUG-94546
virtual void executePendingOperations() const;
inline QModelIndex createIndex(int row, int column, void *data = nullptr) const {
return q_func()->createIndex(row, column, data);
}
inline QModelIndex createIndex(int row, int column, int id) const {
return q_func()->createIndex(row, column, id);
}
inline bool indexValid(const QModelIndex &index) const {
return (index.row() >= 0) && (index.column() >= 0) && (index.model() == q_func());
}
void invalidatePersistentIndexes();
void invalidatePersistentIndex(const QModelIndex &index);
struct Change {
constexpr Change() : parent(), first(-1), last(-1), needsAdjust(false) {}
constexpr Change(const QModelIndex &p, int f, int l) : parent(p), first(f), last(l), needsAdjust(false) {}
QModelIndex parent;
int first, last;
// In cases such as this:
// - A
// - B
// - C
// - - D
// - - E
// - - F
//
// If B is moved to above E, C is the source parent in the signal and its row is 2. When the move is
// completed however, C is at row 1 and there is no row 2 at the same level in the model at all.
// The QModelIndex is adjusted to correct that in those cases before reporting it though the
// rowsMoved signal.
bool needsAdjust;
constexpr bool isValid() const { return first >= 0 && last >= 0; }
};
QStack<Change> changes;
struct Persistent {
Persistent() {}
QMultiHash<QModelIndex, QPersistentModelIndexData *> indexes;
QStack<QList<QPersistentModelIndexData *>> moved;
QStack<QList<QPersistentModelIndexData *>> invalidated;
void insertMultiAtEnd(const QModelIndex& key, QPersistentModelIndexData *data);
} persistent;
static const QHash<int,QByteArray> &defaultRoleNames();
static bool isVariantLessThan(const QVariant &left, const QVariant &right,
Qt::CaseSensitivity cs = Qt::CaseSensitive, bool isLocaleAware = false);
};
Q_DECLARE_TYPEINFO(QAbstractItemModelPrivate::Change, Q_RELOCATABLE_TYPE);
namespace QtPrivate {
/*!
\internal
This is a workaround for QTBUG-75172.
Some predefined model roles are supposed to use certain enum/flag
types (e.g. fetching Qt::TextAlignmentRole is supposed to return a
variant containing a Qt::Alignment object).
For historical reasons, a plain `int` was used sometimes. This is
surprising to end-users and also sloppy on Qt's part; users were
forced to use `int` rather than the correct datatype.
This function tries both the "right" type and plain `int`, for a
given QVariant. This fixes the problem (using the correct datatype)
but also keeps compatibility with existing code using `int`.
### Qt 7: get rid of this. Always use the correct datatype.
*/
template <typename T>
T legacyEnumValueFromModelData(const QVariant &data)
{
static_assert(std::is_enum_v<T>);
if (data.userType() == qMetaTypeId<T>()) {
return data.value<T>();
} else if (std::is_same_v<std::underlying_type_t<T>, int> ||
std::is_same_v<std::underlying_type_t<T>, uint>) {
return T(data.toInt());
}
return T();
}
template <typename T>
T legacyFlagValueFromModelData(const QVariant &data)
{
if (data.userType() == qMetaTypeId<T>()) {
return data.value<T>();
} else if (std::is_same_v<std::underlying_type_t<typename T::enum_type>, int> ||
std::is_same_v<std::underlying_type_t<typename T::enum_type>, uint>) {
return T::fromInt(data.toInt());
}
return T();
}
} // namespace QtPrivate
QT_END_NAMESPACE
#endif // QABSTRACTITEMMODEL_P_H

View File

@ -0,0 +1,66 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTPROXYMODEL_P_H
#define QABSTRACTPROXYMODEL_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of QAbstractItemModel*. This header file may change from version
// to version without notice, or even be removed.
//
// We mean it.
//
//
#include "private/qabstractitemmodel_p.h"
#include "private/qproperty_p.h"
QT_REQUIRE_CONFIG(proxymodel);
QT_BEGIN_NAMESPACE
class Q_CORE_EXPORT QAbstractProxyModelPrivate : public QAbstractItemModelPrivate
{
Q_DECLARE_PUBLIC(QAbstractProxyModel)
public:
QAbstractProxyModelPrivate()
: QAbstractItemModelPrivate(),
sourceHadZeroRows(false),
sourceHadZeroColumns(false)
{}
void setModelForwarder(QAbstractItemModel *sourceModel)
{
q_func()->setSourceModel(sourceModel);
}
void modelChangedForwarder()
{
Q_EMIT q_func()->sourceModelChanged(QAbstractProxyModel::QPrivateSignal());
}
QAbstractItemModel *getModelForwarder() const { return q_func()->sourceModel(); }
Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QAbstractProxyModelPrivate, QAbstractItemModel *, model,
&QAbstractProxyModelPrivate::setModelForwarder,
&QAbstractProxyModelPrivate::modelChangedForwarder,
&QAbstractProxyModelPrivate::getModelForwarder, nullptr)
virtual void _q_sourceModelDestroyed();
void _q_sourceModelRowsAboutToBeInserted(const QModelIndex &parent, int first, int last);
void _q_sourceModelRowsInserted(const QModelIndex &parent, int first, int last);
void _q_sourceModelRowsRemoved(const QModelIndex &parent, int first, int last);
void _q_sourceModelColumnsAboutToBeInserted(const QModelIndex &parent, int first, int last);
void _q_sourceModelColumnsInserted(const QModelIndex &parent, int first, int last);
void _q_sourceModelColumnsRemoved(const QModelIndex &parent, int first, int last);
void mapDropCoordinatesToSource(int row, int column, const QModelIndex &parent,
int *source_row, int *source_column, QModelIndex *source_parent) const;
unsigned int sourceHadZeroRows : 1;
unsigned int sourceHadZeroColumns : 1;
};
QT_END_NAMESPACE
#endif // QABSTRACTPROXYMODEL_P_H

View File

@ -0,0 +1,58 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QANIMATIONGROUP_P_H
#define QANIMATIONGROUP_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qanimationgroup.h"
#include <QtCore/qlist.h>
#include "private/qabstractanimation_p.h"
QT_REQUIRE_CONFIG(animation);
QT_BEGIN_NAMESPACE
class QAnimationGroupPrivate : public QAbstractAnimationPrivate
{
Q_DECLARE_PUBLIC(QAnimationGroup)
public:
QAnimationGroupPrivate()
{
isGroup = true;
}
virtual void animationInsertedAt(qsizetype) { }
virtual void animationRemoved(qsizetype, QAbstractAnimation *);
void clear(bool onDestruction);
void disconnectUncontrolledAnimation(QAbstractAnimation *anim)
{
//0 for the signal here because we might be called from the animation destructor
QObject::disconnect(anim, nullptr, q_func(), SLOT(_q_uncontrolledAnimationFinished()));
}
void connectUncontrolledAnimation(QAbstractAnimation *anim)
{
QObject::connect(anim, SIGNAL(finished()), q_func(), SLOT(_q_uncontrolledAnimationFinished()));
}
QList<QAbstractAnimation *> animations;
};
QT_END_NAMESPACE
#endif //QANIMATIONGROUP_P_H

View File

@ -0,0 +1,107 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QATOMICSCOPEDVALUEROLLBACK_P_H
#define QATOMICSCOPEDVALUEROLLBACK_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
// file may change from version to version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qglobal.h>
#include <QtCore/qatomic.h>
#include <atomic>
QT_BEGIN_NAMESPACE
template <typename T>
class [[nodiscard]] QAtomicScopedValueRollback
{
std::atomic<T> &m_atomic;
T m_value;
std::memory_order m_mo;
Q_DISABLE_COPY_MOVE(QAtomicScopedValueRollback)
constexpr std::memory_order store_part(std::memory_order mo) noexcept
{
switch (mo) {
case std::memory_order_relaxed:
case std::memory_order_consume:
case std::memory_order_acquire: return std::memory_order_relaxed;
case std::memory_order_release:
case std::memory_order_acq_rel: return std::memory_order_release;
case std::memory_order_seq_cst: return std::memory_order_seq_cst;
}
// GCC 8.x does not tread __builtin_unreachable() as constexpr
#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
// NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
Q_UNREACHABLE();
#endif
return std::memory_order_seq_cst;
}
public:
//
// std::atomic:
//
explicit constexpr
QAtomicScopedValueRollback(std::atomic<T> &var,
std::memory_order mo = std::memory_order_seq_cst)
: m_atomic(var), m_value(var.load(mo)), m_mo(mo) {}
explicit constexpr
QAtomicScopedValueRollback(std::atomic<T> &var, T value,
std::memory_order mo = std::memory_order_seq_cst)
: m_atomic(var), m_value(var.exchange(value, mo)), m_mo(mo) {}
//
// Q(Basic)AtomicInteger:
//
explicit constexpr
QAtomicScopedValueRollback(QBasicAtomicInteger<T> &var,
std::memory_order mo = std::memory_order_seq_cst)
: QAtomicScopedValueRollback(var._q_value, mo) {}
explicit constexpr
QAtomicScopedValueRollback(QBasicAtomicInteger<T> &var, T value,
std::memory_order mo = std::memory_order_seq_cst)
: QAtomicScopedValueRollback(var._q_value, value, mo) {}
//
// Q(Basic)AtomicPointer:
//
explicit constexpr
QAtomicScopedValueRollback(QBasicAtomicPointer<std::remove_pointer_t<T>> &var,
std::memory_order mo = std::memory_order_seq_cst)
: QAtomicScopedValueRollback(var._q_value, mo) {}
explicit constexpr
QAtomicScopedValueRollback(QBasicAtomicPointer<std::remove_pointer_t<T>> &var, T value,
std::memory_order mo = std::memory_order_seq_cst)
: QAtomicScopedValueRollback(var._q_value, value, mo) {}
#if __cpp_constexpr >= 201907L
constexpr
#endif
~QAtomicScopedValueRollback()
{
m_atomic.store(m_value, store_part(m_mo));
}
constexpr void commit()
{
m_value = m_atomic.load(m_mo);
}
};
QT_END_NAMESPACE
#endif // QATOMICASCOPEDVALUEROLLBACK_P_H

View File

@ -0,0 +1,29 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QBYTEARRAY_P_H
#define QBYTEARRAY_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of other Qt classes. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qbytearray.h>
#include "private/qtools_p.h"
QT_BEGIN_NAMESPACE
// -1 because of the terminating NUL
constexpr qsizetype MaxByteArraySize = MaxAllocSize - sizeof(std::remove_pointer<QByteArray::DataPointer>::type) - 1;
constexpr qsizetype MaxStringSize = (MaxAllocSize - sizeof(std::remove_pointer<QByteArray::DataPointer>::type)) / 2 - 1;
QT_END_NAMESPACE
#endif // QBYTEARRAY_P_H

View File

@ -0,0 +1,285 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QBYTEDATA_P_H
#define QBYTEDATA_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
#include <qbytearray.h>
#include <QtCore/qlist.h>
#include <climits>
QT_BEGIN_NAMESPACE
// this class handles a list of QByteArrays. It is a variant of QRingBuffer
// that avoid malloc/realloc/memcpy.
class QByteDataBuffer
{
private:
QList<QByteArray> buffers;
qint64 bufferCompleteSize = 0;
qint64 firstPos = 0;
public:
static inline void popFront(QByteArray &ba, qint64 n)
{
ba = QByteArray(ba.constData() + n, ba.size() - n);
}
inline void squeezeFirst()
{
if (!buffers.isEmpty() && firstPos > 0) {
popFront(buffers.first(), firstPos);
firstPos = 0;
}
}
inline void append(const QByteDataBuffer& other)
{
if (other.isEmpty())
return;
buffers.append(other.buffers);
bufferCompleteSize += other.byteAmount();
if (other.firstPos > 0)
popFront(buffers[bufferCount() - other.bufferCount()], other.firstPos);
}
inline void append(QByteDataBuffer &&other)
{
if (other.isEmpty())
return;
auto otherBufferCount = other.bufferCount();
auto otherByteAmount = other.byteAmount();
buffers.append(std::move(other.buffers));
bufferCompleteSize += otherByteAmount;
if (other.firstPos > 0)
popFront(buffers[bufferCount() - otherBufferCount], other.firstPos);
}
inline void append(const QByteArray& bd)
{
append(QByteArray(bd));
}
inline void append(QByteArray &&bd)
{
if (bd.isEmpty())
return;
bufferCompleteSize += bd.size();
buffers.append(std::move(bd));
}
inline void prepend(const QByteArray& bd)
{
prepend(QByteArray(bd));
}
inline void prepend(QByteArray &&bd)
{
if (bd.isEmpty())
return;
squeezeFirst();
bufferCompleteSize += bd.size();
buffers.prepend(std::move(bd));
}
// return the first QByteData. User of this function has to free() its .data!
// preferably use this function to read data.
inline QByteArray read()
{
Q_ASSERT(!isEmpty());
squeezeFirst();
bufferCompleteSize -= buffers.first().size();
return buffers.takeFirst();
}
// return everything. User of this function has to free() its .data!
// avoid to use this, it might malloc and memcpy.
inline QByteArray readAll()
{
return read(byteAmount());
}
// return amount. User of this function has to free() its .data!
// avoid to use this, it might malloc and memcpy.
inline QByteArray read(qint64 amount)
{
amount = qMin(byteAmount(), amount);
if constexpr (sizeof(qsizetype) == sizeof(int)) { // 32-bit
// While we cannot overall have more than INT_MAX memory allocated,
// the QByteArrays we hold may be shared copies of each other,
// causing byteAmount() to exceed INT_MAX.
if (amount > INT_MAX)
qBadAlloc(); // what resize() would do if it saw past the truncation
}
QByteArray byteData;
byteData.resize(qsizetype(amount));
read(byteData.data(), byteData.size());
return byteData;
}
// return amount bytes. User of this function has to free() its .data!
// avoid to use this, it will memcpy.
qint64 read(char* dst, qint64 amount)
{
amount = qMin(amount, byteAmount());
qint64 originalAmount = amount;
char *writeDst = dst;
while (amount > 0) {
const QByteArray &first = buffers.first();
qint64 firstSize = first.size() - firstPos;
if (amount >= firstSize) {
// take it completely
bufferCompleteSize -= firstSize;
amount -= firstSize;
memcpy(writeDst, first.constData() + firstPos, firstSize);
writeDst += firstSize;
firstPos = 0;
buffers.takeFirst();
} else {
// take a part of it & it is the last one to take
bufferCompleteSize -= amount;
memcpy(writeDst, first.constData() + firstPos, amount);
firstPos += amount;
amount = 0;
}
}
return originalAmount;
}
/*!
\internal
Returns a view into the first QByteArray contained inside,
ignoring any already read data. Call advanceReadPointer()
to advance the view forward. When a QByteArray is exhausted
the view returned by this function will view into another
QByteArray if any. Returns a default constructed view if
no data is available.
\sa advanceReadPointer
*/
QByteArrayView readPointer() const
{
if (isEmpty())
return {};
return { buffers.first().constData() + qsizetype(firstPos),
buffers.first().size() - qsizetype(firstPos) };
}
/*!
\internal
Advances the read pointer by \a distance.
\sa readPointer
*/
void advanceReadPointer(qint64 distance)
{
qint64 newPos = firstPos + distance;
if (isEmpty()) {
newPos = 0;
} else if (auto size = buffers.first().size(); newPos >= size) {
while (newPos >= size) {
bufferCompleteSize -= (size - firstPos);
newPos -= size;
buffers.pop_front();
if (isEmpty()) {
size = 0;
newPos = 0;
break;
}
size = buffers.front().size();
}
bufferCompleteSize -= newPos;
} else {
bufferCompleteSize -= newPos - firstPos;
}
firstPos = newPos;
}
inline char getChar()
{
Q_ASSERT_X(!isEmpty(), "QByteDataBuffer::getChar",
"Cannot read a char from an empty buffer!");
char c;
read(&c, 1);
return c;
}
inline void clear()
{
buffers.clear();
bufferCompleteSize = 0;
firstPos = 0;
}
// The byte count of all QByteArrays
inline qint64 byteAmount() const
{
return bufferCompleteSize;
}
// the number of QByteArrays
qsizetype bufferCount() const
{
return buffers.size();
}
inline bool isEmpty() const
{
return byteAmount() == 0;
}
inline qint64 sizeNextBlock() const
{
if (buffers.isEmpty())
return 0;
else
return buffers.first().size() - firstPos;
}
QByteArray &operator[](qsizetype i)
{
if (i == 0)
squeezeFirst();
return buffers[i];
}
inline bool canReadLine() const {
qsizetype i = 0;
if (i < buffers.size()) {
if (buffers.at(i).indexOf('\n', firstPos) != -1)
return true;
++i;
for (; i < buffers.size(); i++)
if (buffers.at(i).contains('\n'))
return true;
}
return false;
}
};
QT_END_NAMESPACE
#endif // QBYTEDATA_P_H

View File

@ -0,0 +1,134 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCALENDAR_BACKEND_P_H
#define QCALENDAR_BACKEND_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of calendar implementations. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qobjectdefs.h>
#include <QtCore/qcalendar.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qstring.h>
#include <QtCore/qmap.h>
#include <QtCore/qanystringview.h>
#include <QtCore/private/qlocale_p.h>
QT_BEGIN_NAMESPACE
namespace QtPrivate {
class QCalendarRegistry;
}
// Locale-related parts, mostly handled in ../text/qlocale.cpp
struct QCalendarLocale {
quint16 m_language_id, m_script_id, m_territory_id;
#define rangeGetter(name) \
QLocaleData::DataRange name() const { return { m_ ## name ## _idx, m_ ## name ## _size }; }
rangeGetter(longMonthStandalone) rangeGetter(longMonth)
rangeGetter(shortMonthStandalone) rangeGetter(shortMonth)
rangeGetter(narrowMonthStandalone) rangeGetter(narrowMonth)
#undef rangeGetter
// Month name indexes:
quint16 m_longMonthStandalone_idx, m_longMonth_idx;
quint16 m_shortMonthStandalone_idx, m_shortMonth_idx;
quint16 m_narrowMonthStandalone_idx, m_narrowMonth_idx;
// Twelve long month names (separated by commas) can add up to more than 256
// QChars - e.g. kde_TZ gets to 264.
quint16 m_longMonthStandalone_size, m_longMonth_size;
quint8 m_shortMonthStandalone_size, m_shortMonth_size;
quint8 m_narrowMonthStandalone_size, m_narrowMonth_size;
};
// Partial implementation, of methods with common forms, in qcalendar.cpp
class Q_CORE_EXPORT QCalendarBackend
{
friend class QCalendar;
friend class QtPrivate::QCalendarRegistry;
public:
virtual ~QCalendarBackend();
virtual QString name() const = 0;
QStringList names() const;
QCalendar::System calendarSystem() const;
QCalendar::SystemId calendarId() const { return m_id; }
// Date queries:
virtual int daysInMonth(int month, int year = QCalendar::Unspecified) const = 0;
virtual int daysInYear(int year) const;
virtual int monthsInYear(int year) const;
virtual bool isDateValid(int year, int month, int day) const;
// Properties of the calendar:
virtual bool isLeapYear(int year) const = 0;
virtual bool isLunar() const = 0;
virtual bool isLuniSolar() const = 0;
virtual bool isSolar() const = 0;
virtual bool isProleptic() const;
virtual bool hasYearZero() const;
virtual int maximumDaysInMonth() const;
virtual int minimumDaysInMonth() const;
virtual int maximumMonthsInYear() const;
// Julian Day conversions:
virtual bool dateToJulianDay(int year, int month, int day, qint64 *jd) const = 0;
virtual QCalendar::YearMonthDay julianDayToDate(qint64 jd) const = 0;
// Day of week and week numbering:
virtual int dayOfWeek(qint64 jd) const;
// Names of months and week-days (implemented in qlocale.cpp):
virtual QString monthName(const QLocale &locale, int month, int year,
QLocale::FormatType format) const;
virtual QString standaloneMonthName(const QLocale &locale, int month, int year,
QLocale::FormatType format) const;
virtual QString weekDayName(const QLocale &locale, int day,
QLocale::FormatType format) const;
virtual QString standaloneWeekDayName(const QLocale &locale, int day,
QLocale::FormatType format) const;
// Formatting of date-times (implemented in qlocale.cpp):
virtual QString dateTimeToString(QStringView format, const QDateTime &datetime,
QDate dateOnly, QTime timeOnly,
const QLocale &locale) const;
bool isGregorian() const;
QCalendar::SystemId registerCustomBackend(const QStringList &names);
// Calendar enumeration by name:
static QStringList availableCalendars();
protected:
// Locale support:
virtual const QCalendarLocale *localeMonthIndexData() const = 0;
virtual const char16_t *localeMonthData() const = 0;
private:
QCalendar::SystemId m_id;
void setIndex(size_t index);
// QCalendar's access to its registry:
static const QCalendarBackend *fromName(QAnyStringView name);
static const QCalendarBackend *fromId(QCalendar::SystemId id);
// QCalendar's access to singletons:
static const QCalendarBackend *fromEnum(QCalendar::System system);
static const QCalendarBackend *gregorian();
};
QT_END_NAMESPACE
#endif // QCALENDAR_BACKEND_P_H

View File

@ -0,0 +1,48 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCALENDARMATH_P_H
#define QCALENDARMATH_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of q*calendar.cpp. This header file may change from version to version
// without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
QT_BEGIN_NAMESPACE
namespace QRoundingDown {
/*
Division, rounding down (rather than towards zero).
From C++11 onwards, integer division is defined to round towards zero, so we
can rely on that when implementing this. This is only used with denominator b
> 0, so we only have to treat negative numerator, a, specially.
If a is a multiple of b, adding 1 before and subtracting it after dividing by
b gets us to where we should be (albeit by an eccentric path), since the
adding caused rounding up, undone by the subtracting. Otherwise, adding 1
doesn't change the result of dividing by b; and we want one less than that
result. This is equivalent to subtracting b - 1 and simply dividing, except
when that subtraction would underflow.
*/
template<typename Int> constexpr Int qDiv(Int a, unsigned b)
{ return a < 0 ? (a + 1) / int(b) - 1 : a / int(b); }
template<typename Int> constexpr Int qMod(Int a, unsigned b)
{ return a - qDiv(a, b) * b; }
} // QRoundingDown
QT_END_NAMESPACE
#endif // QCALENDARMATH_P_H

View File

@ -0,0 +1,49 @@
// Copyright (C) 2018 Intel Corporation.
// Copyright (C) 2019 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCBORCOMMON_P_H
#define QCBORCOMMON_P_H
#include "qcborcommon.h"
#include "private/qglobal_p.h"
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
QT_BEGIN_NAMESPACE
#ifdef QT_NO_DEBUG
# define NDEBUG 1
#endif
#undef assert
#define assert Q_ASSERT
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wunused-function")
QT_WARNING_DISABLE_CLANG("-Wunused-function")
QT_WARNING_DISABLE_CLANG("-Wundefined-internal")
#define CBOR_NO_VALIDATION_API 1
#define CBOR_NO_PRETTY_API 1
#define CBOR_API static inline
#define CBOR_PRIVATE_API static inline
#define CBOR_INLINE_API static inline
#include <cbor.h>
QT_WARNING_POP
Q_DECLARE_TYPEINFO(CborValue, Q_PRIMITIVE_TYPE);
QT_END_NAMESPACE
#endif // QCBORCOMMON_P_H

View File

@ -0,0 +1,449 @@
// Copyright (C) 2020 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCBORVALUE_P_H
#define QCBORVALUE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API.
// This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qcborvalue.h"
#if QT_CONFIG(cborstreamreader)
# include "qcborstreamreader.h"
#endif
#include <private/qglobal_p.h>
#include <private/qstringconverter_p.h>
#include <math.h>
QT_BEGIN_NAMESPACE
namespace QtCbor {
struct Undefined {};
struct Element
{
enum ValueFlag : quint32 {
IsContainer = 0x0001,
HasByteData = 0x0002,
StringIsUtf16 = 0x0004,
StringIsAscii = 0x0008
};
Q_DECLARE_FLAGS(ValueFlags, ValueFlag)
union {
qint64 value;
QCborContainerPrivate *container;
};
QCborValue::Type type;
ValueFlags flags = {};
Element(qint64 v = 0, QCborValue::Type t = QCborValue::Undefined, ValueFlags f = {})
: value(v), type(t), flags(f)
{}
Element(QCborContainerPrivate *d, QCborValue::Type t, ValueFlags f = {})
: container(d), type(t), flags(f | IsContainer)
{}
double fpvalue() const
{
double d;
memcpy(&d, &value, sizeof(d));
return d;
}
};
Q_DECLARE_OPERATORS_FOR_FLAGS(Element::ValueFlags)
static_assert(sizeof(Element) == 16);
struct ByteData
{
QByteArray::size_type len;
const char *byte() const { return reinterpret_cast<const char *>(this + 1); }
char *byte() { return reinterpret_cast<char *>(this + 1); }
const QChar *utf16() const { return reinterpret_cast<const QChar *>(this + 1); }
QChar *utf16() { return reinterpret_cast<QChar *>(this + 1); }
QByteArray toByteArray() const { return QByteArray(byte(), len); }
QString toString() const { return QString(utf16(), len / 2); }
QString toUtf8String() const { return QString::fromUtf8(byte(), len); }
QByteArray asByteArrayView() const { return QByteArray::fromRawData(byte(), len); }
QLatin1StringView asLatin1() const { return {byte(), len}; }
QUtf8StringView asUtf8StringView() const { return QUtf8StringView(byte(), len); }
QStringView asStringView() const{ return QStringView(utf16(), len / 2); }
QString asQStringRaw() const { return QString::fromRawData(utf16(), len / 2); }
};
static_assert(std::is_trivial<ByteData>::value);
static_assert(std::is_standard_layout<ByteData>::value);
} // namespace QtCbor
Q_DECLARE_TYPEINFO(QtCbor::Element, Q_PRIMITIVE_TYPE);
class QCborContainerPrivate : public QSharedData
{
friend class QExplicitlySharedDataPointer<QCborContainerPrivate>;
~QCborContainerPrivate();
public:
enum ContainerDisposition { CopyContainer, MoveContainer };
QByteArray::size_type usedData = 0;
QByteArray data;
QList<QtCbor::Element> elements;
void deref() { if (!ref.deref()) delete this; }
void compact(qsizetype reserved);
static QCborContainerPrivate *clone(QCborContainerPrivate *d, qsizetype reserved = -1);
static QCborContainerPrivate *detach(QCborContainerPrivate *d, qsizetype reserved);
static QCborContainerPrivate *grow(QCborContainerPrivate *d, qsizetype index);
qptrdiff addByteData(const char *block, qsizetype len)
{
// This function does not do overflow checking, since the len parameter
// is expected to be trusted. There's another version of this function
// in decodeStringFromCbor(), which checks.
qptrdiff offset = data.size();
// align offset
offset += alignof(QtCbor::ByteData) - 1;
offset &= ~(alignof(QtCbor::ByteData) - 1);
qptrdiff increment = qptrdiff(sizeof(QtCbor::ByteData)) + len;
usedData += increment;
data.resize(offset + increment);
char *ptr = data.begin() + offset;
auto b = new (ptr) QtCbor::ByteData;
b->len = len;
if (block)
memcpy(b->byte(), block, len);
return offset;
}
const QtCbor::ByteData *byteData(QtCbor::Element e) const
{
if ((e.flags & QtCbor::Element::HasByteData) == 0)
return nullptr;
size_t offset = size_t(e.value);
Q_ASSERT((offset % alignof(QtCbor::ByteData)) == 0);
Q_ASSERT(offset + sizeof(QtCbor::ByteData) <= size_t(data.size()));
auto b = reinterpret_cast<const QtCbor::ByteData *>(data.constData() + offset);
Q_ASSERT(offset + sizeof(*b) + size_t(b->len) <= size_t(data.size()));
return b;
}
const QtCbor::ByteData *byteData(qsizetype idx) const
{
return byteData(elements.at(idx));
}
QCborContainerPrivate *containerAt(qsizetype idx, QCborValue::Type type) const
{
const QtCbor::Element &e = elements.at(idx);
if (e.type != type || (e.flags & QtCbor::Element::IsContainer) == 0)
return nullptr;
return e.container;
}
void replaceAt_complex(QtCbor::Element &e, const QCborValue &value, ContainerDisposition disp);
void replaceAt_internal(QtCbor::Element &e, const QCborValue &value, ContainerDisposition disp)
{
if (value.container)
return replaceAt_complex(e, value, disp);
e = { value.value_helper(), value.type() };
if (value.isContainer())
e.container = nullptr;
}
void replaceAt(qsizetype idx, const QCborValue &value, ContainerDisposition disp = CopyContainer)
{
QtCbor::Element &e = elements[idx];
if (e.flags & QtCbor::Element::IsContainer) {
e.container->deref();
e.container = nullptr;
e.flags = {};
} else if (auto b = byteData(e)) {
usedData -= b->len + sizeof(QtCbor::ByteData);
}
replaceAt_internal(e, value, disp);
}
void insertAt(qsizetype idx, const QCborValue &value, ContainerDisposition disp = CopyContainer)
{
replaceAt_internal(*elements.insert(elements.begin() + int(idx), {}), value, disp);
}
void append(QtCbor::Undefined)
{
elements.append(QtCbor::Element());
}
void append(qint64 value)
{
elements.append(QtCbor::Element(value , QCborValue::Integer));
}
void append(QCborTag tag)
{
elements.append(QtCbor::Element(qint64(tag), QCborValue::Tag));
}
void appendByteData(const char *data, qsizetype len, QCborValue::Type type,
QtCbor::Element::ValueFlags extraFlags = {})
{
elements.append(QtCbor::Element(addByteData(data, len), type,
QtCbor::Element::HasByteData | extraFlags));
}
void appendAsciiString(const QString &s);
void appendAsciiString(const char *str, qsizetype len)
{
appendByteData(str, len, QCborValue::String, QtCbor::Element::StringIsAscii);
}
void appendUtf8String(const char *str, qsizetype len)
{
appendByteData(str, len, QCborValue::String);
}
void append(QLatin1StringView s)
{
if (!QtPrivate::isAscii(s))
return append(QString(s));
// US-ASCII is a subset of UTF-8, so we can keep in 8-bit
appendByteData(s.latin1(), s.size(), QCborValue::String,
QtCbor::Element::StringIsAscii);
}
void appendAsciiString(QStringView s);
void append(const QString &s)
{
append(qToStringViewIgnoringNull(s));
}
void append(QStringView s)
{
if (QtPrivate::isAscii(s))
appendAsciiString(s);
else
appendByteData(reinterpret_cast<const char *>(s.utf16()), s.size() * 2,
QCborValue::String, QtCbor::Element::StringIsUtf16);
}
void append(const QCborValue &v)
{
insertAt(elements.size(), v);
}
QByteArray byteArrayAt(qsizetype idx) const
{
const auto &e = elements.at(idx);
const auto data = byteData(e);
if (!data)
return QByteArray();
return data->toByteArray();
}
QString stringAt(qsizetype idx) const
{
const auto &e = elements.at(idx);
const auto data = byteData(e);
if (!data)
return QString();
if (e.flags & QtCbor::Element::StringIsUtf16)
return data->toString();
if (e.flags & QtCbor::Element::StringIsAscii)
return data->asLatin1();
return data->toUtf8String();
}
static void resetValue(QCborValue &v)
{
v.container = nullptr;
}
static QCborValue makeValue(QCborValue::Type type, qint64 n, QCborContainerPrivate *d = nullptr,
ContainerDisposition disp = CopyContainer)
{
QCborValue result(type);
result.n = n;
result.container = d;
if (d && disp == CopyContainer)
d->ref.ref();
return result;
}
QCborValue valueAt(qsizetype idx) const
{
const auto &e = elements.at(idx);
if (e.flags & QtCbor::Element::IsContainer) {
if (e.type == QCborValue::Tag && e.container->elements.size() != 2) {
// invalid tags can be created due to incomplete parsing
return makeValue(QCborValue::Invalid, 0, nullptr);
}
return makeValue(e.type, -1, e.container);
} else if (e.flags & QtCbor::Element::HasByteData) {
return makeValue(e.type, idx, const_cast<QCborContainerPrivate *>(this));
}
return makeValue(e.type, e.value);
}
QCborValue extractAt_complex(QtCbor::Element e);
QCborValue extractAt(qsizetype idx)
{
QtCbor::Element e;
qSwap(e, elements[idx]);
if (e.flags & QtCbor::Element::IsContainer) {
if (e.type == QCborValue::Tag && e.container->elements.size() != 2) {
// invalid tags can be created due to incomplete parsing
e.container->deref();
return makeValue(QCborValue::Invalid, 0, nullptr);
}
return makeValue(e.type, -1, e.container, MoveContainer);
} else if (e.flags & QtCbor::Element::HasByteData) {
return extractAt_complex(e);
}
return makeValue(e.type, e.value);
}
static QtCbor::Element elementFromValue(const QCborValue &value)
{
if (value.n >= 0 && value.container)
return value.container->elements.at(value.n);
QtCbor::Element e;
e.value = value.n;
e.type = value.t;
if (value.container) {
e.container = value.container;
e.flags = QtCbor::Element::IsContainer;
}
return e;
}
static int compareUtf8(const QtCbor::ByteData *b, QLatin1StringView s)
{
return QUtf8::compareUtf8(QByteArrayView(b->byte(), b->len), s);
}
static int compareUtf8(const QtCbor::ByteData *b, QStringView s)
{
return QUtf8::compareUtf8(QByteArrayView(b->byte(), b->len), s);
}
template<typename String>
int stringCompareElement(const QtCbor::Element &e, String s) const
{
if (e.type != QCborValue::String)
return int(e.type) - int(QCborValue::String);
const QtCbor::ByteData *b = byteData(e);
if (!b)
return s.isEmpty() ? 0 : -1;
if (e.flags & QtCbor::Element::StringIsUtf16)
return QtPrivate::compareStrings(b->asStringView(), s);
return compareUtf8(b, s);
}
template<typename String>
bool stringEqualsElement(const QtCbor::Element &e, String s) const
{
return stringCompareElement(e, s) == 0;
}
template<typename String>
bool stringEqualsElement(qsizetype idx, String s) const
{
return stringEqualsElement(elements.at(idx), s);
}
static int compareElement_helper(const QCborContainerPrivate *c1, QtCbor::Element e1,
const QCborContainerPrivate *c2, QtCbor::Element e2);
int compareElement(qsizetype idx, const QCborValue &value) const
{
auto &e1 = elements.at(idx);
auto e2 = elementFromValue(value);
return compareElement_helper(this, e1, value.container, e2);
}
void removeAt(qsizetype idx)
{
replaceAt(idx, {});
elements.remove(idx);
}
// doesn't apply to JSON
template <typename KeyType> QCborValueConstRef findCborMapKey(KeyType key)
{
qsizetype i = 0;
for ( ; i < elements.size(); i += 2) {
const auto &e = elements.at(i);
bool equals;
if constexpr (std::is_same_v<std::decay_t<KeyType>, QCborValue>) {
equals = (compareElement(i, key) == 0);
} else if constexpr (std::is_integral_v<KeyType>) {
equals = (e.type == QCborValue::Integer && e.value == key);
} else {
// assume it's a string
equals = stringEqualsElement(i, key);
}
if (equals)
break;
}
return { this, i + 1 };
}
template <typename KeyType> static QCborValue findCborMapKey(const QCborValue &self, KeyType key)
{
if (self.isMap() && self.container) {
qsizetype idx = self.container->findCborMapKey(key).i;
if (idx < self.container->elements.size())
return self.container->valueAt(idx);
}
return QCborValue();
}
template <typename KeyType> static QCborValueRef
findOrAddMapKey(QCborContainerPrivate *container, KeyType key)
{
qsizetype size = 0;
qsizetype index = size + 1;
if (container) {
size = container->elements.size();
index = container->findCborMapKey<KeyType>(key).i; // returns size + 1 if not found
}
Q_ASSERT(index & 1);
Q_ASSERT((size & 1) == 0);
container = detach(container, qMax(index + 1, size));
Q_ASSERT(container);
Q_ASSERT((container->elements.size() & 1) == 0);
if (index >= size) {
container->append(key);
container->append(QCborValue());
}
Q_ASSERT(index < container->elements.size());
return { container, index };
}
template <typename KeyType> static QCborValueRef findOrAddMapKey(QCborMap &map, KeyType key);
template <typename KeyType> static QCborValueRef findOrAddMapKey(QCborValue &self, KeyType key);
template <typename KeyType> static QCborValueRef findOrAddMapKey(QCborValueRef self, KeyType key);
#if QT_CONFIG(cborstreamreader)
void decodeValueFromCbor(QCborStreamReader &reader, int remainingStackDepth);
void decodeStringFromCbor(QCborStreamReader &reader);
static inline void setErrorInReader(QCborStreamReader &reader, QCborError error);
#endif
};
QT_END_NAMESPACE
#endif // QCBORVALUE_P_H

View File

@ -0,0 +1,34 @@
// Copyright (C) 2021 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// no, this is not a misspelling of "coffeeparser"
#ifndef QCOFFPEPARSER_H
#define QCOFFPEPARSER_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qlibrary_p.h"
#if defined(Q_OS_WIN)
QT_BEGIN_NAMESPACE
struct QCoffPeParser
{
static QLibraryScanResult parse(QByteArrayView data, QString *errMsg);
};
QT_END_NAMESPACE
#endif // defined(Q_OF_ELF) && defined(Q_CC_GNU)
#endif // QCOFFPEPARSER_H

View File

@ -0,0 +1,111 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2013 Aleix Pol Gonzalez <aleixpol@kde.org>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCOLLATOR_P_H
#define QCOLLATOR_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
#include "qcollator.h"
#include <QList>
#if QT_CONFIG(icu)
#include <unicode/ucol.h>
#elif defined(Q_OS_MACOS)
#include <CoreServices/CoreServices.h>
#elif defined(Q_OS_WIN)
#include <qt_windows.h>
#endif
QT_BEGIN_NAMESPACE
#if QT_CONFIG(icu)
typedef UCollator *CollatorType;
typedef QByteArray CollatorKeyType;
const CollatorType NoCollator = nullptr;
#elif defined(Q_OS_MACOS)
typedef CollatorRef CollatorType;
typedef QList<UCCollationValue> CollatorKeyType;
const CollatorType NoCollator = 0;
#elif defined(Q_OS_WIN)
typedef QString CollatorKeyType;
typedef int CollatorType;
const CollatorType NoCollator = 0;
#else // posix - ignores CollatorType collator, only handles system locale
typedef QList<wchar_t> CollatorKeyType;
typedef bool CollatorType;
const CollatorType NoCollator = false;
#endif
class QCollatorPrivate
{
public:
QAtomicInt ref = 1;
QLocale locale;
#if defined(Q_OS_WIN) && !QT_CONFIG(icu)
LCID localeID;
#endif
Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
bool numericMode = false;
bool ignorePunctuation = false;
bool dirty = true;
CollatorType collator = NoCollator;
QCollatorPrivate(const QLocale &locale) : locale(locale) {}
~QCollatorPrivate() { cleanup(); }
bool isC() { return locale.language() == QLocale::C; }
void clear() {
cleanup();
collator = NoCollator;
}
void ensureInitialized()
{
if (dirty)
init();
}
// Implemented by each back-end, in its own way:
void init();
void cleanup();
private:
Q_DISABLE_COPY_MOVE(QCollatorPrivate)
};
class QCollatorSortKeyPrivate : public QSharedData
{
friend class QCollator;
public:
template <typename...T>
explicit QCollatorSortKeyPrivate(T &&...args)
: QSharedData()
, m_key(std::forward<T>(args)...)
{
}
CollatorKeyType m_key;
private:
Q_DISABLE_COPY_MOVE(QCollatorSortKeyPrivate)
};
QT_END_NAMESPACE
#endif // QCOLLATOR_P_H

View File

@ -0,0 +1,124 @@
#define QT_FEATURE_use_bfd_linker -1
#define QT_FEATURE_use_gold_linker -1
#define QT_FEATURE_use_lld_linker -1
#define QT_FEATURE_use_mold_linker -1
#define QT_FEATURE_android_style_assets -1
#define QT_FEATURE_gc_binaries -1
#define QT_FEATURE_developer_build -1
#define QT_FEATURE_no_prefix -1
#define QT_FEATURE_private_tests -1
#define QT_FEATURE_debug 1
#define QT_FEATURE_reduce_exports -1
#define QT_FEATURE_no_direct_extern_access -1
#define QT_FEATURE_x86intrin 1
#define QT_FEATURE_sse2 1
#define QT_FEATURE_sse3 1
#define QT_FEATURE_ssse3 1
#define QT_FEATURE_sse4_1 1
#define QT_FEATURE_sse4_2 1
#define QT_FEATURE_avx 1
#define QT_FEATURE_f16c 1
#define QT_FEATURE_avx2 1
#define QT_FEATURE_avx512f 1
#define QT_FEATURE_avx512er 1
#define QT_FEATURE_avx512cd 1
#define QT_FEATURE_avx512pf 1
#define QT_FEATURE_avx512dq 1
#define QT_FEATURE_avx512bw 1
#define QT_FEATURE_avx512vl 1
#define QT_FEATURE_avx512ifma 1
#define QT_FEATURE_avx512vbmi 1
#define QT_FEATURE_avx512vbmi2 1
#define QT_FEATURE_aesni 1
#define QT_FEATURE_vaes 1
#define QT_FEATURE_rdrnd 1
#define QT_FEATURE_rdseed 1
#define QT_FEATURE_shani 1
#define QT_FEATURE_mips_dsp -1
#define QT_FEATURE_mips_dspr2 -1
#define QT_FEATURE_neon -1
#define QT_FEATURE_arm_crc32 -1
#define QT_FEATURE_arm_crypto -1
#define QT_FEATURE_posix_fallocate -1
#define QT_FEATURE_alloca_h -1
#define QT_FEATURE_alloca_malloc_h 1
#define QT_FEATURE_alloca 1
#define QT_FEATURE_stack_protector_strong -1
#define QT_FEATURE_system_zlib -1
#define QT_FEATURE_stdlib_libcpp -1
#define QT_FEATURE_dbus 1
#define QT_FEATURE_dbus_linked -1
#define QT_FEATURE_gui 1
#define QT_FEATURE_network 1
#define QT_FEATURE_printsupport 1
#define QT_FEATURE_sql 1
#define QT_FEATURE_testlib 1
#define QT_FEATURE_widgets 1
#define QT_FEATURE_xml 1
#define QT_FEATURE_libudev -1
#define QT_FEATURE_openssl -1
#define QT_FEATURE_dlopen -1
#define QT_FEATURE_relocatable 1
#define QT_FEATURE_intelcet -1

View File

@ -0,0 +1,173 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCOREAPPLICATION_P_H
#define QCOREAPPLICATION_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "QtCore/qcoreapplication.h"
#if QT_CONFIG(commandlineparser)
#include "QtCore/qcommandlineoption.h"
#endif
#include "QtCore/qreadwritelock.h"
#include "QtCore/qtranslator.h"
#if QT_CONFIG(settings)
#include "QtCore/qsettings.h"
#endif
#ifndef QT_NO_QOBJECT
#include "private/qobject_p.h"
#include "private/qlocking_p.h"
#endif
#ifdef Q_OS_MACOS
#include "private/qcore_mac_p.h"
#endif
QT_BEGIN_NAMESPACE
typedef QList<QTranslator*> QTranslatorList;
class QAbstractEventDispatcher;
#ifndef QT_NO_QOBJECT
class QEvent;
#endif
class Q_CORE_EXPORT QCoreApplicationPrivate
#ifndef QT_NO_QOBJECT
: public QObjectPrivate
#endif
{
Q_DECLARE_PUBLIC(QCoreApplication)
public:
enum Type {
Tty,
Gui
};
QCoreApplicationPrivate(int &aargc, char **aargv);
// If not inheriting from QObjectPrivate: force this class to be polymorphic
#ifdef QT_NO_QOBJECT
virtual
#endif
~QCoreApplicationPrivate();
void init();
QString appName() const;
QString appVersion() const;
#ifdef Q_OS_DARWIN
static QString infoDictionaryStringProperty(const QString &propertyName);
#endif
void initConsole();
static void initLocale();
static bool checkInstance(const char *method);
#if QT_CONFIG(commandlineparser)
virtual void addQtOptions(QList<QCommandLineOption> *options);
#endif
#ifndef QT_NO_QOBJECT
bool sendThroughApplicationEventFilters(QObject *, QEvent *);
static bool sendThroughObjectEventFilters(QObject *, QEvent *);
static bool notify_helper(QObject *, QEvent *);
static inline void setEventSpontaneous(QEvent *e, bool spontaneous) { e->m_spont = spontaneous; }
virtual void createEventDispatcher();
virtual void eventDispatcherReady();
static void removePostedEvent(QEvent *);
#ifdef Q_OS_WIN
static void removePostedTimerEvent(QObject *object, int timerId);
#endif
QAtomicInt quitLockRef;
void ref();
void deref();
virtual bool canQuitAutomatically();
void quitAutomatically();
virtual void quit();
static QBasicAtomicPointer<QThread> theMainThread;
static QThread *mainThread();
static bool threadRequiresCoreApplication();
static void sendPostedEvents(QObject *receiver, int event_type, QThreadData *data);
static void checkReceiverThread(QObject *receiver);
void cleanupThreadData();
struct QPostEventListLocker
{
QThreadData *threadData;
std::unique_lock<QMutex> locker;
void unlock() { locker.unlock(); }
};
static QPostEventListLocker lockThreadPostEventList(QObject *object);
#endif // QT_NO_QOBJECT
int &argc;
char **argv;
#if defined(Q_OS_WIN)
int origArgc;
char **origArgv; // store unmodified arguments for QCoreApplication::arguments()
bool consoleAllocated = false;
#endif
void appendApplicationPathToLibraryPaths(void);
#ifndef QT_NO_TRANSLATION
QTranslatorList translators;
QReadWriteLock translateMutex;
static bool isTranslatorInstalled(QTranslator *translator);
#endif
QCoreApplicationPrivate::Type application_type;
QString cachedApplicationDirPath;
static QString *cachedApplicationFilePath;
static void setApplicationFilePath(const QString &path);
static inline void clearApplicationFilePath() { delete cachedApplicationFilePath; cachedApplicationFilePath = nullptr; }
#ifndef QT_NO_QOBJECT
void execCleanup();
bool in_exec;
bool aboutToQuitEmitted;
bool threadData_clean;
static QAbstractEventDispatcher *eventDispatcher;
static bool is_app_running;
static bool is_app_closing;
#endif
static bool setuidAllowed;
static uint attribs;
static inline bool testAttribute(uint flag) { return attribs & (1 << flag); }
void processCommandLineArguments();
QString qmljs_debug_arguments; // a string containing arguments for js/qml debugging.
inline QString qmljsDebugArgumentsString() const { return qmljs_debug_arguments; }
#ifdef QT_NO_QOBJECT
QCoreApplication *q_ptr;
#endif
};
QT_END_NAMESPACE
#endif // QCOREAPPLICATION_P_H

View File

@ -0,0 +1,54 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCORECMDLINEARGS_P_H
#define QCORECMDLINEARGS_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
#include "QtCore/qstring.h"
#include "QtCore/qstringlist.h"
#if defined(Q_OS_WIN)
# ifdef Q_OS_WIN32
# include <qt_windows.h> // first to suppress min, max macros.
# include <shlobj.h>
# else
# include <qt_windows.h>
# endif
QT_BEGIN_NAMESPACE
#if defined(Q_OS_WIN32)
static inline QStringList qWinCmdArgs(const QString &cmdLine)
{
QStringList result;
int size;
if (wchar_t **argv = CommandLineToArgvW((const wchar_t *)cmdLine.utf16(), &size)) {
result.reserve(size);
wchar_t **argvEnd = argv + size;
for (wchar_t **a = argv; a < argvEnd; ++a)
result.append(QString::fromWCharArray(*a));
LocalFree(argv);
}
return result;
}
#endif // Q_OS_WIN32
QT_END_NAMESPACE
#endif // Q_OS_WIN
#endif // QCORECMDLINEARGS_WIN_P_H

View File

@ -0,0 +1,37 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDATASTREAM_P_H
#define QDATASTREAM_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
#include <qdatastream.h>
QT_BEGIN_NAMESPACE
#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
class QDataStreamPrivate
{
public:
QDataStreamPrivate() : floatingPointPrecision(QDataStream::DoublePrecision),
transactionDepth(0) { }
QDataStream::FloatingPointPrecision floatingPointPrecision;
int transactionDepth;
};
#endif
QT_END_NAMESPACE
#endif // QDATASTREAM_P_H

View File

@ -0,0 +1,30 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDATAURL_P_H
#define QDATAURL_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of qDecodeDataUrl. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
#include "QtCore/qurl.h"
#include "QtCore/qbytearray.h"
#include "QtCore/qstring.h"
#include "QtCore/qpair.h"
QT_BEGIN_NAMESPACE
Q_CORE_EXPORT bool qDecodeDataUrl(const QUrl &url, QString &mimeType, QByteArray &payload);
QT_END_NAMESPACE
#endif // QDATAURL_P_H

View File

@ -0,0 +1,130 @@
// Copyright (C) 2022 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDATETIME_P_H
#define QDATETIME_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
#include "qplatformdefs.h"
#include "QtCore/qatomic.h"
#include "QtCore/qdatetime.h"
#include "QtCore/qshareddata.h"
#include "QtCore/qtimezone.h"
#if QT_CONFIG(timezone)
#include "qtimezone.h"
#endif
#include <chrono>
QT_BEGIN_NAMESPACE
class QDateTimePrivate : public QSharedData
{
public:
// forward the declarations from QDateTime (this makes them public)
typedef QDateTime::ShortData QDateTimeShortData;
typedef QDateTime::Data QDateTimeData;
// Never change or delete this enum, it is required for backwards compatible
// serialization of QDateTime before 5.2, so is essentially public API
enum Spec {
LocalUnknown = -1,
LocalStandard = 0,
LocalDST = 1,
UTC = 2,
OffsetFromUTC = 3,
TimeZone = 4
};
// Daylight Time Status
enum DaylightStatus {
UnknownDaylightTime = -1,
StandardTime = 0,
DaylightTime = 1
};
// Status of date/time
enum StatusFlag {
ShortData = 0x01,
ValidDate = 0x02,
ValidTime = 0x04,
ValidDateTime = 0x08,
TimeSpecMask = 0x30,
SetToStandardTime = 0x40,
SetToDaylightTime = 0x80,
ValidityMask = ValidDate | ValidTime | ValidDateTime,
DaylightMask = SetToStandardTime | SetToDaylightTime,
};
Q_DECLARE_FLAGS(StatusFlags, StatusFlag)
enum {
TimeSpecShift = 4,
};
struct ZoneState {
qint64 when; // ms after zone/local 1970 start; may be revised from the input time.
int offset = 0; // seconds
DaylightStatus dst = UnknownDaylightTime;
// Other fields are set, if possible, even when valid is false due to spring-forward.
bool valid = false;
ZoneState(qint64 local) : when(local) {}
ZoneState(qint64 w, int o, DaylightStatus d, bool v = true)
: when(w), offset(o), dst(d), valid(v) {}
};
static QDateTime::Data create(QDate toDate, QTime toTime, const QTimeZone &timeZone);
#if QT_CONFIG(timezone)
static ZoneState zoneStateAtMillis(const QTimeZone &zone, qint64 millis, DaylightStatus dst);
#endif // timezone
static ZoneState expressUtcAsLocal(qint64 utcMSecs);
static ZoneState localStateAtMillis(qint64 millis, DaylightStatus dst);
static QString localNameAtMillis(qint64 millis, DaylightStatus dst); // empty if unknown
StatusFlags m_status = StatusFlag(Qt::LocalTime << TimeSpecShift);
qint64 m_msecs = 0;
int m_offsetFromUtc = 0;
QTimeZone m_timeZone;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimePrivate::StatusFlags)
namespace QtPrivate {
namespace DateTimeConstants {
using namespace std::chrono;
constexpr qint64 SECS_PER_MIN = minutes::period::num;
constexpr qint64 SECS_PER_HOUR = hours::period::num;
constexpr qint64 SECS_PER_DAY = SECS_PER_HOUR * 24; // std::chrono::days is C++20
constexpr qint64 MINS_PER_HOUR = std::ratio_divide<hours::period, minutes::period>::num;
constexpr qint64 MSECS_PER_SEC = milliseconds::period::den;
constexpr qint64 MSECS_PER_MIN = SECS_PER_MIN * MSECS_PER_SEC;
constexpr qint64 MSECS_PER_HOUR = SECS_PER_HOUR * MSECS_PER_SEC;
constexpr qint64 MSECS_PER_DAY = SECS_PER_DAY * MSECS_PER_SEC;
constexpr qint64 JULIAN_DAY_FOR_EPOCH = 2440588; // result of QDate(1970, 1, 1).toJulianDay()
}
}
QT_END_NAMESPACE
#endif // QDATETIME_P_H

View File

@ -0,0 +1,274 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDATETIMEPARSER_P_H
#define QDATETIMEPARSER_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
#include "qplatformdefs.h"
#include "QtCore/qatomic.h"
#include "QtCore/qcalendar.h"
#include "QtCore/qcoreapplication.h"
#include "QtCore/qdatetime.h"
#include "QtCore/qlist.h"
#include "QtCore/qlocale.h"
#include "QtCore/qstringlist.h"
#ifndef QT_BOOTSTRAPPED
# include "QtCore/qvariant.h"
#endif
QT_REQUIRE_CONFIG(datetimeparser);
#define QDATETIMEEDIT_TIME_MIN QTime(0, 0) // Prefer QDate::startOfDay()
#define QDATETIMEEDIT_TIME_MAX QTime(23, 59, 59, 999) // Prefer QDate::endOfDay()
#define QDATETIMEEDIT_DATE_MIN QDate(100, 1, 1)
#define QDATETIMEEDIT_COMPAT_DATE_MIN QDate(1752, 9, 14)
#define QDATETIMEEDIT_DATE_MAX QDate(9999, 12, 31)
#define QDATETIMEEDIT_DATE_INITIAL QDate(2000, 1, 1)
QT_BEGIN_NAMESPACE
class Q_CORE_EXPORT QDateTimeParser
{
public:
enum Context {
FromString,
DateTimeEdit
};
QDateTimeParser(QMetaType::Type t, Context ctx, const QCalendar &cal = QCalendar())
: parserType(t), context(ctx), calendar(cal)
{
defaultLocale = QLocale::system();
first.type = FirstSection;
first.pos = -1;
first.count = -1;
first.zeroesAdded = 0;
last.type = LastSection;
last.pos = -1;
last.count = -1;
last.zeroesAdded = 0;
none.type = NoSection;
none.pos = -1;
none.count = -1;
none.zeroesAdded = 0;
}
virtual ~QDateTimeParser();
enum Section {
NoSection = 0x00000,
AmPmSection = 0x00001,
MSecSection = 0x00002,
SecondSection = 0x00004,
MinuteSection = 0x00008,
Hour12Section = 0x00010,
Hour24Section = 0x00020,
TimeZoneSection = 0x00040,
HourSectionMask = (Hour12Section | Hour24Section),
TimeSectionMask = (MSecSection | SecondSection | MinuteSection |
HourSectionMask | AmPmSection | TimeZoneSection),
DaySection = 0x00100,
MonthSection = 0x00200,
YearSection = 0x00400,
YearSection2Digits = 0x00800,
YearSectionMask = YearSection | YearSection2Digits,
DayOfWeekSectionShort = 0x01000,
DayOfWeekSectionLong = 0x02000,
DayOfWeekSectionMask = DayOfWeekSectionShort | DayOfWeekSectionLong,
DaySectionMask = DaySection | DayOfWeekSectionMask,
DateSectionMask = DaySectionMask | MonthSection | YearSectionMask,
Internal = 0x10000,
FirstSection = 0x20000 | Internal,
LastSection = 0x40000 | Internal,
CalendarPopupSection = 0x80000 | Internal,
NoSectionIndex = -1,
FirstSectionIndex = -2,
LastSectionIndex = -3,
CalendarPopupIndex = -4
}; // extending qdatetimeedit.h's equivalent
Q_DECLARE_FLAGS(Sections, Section)
struct Q_CORE_EXPORT SectionNode {
Section type;
mutable int pos;
int count; // (used as Case(count) indicator for AmPmSection)
int zeroesAdded;
static QString name(Section s);
QString name() const { return name(type); }
QString format() const;
int maxChange() const;
};
enum State { // duplicated from QValidator
Invalid,
Intermediate,
Acceptable
};
struct StateNode {
StateNode() : state(Invalid), padded(0), conflicts(false) {}
StateNode(const QDateTime &val, State ok=Acceptable, int pad=0, bool bad=false)
: value(val), state(ok), padded(pad), conflicts(bad) {}
QDateTime value;
State state;
int padded;
bool conflicts;
};
enum AmPm {
AmText,
PmText
};
StateNode parse(const QString &input, int position,
const QDateTime &defaultValue, bool fixup) const;
bool fromString(const QString &text, QDate *date, QTime *time) const;
bool fromString(const QString &text, QDateTime* datetime) const;
bool parseFormat(QStringView format);
enum FieldInfoFlag {
Numeric = 0x01,
FixedWidth = 0x02,
AllowPartial = 0x04,
Fraction = 0x08
};
Q_DECLARE_FLAGS(FieldInfo, FieldInfoFlag)
FieldInfo fieldInfo(int index) const;
void setDefaultLocale(const QLocale &loc) { defaultLocale = loc; }
virtual QString displayText() const { return m_text; }
void setCalendar(const QCalendar &calendar);
private:
int sectionMaxSize(Section s, int count) const;
QString sectionText(const QString &text, int sectionIndex, int index) const;
StateNode scanString(const QDateTime &defaultValue, bool fixup) const;
struct ParsedSection {
int value;
int used;
int zeroes;
State state;
constexpr ParsedSection(State ok = Invalid,
int val = 0, int read = 0, int zs = 0)
: value(ok == Invalid ? -1 : val), used(read), zeroes(zs), state(ok)
{}
};
ParsedSection parseSection(const QDateTime &currentValue, int sectionIndex, int offset) const;
int findMonth(const QString &str1, int monthstart, int sectionIndex,
int year, QString *monthName = nullptr, int *used = nullptr) const;
int findDay(const QString &str1, int intDaystart, int sectionIndex,
QString *dayName = nullptr, int *used = nullptr) const;
ParsedSection findUtcOffset(QStringView str, int mode) const;
ParsedSection findTimeZoneName(QStringView str, const QDateTime &when) const;
ParsedSection findTimeZone(QStringView str, const QDateTime &when,
int maxVal, int minVal, int mode) const;
// Implemented in qlocaltime.cpp:
static int startsWithLocalTimeZone(const QStringView name);
enum AmPmFinder {
Neither = -1,
AM = 0,
PM = 1,
PossibleAM = 2,
PossiblePM = 3,
PossibleBoth = 4
};
AmPmFinder findAmPm(QString &str, int index, int *used = nullptr) const;
bool potentialValue(QStringView str, int min, int max, int index,
const QDateTime &currentValue, int insert) const;
bool potentialValue(const QString &str, int min, int max, int index,
const QDateTime &currentValue, int insert) const
{
return potentialValue(QStringView(str), min, max, index, currentValue, insert);
}
enum Case {
NativeCase,
LowerCase,
UpperCase
};
QString getAmPmText(AmPm ap, Case cs) const;
friend class QDTPUnitTestParser;
protected: // for the benefit of QDateTimeEditPrivate
int sectionSize(int index) const;
int sectionMaxSize(int index) const;
int sectionPos(int index) const;
int sectionPos(const SectionNode &sn) const;
const SectionNode &sectionNode(int index) const;
Section sectionType(int index) const;
QString sectionText(int sectionIndex) const;
int getDigit(const QDateTime &dt, int index) const;
bool setDigit(QDateTime &t, int index, int newval) const;
int absoluteMax(int index, const QDateTime &value = QDateTime()) const;
int absoluteMin(int index) const;
bool skipToNextSection(int section, const QDateTime &current, QStringView sectionText) const;
bool skipToNextSection(int section, const QDateTime &current, const QString &sectionText) const
{
return skipToNextSection(section, current, QStringView(sectionText));
}
QString stateName(State s) const;
virtual QDateTime getMinimum() const;
virtual QDateTime getMaximum() const;
virtual int cursorPosition() const { return -1; }
virtual QLocale locale() const { return defaultLocale; }
mutable int currentSectionIndex = int(NoSectionIndex);
Sections display;
/*
This stores the most recently selected day.
It is useful when considering the following scenario:
1. Date is: 31/01/2000
2. User increments month: 29/02/2000
3. User increments month: 31/03/2000
At step 1, cachedDay stores 31. At step 2, the 31 is invalid for February, so the cachedDay is not updated.
At step 3, the month is changed to March, for which 31 is a valid day. Since 29 < 31, the day is set to cachedDay.
This is good for when users have selected their desired day and are scrolling up or down in the month or year section
and do not want smaller months (or non-leap years) to alter the day that they chose.
*/
mutable int cachedDay = -1;
mutable QString m_text;
QList<SectionNode> sectionNodes;
SectionNode first, last, none, popup;
QStringList separators;
QString displayFormat;
QLocale defaultLocale;
QMetaType::Type parserType;
bool fixday = false;
Context context;
QCalendar calendar;
};
Q_DECLARE_TYPEINFO(QDateTimeParser::SectionNode, Q_PRIMITIVE_TYPE);
Q_CORE_EXPORT bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::SectionNode &s2);
Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::Sections)
Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::FieldInfo)
QT_END_NAMESPACE
#endif // QDATETIME_P_H

View File

@ -0,0 +1,34 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDEADLINETIMER_P_H
#define QDEADLINETIMER_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
QT_BEGIN_NAMESPACE
enum {
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
// t1 contains seconds and t2 contains nanoseconds
QDeadlineTimerNanosecondsInT2 = 1
#else
// t1 contains nanoseconds, t2 is always zero
QDeadlineTimerNanosecondsInT2 = 0
#endif
};
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,102 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDEBUG_P_H
#define QDEBUG_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of other Qt classes. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
#include "QtCore/qdebug.h"
#include "QtCore/qmetaobject.h"
#include "QtCore/qflags.h"
#include "QtCore/qbytearray.h"
QT_BEGIN_NAMESPACE
namespace QtDebugUtils {
Q_CORE_EXPORT QByteArray toPrintable(const char *data, qint64 len, qsizetype maxSize);
// inline helpers for formatting basic classes.
template <class Point>
static inline void formatQPoint(QDebug &debug, const Point &point)
{
debug << point.x() << ',' << point.y();
}
template <class Size>
static inline void formatQSize(QDebug &debug, const Size &size)
{
debug << size.width() << ", " << size.height();
}
template <class Rect>
static inline void formatQRect(QDebug &debug, const Rect &rect)
{
debug << rect.x() << ',' << rect.y() << ' ' << rect.width() << 'x' << rect.height();
}
template <class Margins>
static inline void formatQMargins(QDebug &debug, const Margins &margins)
{
debug << margins.left() << ", " << margins.top() << ", " << margins.right()
<< ", " << margins.bottom();
}
#ifndef QT_NO_QOBJECT
template <class QEnum>
static inline void formatQEnum(QDebug &debug, QEnum value)
{
const QMetaObject *metaObject = qt_getEnumMetaObject(value);
const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(value)));
if (const char *key = me.valueToKey(int(value)))
debug << key;
else
debug << int(value);
}
template <class QEnum>
static inline void formatNonNullQEnum(QDebug &debug, const char *prefix, QEnum value)
{
if (value) {
debug << prefix;
formatQEnum(debug, value);
}
}
template <class Enum>
static inline void formatQFlags(QDebug &debug, const QFlags<Enum> &value)
{
const QMetaEnum me = QMetaEnum::fromType<QFlags<Enum>>();
const QDebugStateSaver saver(debug);
debug.noquote();
debug << me.valueToKeys(value.toInt());
}
template <class Enum>
static inline void formatNonNullQFlags(QDebug &debug, const char *prefix, const QFlags<Enum> &value)
{
if (value) {
debug << prefix;
formatQFlags(debug, value);
}
}
#endif // !QT_NO_QOBJECT
} // namespace QtDebugUtils
QT_END_NAMESPACE
#endif // QDEBUG_P_H

View File

@ -0,0 +1,80 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDIR_P_H
#define QDIR_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qfilesystementry_p.h"
#include "qfilesystemmetadata_p.h"
#include <memory>
QT_BEGIN_NAMESPACE
class QDirPrivate : public QSharedData
{
public:
enum PathNormalization {
DefaultNormalization = 0x00,
AllowUncPaths = 0x01,
RemotePath = 0x02
};
Q_DECLARE_FLAGS(PathNormalizations, PathNormalization)
Q_FLAGS(PathNormalizations)
explicit QDirPrivate(const QString &path, const QStringList &nameFilters_ = QStringList(),
QDir::SortFlags sort_ = QDir::SortFlags(QDir::Name | QDir::IgnoreCase),
QDir::Filters filters_ = QDir::AllEntries);
explicit QDirPrivate(const QDirPrivate &copy);
bool exists() const;
void initFileEngine();
void initFileLists(const QDir &dir) const;
static void sortFileList(QDir::SortFlags, const QFileInfoList &, QStringList *, QFileInfoList *);
static inline QChar getFilterSepChar(const QString &nameFilter);
static inline QStringList splitFilters(const QString &nameFilter, QChar sep = {});
void setPath(const QString &path);
void clearFileLists();
void resolveAbsoluteEntry() const;
mutable bool fileListsInitialized;
mutable QStringList files;
mutable QFileInfoList fileInfos;
QStringList nameFilters;
QDir::SortFlags sort;
QDir::Filters filters;
std::unique_ptr<QAbstractFileEngine> fileEngine;
QFileSystemEntry dirEntry;
mutable QFileSystemEntry absoluteDirEntry;
mutable QFileSystemMetaData metaData;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDirPrivate::PathNormalizations)
Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormalizations flags, bool *ok = nullptr);
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,120 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDOUBLESCANPRINT_P_H
#define QDOUBLESCANPRINT_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of internal files. This header file may change from version to version
// without notice, or even be removed.
//
// We mean it.
//
#include <private/qglobal_p.h>
#if defined(Q_CC_MSVC) && (defined(QT_BOOTSTRAPPED) || defined(QT_NO_DOUBLECONVERSION))
# include <stdio.h>
# include <locale.h>
QT_BEGIN_NAMESPACE
// We can always use _sscanf_l and _snprintf_l on MSVC as those were introduced in 2005.
// MSVC doesn't document what it will do with a NULL locale passed to _sscanf_l or _snprintf_l.
// The documentation for _create_locale() does not formally document "C" to be valid, but an example
// code snippet in the same documentation shows it.
struct QCLocaleT {
QCLocaleT() : locale(_create_locale(LC_ALL, "C"))
{
}
~QCLocaleT()
{
_free_locale(locale);
}
const _locale_t locale;
};
# define QT_CLOCALE_HOLDER Q_GLOBAL_STATIC(QCLocaleT, cLocaleT)
# define QT_CLOCALE cLocaleT()->locale
inline int qDoubleSscanf(const char *buf, _locale_t locale, const char *format, double *d,
int *processed)
{
return _sscanf_l(buf, format, locale, d, processed);
}
inline int qDoubleSnprintf(char *buf, size_t buflen, _locale_t locale, const char *format, double d)
{
return _snprintf_l(buf, buflen, format, locale, d);
}
QT_END_NAMESPACE
#elif defined(QT_BOOTSTRAPPED)
# include <stdio.h>
QT_BEGIN_NAMESPACE
// When bootstrapping we don't have libdouble-conversion available, yet. We can also not use locale
// aware snprintf and sscanf variants in the general case because those are only available on select
// platforms. We can use the regular snprintf and sscanf because we don't do setlocale(3) when
// bootstrapping and the locale is always "C" then.
# define QT_CLOCALE_HOLDER
# define QT_CLOCALE 0
inline int qDoubleSscanf(const char *buf, int, const char *format, double *d, int *processed)
{
return sscanf(buf, format, d, processed);
}
inline int qDoubleSnprintf(char *buf, size_t buflen, int, const char *format, double d)
{
return snprintf(buf, buflen, format, d);
}
QT_END_NAMESPACE
#else // !QT_BOOTSTRAPPED && (!Q_CC_MSVC || !QT_NO_DOUBLECONVERSION)
# ifdef QT_NO_DOUBLECONVERSION
# include <stdio.h>
# include <xlocale.h>
QT_BEGIN_NAMESPACE
// OS X and FreeBSD both treat NULL as the "C" locale for snprintf_l and sscanf_l.
// When other implementations with different behavior show up, we'll have to do newlocale(3) and
// freelocale(3) here. The arguments to those will depend on what the other implementations will
// offer. OS X and FreeBSD again interpret a locale name of NULL as "C", but "C" itself is not
// documented as valid locale name. Mind that the names of the LC_* constants differ between e.g.
// BSD variants and linux.
# define QT_CLOCALE_HOLDER
# define QT_CLOCALE NULL
inline int qDoubleSscanf(const char *buf, locale_t locale, const char *format, double *d,
int *processed)
{
return sscanf_l(buf, locale, format, d, processed);
}
inline int qDoubleSnprintf(char *buf, size_t buflen, locale_t locale, const char *format, double d)
{
return snprintf_l(buf, buflen, locale, format, d);
}
QT_END_NAMESPACE
# else // !QT_NO_DOUBLECONVERSION
# include <double-conversion/double-conversion.h>
# define QT_CLOCALE_HOLDER
# endif // QT_NO_DOUBLECONVERSION
#endif // QT_BOOTSTRAPPED
#endif // QDOUBLESCANPRINT_P_H

View File

@ -0,0 +1,124 @@
// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDUPLICATETRACKER_P_H
#define QDUPLICATETRACKER_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <private/qglobal_p.h>
#if __has_include(<memory_resource>)
# include <unordered_set>
# include <memory_resource>
# include <qhash.h> // for the hashing helpers
#else
# include <qset.h>
#endif
QT_BEGIN_NAMESPACE
template <typename T, size_t Prealloc = 32>
class QDuplicateTracker {
#ifdef __cpp_lib_memory_resource
template <typename HT>
struct QHasher {
size_t storedSeed = QHashSeed::globalSeed();
size_t operator()(const HT &t) const {
return QHashPrivate::calculateHash(t, storedSeed);
}
};
struct node_guesstimate { void *next; size_t hash; T value; };
static constexpr size_t bufferSize(size_t N) {
return N * sizeof(void*) // bucket list
+ N * sizeof(node_guesstimate); // nodes
}
char buffer[bufferSize(Prealloc)];
std::pmr::monotonic_buffer_resource res{buffer, sizeof buffer};
std::pmr::unordered_set<T, QHasher<T>> set{Prealloc, &res};
#else
class Set : public QSet<T> {
qsizetype setSize = 0;
public:
explicit Set(qsizetype n) : QSet<T>{}
{ this->reserve(n); }
auto insert(const T &e) {
auto it = QSet<T>::insert(e);
const auto n = this->size();
return std::pair{it, std::exchange(setSize, n) != n};
}
auto insert(T &&e) {
auto it = QSet<T>::insert(std::move(e));
const auto n = this->size();
return std::pair{it, std::exchange(setSize, n) != n};
}
};
Set set{Prealloc};
#endif
Q_DISABLE_COPY_MOVE(QDuplicateTracker);
public:
static constexpr inline bool uses_pmr =
#ifdef __cpp_lib_memory_resource
true
#else
false
#endif
;
QDuplicateTracker() = default;
explicit QDuplicateTracker(qsizetype n)
#ifdef __cpp_lib_memory_resource
: set{size_t(n), &res}
#else
: set{n}
#endif
{}
Q_DECL_DEPRECATED_X("Pass the capacity to reserve() to the ctor instead.")
void reserve(qsizetype n) { set.reserve(n); }
[[nodiscard]] bool hasSeen(const T &s)
{
return !set.insert(s).second;
}
[[nodiscard]] bool hasSeen(T &&s)
{
return !set.insert(std::move(s)).second;
}
template <typename C>
void appendTo(C &c) const &
{
for (const auto &e : set)
c.push_back(e);
}
template <typename C>
void appendTo(C &c) &&
{
if constexpr (uses_pmr) {
while (!set.empty())
c.push_back(std::move(set.extract(set.begin()).value()));
} else {
return appendTo(c); // lvalue version
}
}
void clear()
{
set.clear();
}
};
QT_END_NAMESPACE
#endif /* QDUPLICATETRACKER_P_H */

View File

@ -0,0 +1,211 @@
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QENDIAN_P_H
#define QENDIAN_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qendian.h>
#include <QtCore/private/qglobal_p.h>
QT_BEGIN_NAMESPACE
enum class QSpecialIntegerBitfieldInitializer {};
constexpr QSpecialIntegerBitfieldInitializer QSpecialIntegerBitfieldZero{};
template<class S>
class QSpecialIntegerStorage
{
public:
using UnsignedStorageType = std::make_unsigned_t<typename S::StorageType>;
constexpr QSpecialIntegerStorage() = default;
constexpr QSpecialIntegerStorage(QSpecialIntegerBitfieldInitializer) : val(0) {}
constexpr QSpecialIntegerStorage(UnsignedStorageType initial) : val(initial) {}
UnsignedStorageType val;
};
template<class S, int pos, int width, class T = typename S::StorageType>
class QSpecialIntegerAccessor;
template<class S, int pos, int width, class T = typename S::StorageType>
class QSpecialIntegerConstAccessor
{
Q_DISABLE_COPY_MOVE(QSpecialIntegerConstAccessor)
public:
using Storage = const QSpecialIntegerStorage<S>;
using Type = T;
using UnsignedType = std::make_unsigned_t<T>;
operator Type() const noexcept
{
if constexpr (std::is_signed_v<Type>) {
UnsignedType i = S::fromSpecial(storage->val);
i <<= (sizeof(Type) * 8) - width - pos;
Type t = Type(i);
t >>= (sizeof(Type) * 8) - width;
return t;
}
return (S::fromSpecial(storage->val) & mask()) >> pos;
}
bool operator!() const noexcept { return !(storage->val & S::toSpecial(mask())); }
static constexpr UnsignedType mask() noexcept
{
if constexpr (width == sizeof(UnsignedType) * 8) {
static_assert(pos == 0);
return ~UnsignedType(0);
} else {
return ((UnsignedType(1) << width) - 1) << pos;
}
}
private:
template<class Storage, typename... Accessors>
friend class QSpecialIntegerBitfieldUnion;
friend class QSpecialIntegerAccessor<S, pos, width, T>;
explicit QSpecialIntegerConstAccessor(Storage *storage) : storage(storage) {}
friend bool operator==(const QSpecialIntegerConstAccessor<S, pos, width, T> &i,
const QSpecialIntegerConstAccessor<S, pos, width, T> &j) noexcept
{
return ((i.storage->val ^ j.storage->val) & S::toSpecial(mask())) == 0;
}
friend bool operator!=(const QSpecialIntegerConstAccessor<S, pos, width, T> &i,
const QSpecialIntegerConstAccessor<S, pos, width, T> &j) noexcept
{
return ((i.storage->val ^ j.storage->val) & S::toSpecial(mask())) != 0;
}
Storage *storage;
};
template<class S, int pos, int width, class T>
class QSpecialIntegerAccessor
{
Q_DISABLE_COPY_MOVE(QSpecialIntegerAccessor)
public:
using Const = QSpecialIntegerConstAccessor<S, pos, width, T>;
using Storage = QSpecialIntegerStorage<S>;
using Type = T;
using UnsignedType = std::make_unsigned_t<T>;
QSpecialIntegerAccessor &operator=(Type t)
{
UnsignedType i = S::fromSpecial(storage->val);
i &= ~Const::mask();
i |= (UnsignedType(t) << pos) & Const::mask();
storage->val = S::toSpecial(i);
return *this;
}
operator Const() { return Const(storage); }
private:
template<class Storage, typename... Accessors>
friend class QSpecialIntegerBitfieldUnion;
explicit QSpecialIntegerAccessor(Storage *storage) : storage(storage) {}
Storage *storage;
};
template<class S, typename... Accessors>
class QSpecialIntegerBitfieldUnion
{
public:
constexpr QSpecialIntegerBitfieldUnion() = default;
constexpr QSpecialIntegerBitfieldUnion(QSpecialIntegerBitfieldInitializer initial)
: storage(initial)
{}
constexpr QSpecialIntegerBitfieldUnion(
typename QSpecialIntegerStorage<S>::UnsignedStorageType initial)
: storage(initial)
{}
template<typename A>
void set(typename A::Type value)
{
member<A>() = value;
}
template<typename A>
typename A::Type get() const
{
return member<A>();
}
typename QSpecialIntegerStorage<S>::UnsignedStorageType data() const
{
return storage.val;
}
private:
template<typename A>
static constexpr bool isAccessor = std::disjunction_v<std::is_same<A, Accessors>...>;
template<typename A>
A member()
{
static_assert(isAccessor<A>);
return A(&storage);
}
template<typename A>
typename A::Const member() const
{
static_assert(isAccessor<A>);
return typename A::Const(&storage);
}
QSpecialIntegerStorage<S> storage;
};
template<typename T, typename... Accessors>
using QLEIntegerBitfieldUnion
= QSpecialIntegerBitfieldUnion<QLittleEndianStorageType<T>, Accessors...>;
template<typename T, typename... Accessors>
using QBEIntegerBitfieldUnion
= QSpecialIntegerBitfieldUnion<QBigEndianStorageType<T>, Accessors...>;
template<typename... Accessors>
using qint32_le_bitfield_union = QLEIntegerBitfieldUnion<int, Accessors...>;
template<typename... Accessors>
using quint32_le_bitfield_union = QLEIntegerBitfieldUnion<uint, Accessors...>;
template<typename... Accessors>
using qint32_be_bitfield_union = QBEIntegerBitfieldUnion<int, Accessors...>;
template<typename... Accessors>
using quint32_be_bitfield_union = QBEIntegerBitfieldUnion<uint, Accessors...>;
template<int pos, int width, typename T = int>
using qint32_le_bitfield_member
= QSpecialIntegerAccessor<QLittleEndianStorageType<int>, pos, width, T>;
template<int pos, int width, typename T = uint>
using quint32_le_bitfield_member
= QSpecialIntegerAccessor<QLittleEndianStorageType<uint>, pos, width, T>;
template<int pos, int width, typename T = int>
using qint32_be_bitfield_member
= QSpecialIntegerAccessor<QBigEndianStorageType<int>, pos, width, T>;
template<int pos, int width, typename T = uint>
using quint32_be_bitfield_member
= QSpecialIntegerAccessor<QBigEndianStorageType<uint>, pos, width, T>;
QT_END_NAMESPACE
#endif // QENDIAN_P_H

View File

@ -0,0 +1,149 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QEVENTDISPATCHER_WIN_P_H
#define QEVENTDISPATCHER_WIN_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "QtCore/qabstracteventdispatcher.h"
#include "QtCore/qt_windows.h"
#include "QtCore/qhash.h"
#include "QtCore/qatomic.h"
#include "qabstracteventdispatcher_p.h"
QT_BEGIN_NAMESPACE
class QEventDispatcherWin32Private;
// forward declaration
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
quint64 qt_msectime();
class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher
{
Q_OBJECT
Q_DECLARE_PRIVATE(QEventDispatcherWin32)
public:
explicit QEventDispatcherWin32(QObject *parent = nullptr);
~QEventDispatcherWin32();
bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags) override;
void registerSocketNotifier(QSocketNotifier *notifier) override;
void unregisterSocketNotifier(QSocketNotifier *notifier) override;
void registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object) override;
bool unregisterTimer(int timerId) override;
bool unregisterTimers(QObject *object) override;
QList<TimerInfo> registeredTimers(QObject *object) const override;
int remainingTime(int timerId) override;
void wakeUp() override;
void interrupt() override;
void startingUp() override;
void closingDown() override;
bool event(QEvent *e) override;
HWND internalHwnd();
protected:
QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = nullptr);
virtual void sendPostedEvents();
void doUnregisterSocketNotifier(QSocketNotifier *notifier);
private:
friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
};
struct QSockNot {
QSocketNotifier *obj;
int fd;
};
typedef QHash<int, QSockNot *> QSNDict;
struct QSockFd {
long event;
long mask;
bool selected;
explicit inline QSockFd(long ev = 0, long ma = 0) : event(ev), mask(ma), selected(false) { }
};
typedef QHash<int, QSockFd> QSFDict;
struct WinTimerInfo { // internal timer info
QObject *dispatcher;
int timerId;
qint64 interval;
Qt::TimerType timerType;
quint64 timeout; // - when to actually fire
QObject *obj; // - object to receive events
bool inTimerEvent;
UINT fastTimerId;
};
class QZeroTimerEvent : public QTimerEvent
{
public:
explicit inline QZeroTimerEvent(int timerId)
: QTimerEvent(timerId)
{ t = QEvent::ZeroTimerEvent; }
};
typedef QHash<int, WinTimerInfo*> WinTimerDict; // fast dict of timers
class Q_CORE_EXPORT QEventDispatcherWin32Private : public QAbstractEventDispatcherPrivate
{
Q_DECLARE_PUBLIC(QEventDispatcherWin32)
public:
QEventDispatcherWin32Private();
~QEventDispatcherWin32Private();
QAtomicInt interrupt;
// internal window handle used for socketnotifiers/timers/etc
HWND internalHwnd;
// for controlling when to send posted events
UINT_PTR sendPostedEventsTimerId;
QAtomicInt wakeUps;
void startPostedEventsTimer();
// timers
WinTimerDict timerDict;
void registerTimer(WinTimerInfo *t);
void unregisterTimer(WinTimerInfo *t);
void sendTimerEvent(int timerId);
// socket notifiers
QSNDict sn_read;
QSNDict sn_write;
QSNDict sn_except;
QSFDict active_fd;
bool activateNotifiersPosted;
void postActivateSocketNotifiers();
void doWsaAsyncSelect(int socket, long event);
bool closingDown = false;
QList<MSG> queuedUserInputEvents;
QList<MSG> queuedSocketEvents;
};
QT_END_NAMESPACE
#endif // QEVENTDISPATCHER_WIN_P_H

View File

@ -0,0 +1,55 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QEVENTLOOP_P_H
#define QEVENTLOOP_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qcoreapplication.h"
#include "qobject_p.h"
QT_BEGIN_NAMESPACE
class QEventLoopPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QEventLoop)
public:
inline QEventLoopPrivate()
: inExec(false)
{
returnCode.storeRelaxed(-1);
exit.storeRelaxed(true);
}
QAtomicInt quitLockRef;
QBasicAtomicInt exit; // bool
QBasicAtomicInt returnCode;
bool inExec;
void ref()
{
quitLockRef.ref();
}
void deref()
{
if (!quitLockRef.deref() && inExec) {
qApp->postEvent(q_ptr, new QEvent(QEvent::Quit));
}
}
};
QT_END_NAMESPACE
#endif // QEVENTLOOP_P_H

View File

@ -0,0 +1,52 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFACTORYCACHEREGISTRATION_P_H
#define QFACTORYCACHEREGISTRATION_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qglobal.h>
#if !defined(QT_BOOTSTRAPPED) && QT_CONFIG(cpp_winrt)
# define QT_USE_FACTORY_CACHE_REGISTRATION
#endif
#ifdef QT_USE_FACTORY_CACHE_REGISTRATION
#include "qt_winrtbase_p.h"
QT_BEGIN_NAMESPACE
namespace detail {
class QWinRTFactoryCacheRegistration
{
public:
Q_CORE_EXPORT explicit QWinRTFactoryCacheRegistration(QFunctionPointer clearFunction);
Q_CORE_EXPORT ~QWinRTFactoryCacheRegistration();
Q_CORE_EXPORT static void clearAllCaches();
Q_DISABLE_COPY_MOVE(QWinRTFactoryCacheRegistration)
private:
QWinRTFactoryCacheRegistration **m_prevNext = nullptr;
QWinRTFactoryCacheRegistration *m_next = nullptr;
QFunctionPointer m_clearFunction;
};
inline QWinRTFactoryCacheRegistration reg([]() noexcept { winrt::clear_factory_cache(); });
}
QT_END_NAMESPACE
#endif
#endif // QFACTORYCACHEREGISTRATION_P_H

View File

@ -0,0 +1,113 @@
// Copyright (C) 2017 The Qt Company Ltd.
// Copyright (C) 2022 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFACTORYLOADER_P_H
#define QFACTORYLOADER_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "QtCore/qglobal.h"
#ifndef QT_NO_QOBJECT
#include "QtCore/private/qplugin_p.h"
#include "QtCore/qcbormap.h"
#include "QtCore/qcborvalue.h"
#include "QtCore/qmap.h"
#include "QtCore/qobject.h"
#include "QtCore/qplugin.h"
QT_BEGIN_NAMESPACE
class QJsonObject;
class QLibraryPrivate;
class QPluginParsedMetaData
{
QCborValue data;
bool setError(const QString &errorString) Q_DECL_COLD_FUNCTION
{
data = errorString;
return false;
}
public:
QPluginParsedMetaData() = default;
QPluginParsedMetaData(QByteArrayView input) { parse(input); }
bool isError() const { return !data.isMap(); }
QString errorString() const { return data.toString(); }
bool parse(QByteArrayView input);
bool parse(QPluginMetaData metaData)
{ return parse(QByteArrayView(reinterpret_cast<const char *>(metaData.data), metaData.size)); }
QJsonObject toJson() const; // only for QLibrary & QPluginLoader
// if data is not a map, toMap() returns empty, so shall these functions
QCborMap toCbor() const { return data.toMap(); }
QCborValue value(QtPluginMetaDataKeys k) const { return data[int(k)]; }
};
class QFactoryLoaderPrivate;
class Q_CORE_EXPORT QFactoryLoader : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QFactoryLoader)
public:
explicit QFactoryLoader(const char *iid,
const QString &suffix = QString(),
Qt::CaseSensitivity = Qt::CaseSensitive);
#if QT_CONFIG(library)
~QFactoryLoader();
void update();
static void refreshAll();
#if defined(Q_OS_UNIX) && !defined (Q_OS_MAC)
QLibraryPrivate *library(const QString &key) const;
#endif // Q_OS_UNIX && !Q_OS_MAC
#endif // QT_CONFIG(library)
void setExtraSearchPath(const QString &path);
QMultiMap<int, QString> keyMap() const;
int indexOf(const QString &needle) const;
using MetaDataList = QList<QPluginParsedMetaData>;
MetaDataList metaData() const;
QObject *instance(int index) const;
};
template <class PluginInterface, class FactoryInterface, typename ...Args>
PluginInterface *qLoadPlugin(const QFactoryLoader *loader, const QString &key, Args &&...args)
{
const int index = loader->indexOf(key);
if (index != -1) {
QObject *factoryObject = loader->instance(index);
if (FactoryInterface *factory = qobject_cast<FactoryInterface *>(factoryObject))
if (PluginInterface *result = factory->create(key, std::forward<Args>(args)...))
return result;
}
return nullptr;
}
template <class PluginInterface, class FactoryInterface, typename Arg>
Q_DECL_DEPRECATED PluginInterface *qLoadPlugin1(const QFactoryLoader *loader, const QString &key, Arg &&arg)
{ return qLoadPlugin<PluginInterface, FactoryInterface>(loader, key, std::forward<Arg>(arg)); }
QT_END_NAMESPACE
#endif // QT_NO_QOBJECT
#endif // QFACTORYLOADER_P_H

View File

@ -0,0 +1,44 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILE_P_H
#define QFILE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qfile.h"
#include "private/qfiledevice_p.h"
QT_BEGIN_NAMESPACE
class QTemporaryFile;
class QFilePrivate : public QFileDevicePrivate
{
Q_DECLARE_PUBLIC(QFile)
friend class QTemporaryFile;
protected:
QFilePrivate();
~QFilePrivate();
bool openExternalFile(QIODevice::OpenMode flags, int fd, QFile::FileHandleFlags handleFlags);
bool openExternalFile(QIODevice::OpenMode flags, FILE *fh, QFile::FileHandleFlags handleFlags);
QAbstractFileEngine *engine() const override;
QString fileName;
};
QT_END_NAMESPACE
#endif // QFILE_P_H

View File

@ -0,0 +1,138 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILEDEVICE_P_H
#define QFILEDEVICE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "private/qiodevice_p.h"
#include "qfiledevice.h"
#include <memory>
#if defined(Q_OS_UNIX)
# include <sys/types.h> // for mode_t
# include <sys/stat.h> // for mode_t constants
#elif defined(Q_OS_WINDOWS)
# include <qt_windows.h>
# include <winnt.h> // for SECURITY_DESCRIPTOR
# include <optional>
# if defined(QT_BOOTSTRAPPED)
# define QT_FEATURE_fslibs -1
# else
# define QT_FEATURE_fslibs 1
# endif // QT_BOOTSTRAPPED
#endif
QT_BEGIN_NAMESPACE
class QAbstractFileEngine;
class QFSFileEngine;
class QFileDevicePrivate : public QIODevicePrivate
{
Q_DECLARE_PUBLIC(QFileDevice)
protected:
QFileDevicePrivate();
~QFileDevicePrivate();
virtual QAbstractFileEngine *engine() const;
inline bool ensureFlushed() const;
bool putCharHelper(char c) override;
void setError(QFileDevice::FileError err);
void setError(QFileDevice::FileError err, const QString &errorString);
void setError(QFileDevice::FileError err, int errNum);
mutable std::unique_ptr<QAbstractFileEngine> fileEngine;
mutable qint64 cachedSize;
QFileDevice::FileHandleFlags handleFlags;
QFileDevice::FileError error;
bool lastWasWrite;
};
inline bool QFileDevicePrivate::ensureFlushed() const
{
// This function ensures that the write buffer has been flushed (const
// because certain const functions need to call it.
if (lastWasWrite) {
const_cast<QFileDevicePrivate *>(this)->lastWasWrite = false;
if (!const_cast<QFileDevice *>(q_func())->flush())
return false;
}
return true;
}
#ifdef Q_OS_UNIX
namespace QtPrivate {
constexpr mode_t toMode_t(QFileDevice::Permissions permissions)
{
mode_t mode = 0;
if (permissions & (QFileDevice::ReadOwner | QFileDevice::ReadUser))
mode |= S_IRUSR;
if (permissions & (QFileDevice::WriteOwner | QFileDevice::WriteUser))
mode |= S_IWUSR;
if (permissions & (QFileDevice::ExeOwner | QFileDevice::ExeUser))
mode |= S_IXUSR;
if (permissions & QFileDevice::ReadGroup)
mode |= S_IRGRP;
if (permissions & QFileDevice::WriteGroup)
mode |= S_IWGRP;
if (permissions & QFileDevice::ExeGroup)
mode |= S_IXGRP;
if (permissions & QFileDevice::ReadOther)
mode |= S_IROTH;
if (permissions & QFileDevice::WriteOther)
mode |= S_IWOTH;
if (permissions & QFileDevice::ExeOther)
mode |= S_IXOTH;
return mode;
}
} // namespace QtPrivate
#elif defined(Q_OS_WINDOWS)
class QNativeFilePermissions
{
public:
QNativeFilePermissions(std::optional<QFileDevice::Permissions> perms, bool isDir);
SECURITY_ATTRIBUTES *securityAttributes();
bool isOk() const { return ok; }
private:
bool ok = false;
bool isNull = true;
// At most 1 allow + 1 deny ACEs for user and group, 1 allow ACE for others
static constexpr auto MaxNumACEs = 5;
static constexpr auto MaxACLSize =
sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE) + SECURITY_MAX_SID_SIZE) * MaxNumACEs;
SECURITY_ATTRIBUTES sa;
#if QT_CONFIG(fslibs)
SECURITY_DESCRIPTOR sd;
alignas(DWORD) char aclStorage[MaxACLSize];
#endif
};
#endif // Q_OS_UNIX
QT_END_NAMESPACE
#endif // QFILEDEVICE_P_H

View File

@ -0,0 +1,173 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILEINFO_P_H
#define QFILEINFO_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qfileinfo.h"
#include "qdatetime.h"
#include "qatomic.h"
#include "qshareddata.h"
#include "qfilesystemengine_p.h"
#include <QtCore/private/qabstractfileengine_p.h>
#include <QtCore/private/qfilesystementry_p.h>
#include <QtCore/private/qfilesystemmetadata_p.h>
#include <memory>
QT_BEGIN_NAMESPACE
class QFileInfoPrivate : public QSharedData
{
public:
enum {
// note: cachedFlags is only 30-bits wide
CachedFileFlags = 0x01,
CachedLinkTypeFlag = 0x02,
CachedBundleTypeFlag = 0x04,
CachedSize = 0x08,
CachedATime = 0x10,
CachedBTime = 0x20,
CachedMCTime = 0x40,
CachedMTime = 0x80,
CachedPerms = 0x100
};
inline QFileInfoPrivate()
: QSharedData(), fileEngine(nullptr),
cachedFlags(0),
isDefaultConstructed(true),
cache_enabled(true), fileFlags(0), fileSize(0)
{}
inline QFileInfoPrivate(const QFileInfoPrivate &copy)
: QSharedData(copy),
fileEntry(copy.fileEntry),
metaData(copy.metaData),
fileEngine(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)),
cachedFlags(0),
#ifndef QT_NO_FSFILEENGINE
isDefaultConstructed(false),
#else
isDefaultConstructed(!fileEngine),
#endif
cache_enabled(copy.cache_enabled), fileFlags(0), fileSize(0)
{}
inline QFileInfoPrivate(const QString &file)
: fileEntry(file),
fileEngine(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)),
cachedFlags(0),
#ifndef QT_NO_FSFILEENGINE
isDefaultConstructed(file.isEmpty()),
#else
isDefaultConstructed(!fileEngine),
#endif
cache_enabled(true), fileFlags(0), fileSize(0)
{
}
inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data)
: QSharedData(),
fileEntry(file),
metaData(data),
fileEngine(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)),
cachedFlags(0),
isDefaultConstructed(false),
cache_enabled(true), fileFlags(0), fileSize(0)
{
//If the file engine is not null, this maybe a "mount point" for a custom file engine
//in which case we can't trust the metadata
if (fileEngine)
metaData = QFileSystemMetaData();
}
inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data, std::unique_ptr<QAbstractFileEngine> engine)
: fileEntry(file),
metaData(data),
fileEngine{std::move(engine)},
cachedFlags(0),
#ifndef QT_NO_FSFILEENGINE
isDefaultConstructed(false),
#else
isDefaultConstructed(!fileEngine),
#endif
cache_enabled(true), fileFlags(0), fileSize(0)
{
}
inline void clearFlags() const {
fileFlags = 0;
cachedFlags = 0;
if (fileEngine)
(void)fileEngine->fileFlags(QAbstractFileEngine::Refresh);
}
inline void clear() {
metaData.clear();
clearFlags();
for (int i = QAbstractFileEngine::NFileNames - 1 ; i >= 0 ; --i)
fileNames[i].clear();
fileOwners[1].clear();
fileOwners[0].clear();
}
uint getFileFlags(QAbstractFileEngine::FileFlags) const;
QDateTime &getFileTime(QAbstractFileEngine::FileTime) const;
QString getFileName(QAbstractFileEngine::FileName) const;
QString getFileOwner(QAbstractFileEngine::FileOwner own) const;
QFileSystemEntry fileEntry;
mutable QFileSystemMetaData metaData;
std::unique_ptr<QAbstractFileEngine> const fileEngine;
mutable QString fileNames[QAbstractFileEngine::NFileNames];
mutable QString fileOwners[2]; // QAbstractFileEngine::FileOwner: OwnerUser and OwnerGroup
mutable QDateTime fileTimes[4]; // QAbstractFileEngine::FileTime: BirthTime, MetadataChangeTime, ModificationTime, AccessTime
mutable uint cachedFlags : 30;
bool const isDefaultConstructed : 1; // QFileInfo is a default constructed instance
bool cache_enabled : 1;
mutable uint fileFlags;
mutable qint64 fileSize;
inline bool getCachedFlag(uint c) const
{ return cache_enabled ? (cachedFlags & c) : 0; }
inline void setCachedFlag(uint c) const
{ if (cache_enabled) cachedFlags |= c; }
template <typename Ret, typename FSLambda, typename EngineLambda>
Ret checkAttribute(Ret defaultValue, QFileSystemMetaData::MetaDataFlags fsFlags, const FSLambda &fsLambda,
const EngineLambda &engineLambda) const
{
if (isDefaultConstructed)
return defaultValue;
if (fileEngine)
return engineLambda();
if (!cache_enabled || !metaData.hasFlags(fsFlags)) {
QFileSystemEngine::fillMetaData(fileEntry, metaData, fsFlags);
// ignore errors, fillMetaData will have cleared the flags
}
return fsLambda();
}
template <typename Ret, typename FSLambda, typename EngineLambda>
Ret checkAttribute(QFileSystemMetaData::MetaDataFlags fsFlags, const FSLambda &fsLambda,
const EngineLambda &engineLambda) const
{
return checkAttribute(Ret(), fsFlags, fsLambda, engineLambda);
}
};
QT_END_NAMESPACE
#endif // QFILEINFO_P_H

View File

@ -0,0 +1,48 @@
// Copyright (C) 2013 BlackBerry Limited. All rights reserved.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILESELECTOR_P_H
#define QFILESELECTOR_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/QString>
#include <QtCore/QFileSelector>
#include <private/qobject_p.h>
QT_BEGIN_NAMESPACE
struct QFileSelectorSharedData //Not QSharedData because currently is just a global store
{
QStringList staticSelectors;
QStringList preloadedStatics;
};
class Q_CORE_EXPORT QFileSelectorPrivate : QObjectPrivate //Exported for use in other modules (like QtGui)
{
Q_DECLARE_PUBLIC(QFileSelector)
public:
static void updateSelectors();
static QStringList platformSelectors();
static void addStatics(const QStringList &); //For loading GUI statics from other Qt modules
static QString selectionHelper(const QString &path, const QString &fileName,
const QStringList &selectors, QChar indicator = u'+');
QFileSelectorPrivate();
QString select(const QString &filePath) const;
QStringList extras;
};
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,153 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILESYSTEMENGINE_P_H
#define QFILESYSTEMENGINE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qfile.h"
#include "qfilesystementry_p.h"
#include "qfilesystemmetadata_p.h"
#include <QtCore/private/qsystemerror_p.h>
#include <optional>
QT_BEGIN_NAMESPACE
#define Q_RETURN_ON_INVALID_FILENAME(message, result) \
{ \
QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC).warning(message); \
errno = EINVAL; \
return (result); \
}
inline bool qIsFilenameBroken(const QByteArray &name)
{
return name.contains('\0');
}
inline bool qIsFilenameBroken(const QString &name)
{
return name.contains(QLatin1Char('\0'));
}
inline bool qIsFilenameBroken(const QFileSystemEntry &entry)
{
return qIsFilenameBroken(entry.nativeFilePath());
}
#define Q_CHECK_FILE_NAME(name, result) \
do { \
if (Q_UNLIKELY((name).isEmpty())) \
Q_RETURN_ON_INVALID_FILENAME("Empty filename passed to function", (result)); \
if (Q_UNLIKELY(qIsFilenameBroken(name))) \
Q_RETURN_ON_INVALID_FILENAME("Broken filename passed to function", (result)); \
} while (false)
class Q_AUTOTEST_EXPORT QFileSystemEngine
{
public:
static bool isCaseSensitive()
{
#ifndef Q_OS_WIN
return true;
#else
return false;
#endif
}
static QFileSystemEntry getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data);
static QFileSystemEntry getJunctionTarget(const QFileSystemEntry &link, QFileSystemMetaData &data);
static QFileSystemEntry canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data);
static QFileSystemEntry absoluteName(const QFileSystemEntry &entry);
static QByteArray id(const QFileSystemEntry &entry);
static QString resolveUserName(const QFileSystemEntry &entry, QFileSystemMetaData &data);
static QString resolveGroupName(const QFileSystemEntry &entry, QFileSystemMetaData &data);
#if defined(Q_OS_UNIX)
static QString resolveUserName(uint userId);
static QString resolveGroupName(uint groupId);
#endif
#if defined(Q_OS_DARWIN)
static QString bundleName(const QFileSystemEntry &entry);
#else
static QString bundleName(const QFileSystemEntry &) { return QString(); }
#endif
static bool fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data,
QFileSystemMetaData::MetaDataFlags what);
#if defined(Q_OS_UNIX)
static bool cloneFile(int srcfd, int dstfd, const QFileSystemMetaData &knownData);
static bool fillMetaData(int fd, QFileSystemMetaData &data); // what = PosixStatFlags
static QByteArray id(int fd);
static bool setFileTime(int fd, const QDateTime &newDate,
QAbstractFileEngine::FileTime whatTime, QSystemError &error);
static bool setPermissions(int fd, QFile::Permissions permissions, QSystemError &error,
QFileSystemMetaData *data = nullptr);
#endif
#if defined(Q_OS_WIN)
static QFileSystemEntry junctionTarget(const QFileSystemEntry &link, QFileSystemMetaData &data);
static bool uncListSharesOnServer(const QString &server, QStringList *list); //Used also by QFSFileEngineIterator::hasNext()
static bool fillMetaData(int fd, QFileSystemMetaData &data,
QFileSystemMetaData::MetaDataFlags what);
static bool fillMetaData(HANDLE fHandle, QFileSystemMetaData &data,
QFileSystemMetaData::MetaDataFlags what);
static bool fillPermissions(const QFileSystemEntry &entry, QFileSystemMetaData &data,
QFileSystemMetaData::MetaDataFlags what);
static QByteArray id(HANDLE fHandle);
static bool setFileTime(HANDLE fHandle, const QDateTime &newDate,
QAbstractFileEngine::FileTime whatTime, QSystemError &error);
static QString owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own);
static QString nativeAbsoluteFilePath(const QString &path);
static bool isDirPath(const QString &path, bool *existed);
#endif
//homePath, rootPath and tempPath shall return clean paths
static QString homePath();
static QString rootPath();
static QString tempPath();
static bool createDirectory(const QFileSystemEntry &entry, bool createParents,
std::optional<QFile::Permissions> permissions = std::nullopt);
static bool removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents);
static bool createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error);
static bool copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error);
static bool moveFileToTrash(const QFileSystemEntry &source, QFileSystemEntry &newLocation, QSystemError &error);
static bool renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error);
static bool renameOverwriteFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error);
static bool removeFile(const QFileSystemEntry &entry, QSystemError &error);
static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error,
QFileSystemMetaData *data = nullptr);
// unused, therefore not implemented
static bool setFileTime(const QFileSystemEntry &entry, const QDateTime &newDate,
QAbstractFileEngine::FileTime whatTime, QSystemError &error);
static bool setCurrentPath(const QFileSystemEntry &entry);
static QFileSystemEntry currentPath();
static QAbstractFileEngine *resolveEntryAndCreateLegacyEngine(QFileSystemEntry &entry,
QFileSystemMetaData &data);
private:
static QString slowCanonicalized(const QString &path);
#if defined(Q_OS_WIN)
static void clearWinStatData(QFileSystemMetaData &data);
#endif
};
QT_END_NAMESPACE
#endif // include guard

View File

@ -0,0 +1,93 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILESYSTEMENTRY_P_H
#define QFILESYSTEMENTRY_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
#include <QtCore/qstring.h>
#include <QtCore/qbytearray.h>
QT_BEGIN_NAMESPACE
class QFileSystemEntry
{
public:
#ifndef Q_OS_WIN
typedef QByteArray NativePath;
#else
typedef QString NativePath;
#endif
struct FromNativePath{};
struct FromInternalPath{};
QFileSystemEntry();
explicit QFileSystemEntry(const QString &filePath);
QFileSystemEntry(const QString &filePath, FromInternalPath dummy);
QFileSystemEntry(const NativePath &nativeFilePath, FromNativePath dummy);
QFileSystemEntry(const QString &filePath, const NativePath &nativeFilePath);
QString filePath() const;
QString fileName() const;
QString path() const;
NativePath nativeFilePath() const;
QString baseName() const;
QString completeBaseName() const;
QString suffix() const;
QString completeSuffix() const;
bool isAbsolute() const;
bool isRelative() const;
bool isClean() const;
#if defined(Q_OS_WIN)
bool isDriveRoot() const;
static bool isDriveRootPath(const QString &path);
static QString removeUncOrLongPathPrefix(QString path);
#endif
bool isRoot() const;
bool isEmpty() const
{
return m_filePath.isEmpty() && m_nativeFilePath.isEmpty();
}
void clear()
{
*this = QFileSystemEntry();
}
Q_CORE_EXPORT static bool isRootPath(const QString &path);
private:
// creates the QString version out of the bytearray version
void resolveFilePath() const;
// creates the bytearray version out of the QString version
void resolveNativeFilePath() const;
// resolves the separator
void findLastSeparator() const;
// resolves the dots and the separator
void findFileNameSeparators() const;
mutable QString m_filePath; // always has slashes as separator
mutable NativePath m_nativeFilePath; // native encoding and separators
mutable qint16 m_lastSeparator; // index in m_filePath of last separator
mutable qint16 m_firstDotInFileName; // index after m_filePath for first dot (.)
mutable qint16 m_lastDotInFileName; // index after m_firstDotInFileName for last dot (.)
};
QT_END_NAMESPACE
#endif // include guard

View File

@ -0,0 +1,70 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILESYSTEMITERATOR_P_H
#define QFILESYSTEMITERATOR_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qglobal.h>
#ifndef QT_NO_FILESYSTEMITERATOR
#include <QtCore/qdir.h>
#include <QtCore/qdiriterator.h>
#include <QtCore/qstringlist.h>
#include <QtCore/private/qfilesystementry_p.h>
#include <QtCore/private/qfilesystemmetadata_p.h>
// Platform-specific headers
#if !defined(Q_OS_WIN)
#include <QtCore/qscopedpointer.h>
#endif
QT_BEGIN_NAMESPACE
class QFileSystemIterator
{
public:
QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters,
const QStringList &nameFilters, QDirIterator::IteratorFlags flags
= QDirIterator::FollowSymlinks | QDirIterator::Subdirectories);
~QFileSystemIterator();
bool advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData);
private:
QFileSystemEntry::NativePath nativePath;
// Platform-specific data
#if defined(Q_OS_WIN)
QString dirPath;
HANDLE findFileHandle;
QStringList uncShares;
bool uncFallback;
int uncShareIndex;
bool onlyDirs;
#else
QT_DIR *dir;
QT_DIRENT *dirEntry;
int lastError;
#endif
Q_DISABLE_COPY_MOVE(QFileSystemIterator)
};
QT_END_NAMESPACE
#endif // QT_NO_FILESYSTEMITERATOR
#endif // include guard

View File

@ -0,0 +1,375 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILESYSTEMMETADATA_P_H
#define QFILESYSTEMMETADATA_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qplatformdefs.h"
#include <QtCore/qglobal.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qtimezone.h>
#include <QtCore/private/qabstractfileengine_p.h>
// Platform-specific includes
#ifdef Q_OS_WIN
# include <QtCore/qt_windows.h>
# ifndef IO_REPARSE_TAG_SYMLINK
# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
# endif
#endif
#ifdef Q_OS_UNIX
struct statx;
#endif
QT_BEGIN_NAMESPACE
class QFileSystemEngine;
class Q_AUTOTEST_EXPORT QFileSystemMetaData
{
public:
QFileSystemMetaData()
: size_(-1)
{
}
enum MetaDataFlag {
// Permissions, overlaps with QFile::Permissions
OtherReadPermission = 0x00000004, OtherWritePermission = 0x00000002, OtherExecutePermission = 0x00000001,
GroupReadPermission = 0x00000040, GroupWritePermission = 0x00000020, GroupExecutePermission = 0x00000010,
UserReadPermission = 0x00000400, UserWritePermission = 0x00000200, UserExecutePermission = 0x00000100,
OwnerReadPermission = 0x00004000, OwnerWritePermission = 0x00002000, OwnerExecutePermission = 0x00001000,
OtherPermissions = OtherReadPermission | OtherWritePermission | OtherExecutePermission,
GroupPermissions = GroupReadPermission | GroupWritePermission | GroupExecutePermission,
UserPermissions = UserReadPermission | UserWritePermission | UserExecutePermission,
OwnerPermissions = OwnerReadPermission | OwnerWritePermission | OwnerExecutePermission,
ReadPermissions = OtherReadPermission | GroupReadPermission | UserReadPermission | OwnerReadPermission,
WritePermissions = OtherWritePermission | GroupWritePermission | UserWritePermission | OwnerWritePermission,
ExecutePermissions = OtherExecutePermission | GroupExecutePermission | UserExecutePermission | OwnerExecutePermission,
Permissions = OtherPermissions | GroupPermissions | UserPermissions | OwnerPermissions,
// Type
LinkType = 0x00010000,
FileType = 0x00020000,
DirectoryType = 0x00040000,
#if defined(Q_OS_DARWIN)
BundleType = 0x00080000,
AliasType = 0x08000000,
#else
BundleType = 0x0,
AliasType = 0x0,
#endif
#if defined(Q_OS_WIN)
JunctionType = 0x04000000,
WinLnkType = 0x08000000, // Note: Uses the same position for AliasType on Mac
#else
JunctionType = 0x0,
WinLnkType = 0x0,
#endif
SequentialType = 0x00800000, // Note: overlaps with QAbstractFileEngine::RootFlag
LegacyLinkType = LinkType | AliasType | WinLnkType,
Type = LinkType | FileType | DirectoryType | BundleType | SequentialType | AliasType,
// Attributes
HiddenAttribute = 0x00100000,
SizeAttribute = 0x00200000, // Note: overlaps with QAbstractFileEngine::LocalDiskFlag
ExistsAttribute = 0x00400000, // For historical reasons, indicates existence of data, not the file
#if defined(Q_OS_WIN)
WasDeletedAttribute = 0x0,
#else
WasDeletedAttribute = 0x40000000, // Indicates the file was deleted
#endif
Attributes = HiddenAttribute | SizeAttribute | ExistsAttribute | WasDeletedAttribute,
// Times - if we know one of them, we know them all
AccessTime = 0x02000000,
BirthTime = 0x02000000,
MetadataChangeTime = 0x02000000,
ModificationTime = 0x02000000,
Times = AccessTime | BirthTime | MetadataChangeTime | ModificationTime,
// Owner IDs
UserId = 0x10000000,
GroupId = 0x20000000,
OwnerIds = UserId | GroupId,
PosixStatFlags = QFileSystemMetaData::OtherPermissions
| QFileSystemMetaData::GroupPermissions
| QFileSystemMetaData::OwnerPermissions
| QFileSystemMetaData::FileType
| QFileSystemMetaData::DirectoryType
| QFileSystemMetaData::SequentialType
| QFileSystemMetaData::SizeAttribute
| QFileSystemMetaData::WasDeletedAttribute
| QFileSystemMetaData::Times
| QFileSystemMetaData::OwnerIds,
#if defined(Q_OS_WIN)
WinStatFlags = QFileSystemMetaData::FileType
| QFileSystemMetaData::DirectoryType
| QFileSystemMetaData::HiddenAttribute
| QFileSystemMetaData::ExistsAttribute
| QFileSystemMetaData::SizeAttribute
| QFileSystemMetaData::Times,
#endif
AllMetaDataFlags = 0xFFFFFFFF
};
Q_DECLARE_FLAGS(MetaDataFlags, MetaDataFlag)
bool hasFlags(MetaDataFlags flags) const
{
return ((knownFlagsMask & flags) == flags);
}
MetaDataFlags missingFlags(MetaDataFlags flags)
{
return flags & ~knownFlagsMask;
}
void clear()
{
knownFlagsMask = {};
}
void clearFlags(MetaDataFlags flags = AllMetaDataFlags)
{
knownFlagsMask &= ~flags;
}
bool exists() const { return entryFlags.testAnyFlag(ExistsAttribute); }
bool isLink() const { return entryFlags.testAnyFlag(LinkType); }
bool isFile() const { return entryFlags.testAnyFlag(FileType); }
bool isDirectory() const { return entryFlags.testAnyFlag(DirectoryType); }
bool isBundle() const;
bool isAlias() const;
bool isLegacyLink() const { return entryFlags.testAnyFlag(LegacyLinkType); }
bool isSequential() const { return entryFlags.testAnyFlag(SequentialType); }
bool isHidden() const { return entryFlags.testAnyFlag(HiddenAttribute); }
bool wasDeleted() const { return entryFlags.testAnyFlag(WasDeletedAttribute); }
#if defined(Q_OS_WIN)
bool isLnkFile() const { return entryFlags.testAnyFlag(WinLnkType); }
bool isJunction() const { return entryFlags.testAnyFlag(JunctionType); }
#else
bool isLnkFile() const { return false; }
bool isJunction() const { return false; }
#endif
qint64 size() const { return size_; }
QFile::Permissions permissions() const;
QDateTime accessTime() const;
QDateTime birthTime() const;
QDateTime metadataChangeTime() const;
QDateTime modificationTime() const;
QDateTime fileTime(QAbstractFileEngine::FileTime time) const;
uint userId() const;
uint groupId() const;
uint ownerId(QAbstractFileEngine::FileOwner owner) const;
#ifdef Q_OS_UNIX
void fillFromStatxBuf(const struct statx &statBuffer);
void fillFromStatBuf(const QT_STATBUF &statBuffer);
void fillFromDirEnt(const QT_DIRENT &statBuffer);
#endif
#if defined(Q_OS_WIN)
inline void fillFromFileAttribute(DWORD fileAttribute, bool isDriveRoot = false);
inline void fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType = false, bool isDriveRoot = false);
inline void fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo);
#endif
private:
friend class QFileSystemEngine;
MetaDataFlags knownFlagsMask;
MetaDataFlags entryFlags;
qint64 size_ = 0;
// Platform-specific data goes here:
#if defined(Q_OS_WIN)
DWORD fileAttribute_;
FILETIME birthTime_;
FILETIME changeTime_;
FILETIME lastAccessTime_;
FILETIME lastWriteTime_;
#else
// msec precision
qint64 accessTime_ = 0;
qint64 birthTime_ = 0;
qint64 metadataChangeTime_ = 0;
qint64 modificationTime_ = 0;
uint userId_ = (uint) -2;
uint groupId_ = (uint) -2;
#endif
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QFileSystemMetaData::MetaDataFlags)
inline QFile::Permissions QFileSystemMetaData::permissions() const { return QFile::Permissions::fromInt((Permissions & entryFlags).toInt()); }
#if defined(Q_OS_DARWIN)
inline bool QFileSystemMetaData::isBundle() const { return entryFlags.testAnyFlag(BundleType); }
inline bool QFileSystemMetaData::isAlias() const { return entryFlags.testAnyFlag(AliasType); }
#else
inline bool QFileSystemMetaData::isBundle() const { return false; }
inline bool QFileSystemMetaData::isAlias() const { return false; }
#endif
#if defined(Q_OS_UNIX) || defined (Q_OS_WIN)
inline QDateTime QFileSystemMetaData::fileTime(QAbstractFileEngine::FileTime time) const
{
switch (time) {
case QAbstractFileEngine::ModificationTime:
return modificationTime();
case QAbstractFileEngine::AccessTime:
return accessTime();
case QAbstractFileEngine::BirthTime:
return birthTime();
case QAbstractFileEngine::MetadataChangeTime:
return metadataChangeTime();
}
return QDateTime();
}
#endif
#if defined(Q_OS_UNIX)
inline QDateTime QFileSystemMetaData::birthTime() const
{
return birthTime_
? QDateTime::fromMSecsSinceEpoch(birthTime_, QTimeZone::UTC)
: QDateTime();
}
inline QDateTime QFileSystemMetaData::metadataChangeTime() const
{
return metadataChangeTime_
? QDateTime::fromMSecsSinceEpoch(metadataChangeTime_, QTimeZone::UTC)
: QDateTime();
}
inline QDateTime QFileSystemMetaData::modificationTime() const
{
return modificationTime_
? QDateTime::fromMSecsSinceEpoch(modificationTime_, QTimeZone::UTC)
: QDateTime();
}
inline QDateTime QFileSystemMetaData::accessTime() const
{
return accessTime_
? QDateTime::fromMSecsSinceEpoch(accessTime_, QTimeZone::UTC)
: QDateTime();
}
inline uint QFileSystemMetaData::userId() const { return userId_; }
inline uint QFileSystemMetaData::groupId() const { return groupId_; }
inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) const
{
if (owner == QAbstractFileEngine::OwnerUser)
return userId();
else
return groupId();
}
#endif
#if defined(Q_OS_WIN)
inline uint QFileSystemMetaData::userId() const { return (uint) -2; }
inline uint QFileSystemMetaData::groupId() const { return (uint) -2; }
inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) const
{
if (owner == QAbstractFileEngine::OwnerUser)
return userId();
else
return groupId();
}
inline void QFileSystemMetaData::fillFromFileAttribute(DWORD fileAttribute,bool isDriveRoot)
{
fileAttribute_ = fileAttribute;
// Ignore the hidden attribute for drives.
if (!isDriveRoot && (fileAttribute_ & FILE_ATTRIBUTE_HIDDEN))
entryFlags |= HiddenAttribute;
entryFlags |= ((fileAttribute & FILE_ATTRIBUTE_DIRECTORY) ? DirectoryType: FileType);
entryFlags |= ExistsAttribute;
knownFlagsMask |= FileType | DirectoryType | HiddenAttribute | ExistsAttribute;
}
inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType, bool isDriveRoot)
{
fillFromFileAttribute(findData.dwFileAttributes, isDriveRoot);
birthTime_ = findData.ftCreationTime;
lastAccessTime_ = findData.ftLastAccessTime;
changeTime_ = lastWriteTime_ = findData.ftLastWriteTime;
if (fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) {
size_ = 0;
} else {
size_ = findData.nFileSizeHigh;
size_ <<= 32;
size_ += findData.nFileSizeLow;
}
knownFlagsMask |= Times | SizeAttribute;
if (setLinkType) {
knownFlagsMask |= LinkType;
entryFlags &= ~LinkType;
if (fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) {
if (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
entryFlags |= LinkType;
#if defined(IO_REPARSE_TAG_MOUNT_POINT)
} else if ((fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY)
&& (findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) {
entryFlags |= JunctionType;
#endif
}
}
}
}
inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo)
{
fillFromFileAttribute(fileInfo.dwFileAttributes);
birthTime_ = fileInfo.ftCreationTime;
lastAccessTime_ = fileInfo.ftLastAccessTime;
changeTime_ = lastWriteTime_ = fileInfo.ftLastWriteTime;
if (fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) {
size_ = 0;
} else {
size_ = fileInfo.nFileSizeHigh;
size_ <<= 32;
size_ += fileInfo.nFileSizeLow;
}
knownFlagsMask |= Times | SizeAttribute;
}
#endif // Q_OS_WIN
QT_END_NAMESPACE
#endif // include guard

View File

@ -0,0 +1,87 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILESYSTEMWATCHER_P_H
#define QFILESYSTEMWATCHER_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qfilesystemwatcher.h"
QT_REQUIRE_CONFIG(filesystemwatcher);
#include <private/qobject_p.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qhash.h>
QT_BEGIN_NAMESPACE
class QFileSystemWatcherEngine : public QObject
{
Q_OBJECT
protected:
inline QFileSystemWatcherEngine(QObject *parent)
: QObject(parent)
{
}
public:
// fills \a files and \a directories with the \a paths it could
// watch, and returns a list of paths this engine could not watch
virtual QStringList addPaths(const QStringList &paths,
QStringList *files,
QStringList *directories) = 0;
// removes \a paths from \a files and \a directories, and returns
// a list of paths this engine does not know about (either addPath
// failed or wasn't called)
virtual QStringList removePaths(const QStringList &paths,
QStringList *files,
QStringList *directories) = 0;
Q_SIGNALS:
void fileChanged(const QString &path, bool removed);
void directoryChanged(const QString &path, bool removed);
};
class QFileSystemWatcherPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QFileSystemWatcher)
static QFileSystemWatcherEngine *createNativeEngine(QObject *parent);
public:
QFileSystemWatcherPrivate();
void init();
void initPollerEngine();
QFileSystemWatcherEngine *native, *poller;
QStringList files, directories;
// private slots
void _q_fileChanged(const QString &path, bool removed);
void _q_directoryChanged(const QString &path, bool removed);
#if defined(Q_OS_WIN)
void _q_winDriveLockForRemoval(const QString &);
void _q_winDriveLockForRemovalFailed(const QString &);
void _q_winDriveRemoved(const QString &);
private:
QHash<QChar, QStringList> temporarilyRemovedPaths;
#endif // Q_OS_WIN
};
QT_END_NAMESPACE
#endif // QFILESYSTEMWATCHER_P_H

View File

@ -0,0 +1,89 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILESYSTEMWATCHER_POLLING_P_H
#define QFILESYSTEMWATCHER_POLLING_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qfileinfo.h>
#include <QtCore/qmutex.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qdir.h>
#include <QtCore/qtimer.h>
#include <QtCore/qhash.h>
#include "qfilesystemwatcher_p.h"
QT_REQUIRE_CONFIG(filesystemwatcher);
QT_BEGIN_NAMESPACE
enum { PollingInterval = 1000 };
class QPollingFileSystemWatcherEngine : public QFileSystemWatcherEngine
{
Q_OBJECT
class FileInfo
{
uint ownerId;
uint groupId;
QFile::Permissions permissions;
QDateTime lastModified;
QStringList entries;
public:
FileInfo(const QFileInfo &fileInfo)
: ownerId(fileInfo.ownerId()),
groupId(fileInfo.groupId()),
permissions(fileInfo.permissions()),
lastModified(fileInfo.lastModified())
{
if (fileInfo.isDir()) {
entries = fileInfo.absoluteDir().entryList(QDir::AllEntries);
}
}
FileInfo &operator=(const QFileInfo &fileInfo)
{
*this = FileInfo(fileInfo);
return *this;
}
bool operator!=(const QFileInfo &fileInfo) const
{
if (fileInfo.isDir() && entries != fileInfo.absoluteDir().entryList(QDir::AllEntries))
return true;
return (ownerId != fileInfo.ownerId()
|| groupId != fileInfo.groupId()
|| permissions != fileInfo.permissions()
|| lastModified != fileInfo.lastModified());
}
};
QHash<QString, FileInfo> files, directories;
public:
QPollingFileSystemWatcherEngine(QObject *parent);
QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories) override;
QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories) override;
private Q_SLOTS:
void timeout();
private:
QTimer timer;
};
QT_END_NAMESPACE
#endif // QFILESYSTEMWATCHER_POLLING_P_H

Some files were not shown because too many files have changed in this diff Show More