summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qtypeinfo.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/global/qtypeinfo.h')
-rw-r--r--src/corelib/global/qtypeinfo.h140
1 files changed, 65 insertions, 75 deletions
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index 96b52ca0b2..255a2b33c6 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -1,51 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qglobal.h>
+// Copyright (C) 2016 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 QTYPEINFO_H
+#define QTYPEINFO_H
+
+#include <QtCore/qcompilerdetection.h>
#include <QtCore/qcontainerfwd.h>
+
#include <variant>
#include <optional>
#include <tuple>
-
-#ifndef QTYPEINFO_H
-#define QTYPEINFO_H
+#include <type_traits>
QT_BEGIN_NAMESPACE
@@ -55,9 +21,30 @@ class QDebug;
QTypeInfo - type trait functionality
*/
+namespace QtPrivate {
+
+// A trivially copyable class must also have a trivial, non-deleted
+// destructor [class.prop/1.3], CWG1734. Some implementations don't
+// check for a trivial destructor, because of backwards compatibility
+// with C++98's definition of trivial copyability.
+// Since trivial copiability has implications for the ABI, implementations
+// can't "just fix" their traits. So, although formally redundant, we
+// explicitly check for trivial destruction here.
template <typename T>
inline constexpr bool qIsRelocatable = std::is_trivially_copyable_v<T> && std::is_trivially_destructible_v<T>;
+// Denotes types that are trivially default constructible, and for which
+// value-initialization can be achieved by filling their storage with 0 bits.
+// There is no type trait we can use for this, so we hardcode a list of
+// possibilities that we know are OK on the architectures that we support.
+// The most notable exception are pointers to data members, which for instance
+// on the Itanium ABI are initialized to -1.
+template <typename T>
+inline constexpr bool qIsValueInitializationBitwiseZero =
+ std::is_scalar_v<T> && !std::is_member_object_pointer_v<T>;
+
+}
+
/*
The catch-all template.
*/
@@ -67,10 +54,11 @@ class QTypeInfo
{
public:
enum {
- isPointer = std::is_pointer_v<T>,
- isIntegral = std::is_integral_v<T>,
+ isPointer [[deprecated("Use std::is_pointer instead")]] = std::is_pointer_v<T>,
+ isIntegral [[deprecated("Use std::is_integral instead")]] = std::is_integral_v<T>,
isComplex = !std::is_trivial_v<T>,
- isRelocatable = qIsRelocatable<T>,
+ isRelocatable = QtPrivate::qIsRelocatable<T>,
+ isValueInitializationBitwiseZero = QtPrivate::qIsValueInitializationBitwiseZero<T>,
};
};
@@ -79,10 +67,11 @@ class QTypeInfo<void>
{
public:
enum {
- isPointer = false,
- isIntegral = false,
+ isPointer [[deprecated("Use std::is_pointer instead")]] = false,
+ isIntegral [[deprecated("Use std::is_integral instead")]] = false,
isComplex = false,
isRelocatable = false,
+ isValueInitializationBitwiseZero = false,
};
};
@@ -113,20 +102,33 @@ class QTypeInfoMerger
public:
static constexpr bool isComplex = ((QTypeInfo<Ts>::isComplex) || ...);
static constexpr bool isRelocatable = ((QTypeInfo<Ts>::isRelocatable) && ...);
- static constexpr bool isPointer = false;
- static constexpr bool isIntegral = false;
+ [[deprecated("Use std::is_pointer instead")]] static constexpr bool isPointer = false;
+ [[deprecated("Use std::is_integral instead")]] static constexpr bool isIntegral = false;
+ static constexpr bool isValueInitializationBitwiseZero = false;
+ static_assert(!isRelocatable ||
+ std::is_copy_constructible_v<T> ||
+ std::is_move_constructible_v<T>,
+ "All Ts... are Q_RELOCATABLE_TYPE, but T is neither copy- nor move-constructible, "
+ "so cannot be Q_RELOCATABLE_TYPE. Please mark T as Q_COMPLEX_TYPE manually.");
};
+// QTypeInfo for std::pair:
+// std::pair is spec'ed to be struct { T1 first; T2 second; }, so, unlike tuple<>,
+// we _can_ specialize QTypeInfo for pair<>:
+template <class T1, class T2>
+class QTypeInfo<std::pair<T1, T2>> : public QTypeInfoMerger<std::pair<T1, T2>, T1, T2> {};
+
#define Q_DECLARE_MOVABLE_CONTAINER(CONTAINER) \
template <typename ...T> \
class QTypeInfo<CONTAINER<T...>> \
{ \
public: \
enum { \
- isPointer = false, \
- isIntegral = false, \
+ isPointer [[deprecated("Use std::is_pointer instead")]] = false, \
+ isIntegral [[deprecated("Use std::is_integral instead")]] = false, \
isComplex = true, \
isRelocatable = true, \
+ isValueInitializationBitwiseZero = false, \
}; \
}
@@ -164,10 +166,15 @@ class QTypeInfo<TYPE > \
public: \
enum { \
isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0) && !std::is_trivial_v<TYPE>, \
- isRelocatable = !isComplex || ((FLAGS) & Q_RELOCATABLE_TYPE) || qIsRelocatable<TYPE>, \
- isPointer = false, \
- isIntegral = std::is_integral< TYPE >::value, \
+ isRelocatable = !isComplex || ((FLAGS) & Q_RELOCATABLE_TYPE) || QtPrivate::qIsRelocatable<TYPE>, \
+ isPointer [[deprecated("Use std::is_pointer instead")]] = std::is_pointer_v< TYPE >, \
+ isIntegral [[deprecated("Use std::is_integral instead")]] = std::is_integral< TYPE >::value, \
+ isValueInitializationBitwiseZero = QtPrivate::qIsValueInitializationBitwiseZero<TYPE>, \
}; \
+ static_assert(!isRelocatable || \
+ std::is_copy_constructible_v<TYPE > || \
+ std::is_move_constructible_v<TYPE >, \
+ #TYPE " is neither copy- nor move-constructible, so cannot be Q_RELOCATABLE_TYPE"); \
}
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS) \
@@ -179,23 +186,6 @@ template<typename T> class QFlags;
template<typename T>
Q_DECLARE_TYPEINFO_BODY(QFlags<T>, Q_PRIMITIVE_TYPE);
-/*
- Specialize a shared type with:
-
- Q_DECLARE_SHARED(type)
-
- where 'type' is the name of the type to specialize. NOTE: shared
- types must define a member-swap, and be defined in the same
- namespace as Qt for this to work.
-*/
-
-#define Q_DECLARE_SHARED_IMPL(TYPE, FLAGS) \
-Q_DECLARE_TYPEINFO(TYPE, FLAGS); \
-inline void swap(TYPE &value1, TYPE &value2) \
- noexcept(noexcept(value1.swap(value2))) \
-{ value1.swap(value2); }
-#define Q_DECLARE_SHARED(TYPE) Q_DECLARE_SHARED_IMPL(TYPE, Q_RELOCATABLE_TYPE)
-
namespace QTypeTraits
{
@@ -264,7 +254,7 @@ using expand_operator_equal_recursive = std::conjunction<expand_operator_equal<T
template<typename T>
struct expand_operator_equal_tuple : has_operator_equal<T> {};
template<typename T>
-struct expand_operator_equal_tuple<std::optional<T>> : has_operator_equal<T> {};
+struct expand_operator_equal_tuple<std::optional<T>> : expand_operator_equal_recursive<T> {};
template<typename T1, typename T2>
struct expand_operator_equal_tuple<std::pair<T1, T2>> : expand_operator_equal_recursive<T1, T2> {};
template<typename ...T>
@@ -304,7 +294,7 @@ using expand_operator_less_than_recursive = std::conjunction<expand_operator_les
template<typename T>
struct expand_operator_less_than_tuple : has_operator_less_than<T> {};
template<typename T>
-struct expand_operator_less_than_tuple<std::optional<T>> : has_operator_less_than<T> {};
+struct expand_operator_less_than_tuple<std::optional<T>> : expand_operator_less_than_recursive<T> {};
template<typename T1, typename T2>
struct expand_operator_less_than_tuple<std::pair<T1, T2>> : expand_operator_less_than_recursive<T1, T2> {};
template<typename ...T>