Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qfunctionaltools_impl.h
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#if 0
6#pragma qt_sync_skip_header_check
7#pragma qt_sync_stop_processing
8#endif
9
10#ifndef QFUNCTIONALTOOLS_IMPL_H
11#define QFUNCTIONALTOOLS_IMPL_H
12
13#include <QtCore/qtconfigmacros.h>
14
15#include <type_traits>
16#include <utility>
17
18QT_BEGIN_NAMESPACE
19
20/*!
21 \class QtPrivate::CompactStorage
22 \internal
23 CompactStorage is a small utility class that stores an object in the
24 most space-efficient way possible. If the stored type is empty and not
25 marked as \c final, CompactStorage inherits from it directly, allowing
26 the compiler to apply the Empty Base Optimization (EBO). Otherwise,
27 the object is stored as a regular data member.
28
29 This class is typically used as a private base class for utility types
30 that need to optionally carry extra data without increasing their size.
31 The stored object can be accessed through the \c object() accessor,
32 which returns the contained object in any const/reference combination.
33
34 Example 1:
35
36 // FileHandle carries a lightweight context describing
37 // the underlying OS resource.
38 struct Context {
39 int fd = -1;
40 bool isTemporary = false;
41 };
42
43 struct FileHandle : private QtPrivate::CompactStorage<Context>
44 {
45 using Storage = QtPrivate::CompactStorage<Context>;
46
47 FileHandle(int descriptor, bool temp)
48 : Storage(Context{descriptor, temp})
49 {}
50
51 void open(int descriptor, bool temp) noexcept {
52 object().fd = descriptor;
53 object().isTemporary = temp;
54 }
55
56 void close() noexcept {
57 if (object().isTemporary)
58 ::close(object().fd);
59 }
60 };
61
62 Example 2:
63
64 // When the stored type is empty, EBO removes any overhead.
65 struct EmptyContext {};
66
67 struct LightweightHandle : private QtPrivate::CompactStorage<EmptyContext>
68 {
69 using Storage = QtPrivate::CompactStorage<EmptyContext>;
70 int handle = -1;
71
72 void reset(int h) noexcept { handle = h; }
73 };
74
75 static_assert(sizeof(LightweightHandle) == sizeof(int));
76*/
77
78namespace QtPrivate {
79
80namespace detail {
81
82#define FOR_EACH_CVREF(op)
83 op(&)
84 op(const &)
85 op(&&)
86 op(const &&)
87 /* end */
88
89
90template <typename Object, typename = void>
92{
93 Object o;
94#define MAKE_GETTER(cvref)
95 constexpr Object cvref object() cvref noexcept
96 { return static_cast<Object cvref>(o); }
98#undef MAKE_GETTER
99};
100
101template <typename Object, typename Tag = void>
103{
106 : Object(std::move(o))
107 {}
109 : Object(o)
110 {}
111
112#define MAKE_GETTER(cvref)
113 constexpr Object cvref object() cvref noexcept
114 { return static_cast<Object cvref>(*this); }
116#undef MAKE_GETTER
117};
118} // namespace detail
119
120template <typename Object, typename Tag = void>
125 >,
128 >;
129
130} // namespace QtPrivate
131
132#undef FOR_EACH_CVREF
133
134QT_END_NAMESPACE
135
136#endif // QFUNCTIONALTOOLS_IMPL_H
#define FOR_EACH_CVREF(op)