Long live QtPrivate::CompactStorage<>
This is a generalization of QPrivateSlotObject's FunctionStorage. Changes from the old API: - uses a more neutral API (s/func/object/) - preserves cv-qualifiers and value categories - preserves constexpr'ness - adds a disambiguation tag (e.g. for use in a compressed_pair). The main feature is that it transparently uses the empty base-class optimization to stow away empty classes without allocating separate bytes for them. To be used for the public QSlotObject and QGenericRunnable, at least, so finally pulled the trigger and made it a separate component. Change-Id: I9a13bbdd1dcf64aaf5fc7b2d40a60050d61800b6 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>bb10
parent
9f0b4e18cd
commit
b7780b5e5d
|
|
@ -282,6 +282,7 @@ qt_internal_add_module(Core
|
|||
tools/qduplicatetracker_p.h
|
||||
tools/qflatmap_p.h
|
||||
tools/qfreelist.cpp tools/qfreelist_p.h
|
||||
tools/qfunctionaltools_impl.h
|
||||
tools/qhashfunctions.h
|
||||
tools/qiterator.h
|
||||
tools/qline.cpp tools/qline.h
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <QtCore/private/qglobal_p.h>
|
||||
#include "QtCore/qcoreevent.h"
|
||||
#include <QtCore/qfunctionaltools_impl.h>
|
||||
#include "QtCore/qlist.h"
|
||||
#include "QtCore/qobject.h"
|
||||
#include "QtCore/qpointer.h"
|
||||
|
|
@ -255,28 +256,7 @@ namespace QtPrivate {
|
|||
inline const QObject *getQObject(const QObjectPrivate *d) { return d->q_func(); }
|
||||
|
||||
template <typename Func>
|
||||
struct FunctionStorageByValue
|
||||
{
|
||||
Func f;
|
||||
Func &func() noexcept { return f; }
|
||||
};
|
||||
|
||||
template <typename Func>
|
||||
struct FunctionStorageEmptyBaseClassOptimization : Func
|
||||
{
|
||||
Func &func() noexcept { return *this; }
|
||||
using Func::Func;
|
||||
};
|
||||
|
||||
template <typename Func>
|
||||
using FunctionStorage = typename std::conditional_t<
|
||||
std::conjunction_v<
|
||||
std::is_empty<Func>,
|
||||
std::negation<std::is_final<Func>>
|
||||
>,
|
||||
FunctionStorageEmptyBaseClassOptimization<Func>,
|
||||
FunctionStorageByValue<Func>
|
||||
>;
|
||||
using FunctionStorage = QtPrivate::CompactStorage<Func>;
|
||||
|
||||
template <typename ObjPrivate> inline void assertObjectType(QObjectPrivate *d)
|
||||
{
|
||||
|
|
@ -296,11 +276,11 @@ class QPrivateSlotObject : public QSlotObjectBase, private FunctionStorage<Func>
|
|||
delete that;
|
||||
break;
|
||||
case Call:
|
||||
FuncType::template call<Args, R>(that->func(),
|
||||
FuncType::template call<Args, R>(that->object(),
|
||||
static_cast<typename FuncType::Object *>(QObjectPrivate::get(r)), a);
|
||||
break;
|
||||
case Compare:
|
||||
*ret = *reinterpret_cast<Func *>(a) == that->func();
|
||||
*ret = *reinterpret_cast<Func *>(a) == that->object();
|
||||
break;
|
||||
case NumOperations: ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright (C) 2023 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
|
||||
|
||||
#if 0
|
||||
#pragma qt_sync_skip_header_check
|
||||
#pragma qt_sync_stop_processing
|
||||
#endif
|
||||
|
||||
#ifndef QFUNCTIONALTOOLS_IMPL_H
|
||||
#define QFUNCTIONALTOOLS_IMPL_H
|
||||
|
||||
#include <QtCore/qtconfigmacros.h>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtPrivate {
|
||||
|
||||
namespace detail {
|
||||
|
||||
#define FOR_EACH_CVREF(op) \
|
||||
op(&) \
|
||||
op(const &) \
|
||||
op(&&) \
|
||||
op(const &&) \
|
||||
/* end */
|
||||
|
||||
|
||||
template <typename Object, typename = void>
|
||||
struct StorageByValue
|
||||
{
|
||||
Object o;
|
||||
#define MAKE_GETTER(cvref) \
|
||||
constexpr Object cvref object() cvref noexcept \
|
||||
{ return static_cast<Object cvref>(o); }
|
||||
FOR_EACH_CVREF(MAKE_GETTER)
|
||||
#undef MAKE_GETTER
|
||||
};
|
||||
|
||||
template <typename Object, typename = void>
|
||||
struct StorageEmptyBaseClassOptimization : Object
|
||||
{
|
||||
#define MAKE_GETTER(cvref) \
|
||||
constexpr Object cvref object() cvref noexcept \
|
||||
{ return static_cast<Object cvref>(*this); }
|
||||
FOR_EACH_CVREF(MAKE_GETTER)
|
||||
#undef MAKE_GETTER
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <typename Object, typename Tag = void>
|
||||
using CompactStorage = typename std::conditional_t<
|
||||
std::conjunction_v<
|
||||
std::is_empty<Object>,
|
||||
std::negation<std::is_final<Object>>
|
||||
>,
|
||||
detail::StorageEmptyBaseClassOptimization<Object, Tag>,
|
||||
detail::StorageByValue<Object, Tag>
|
||||
>;
|
||||
|
||||
} // namespace QtPrivate
|
||||
|
||||
#undef FOR_EACH_CVREF
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QFUNCTIONALTOOLS_IMPL_H
|
||||
Loading…
Reference in New Issue