123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 | // 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#ifndef QVARIANT_P_H#define QVARIANT_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"qvariant.h" QT_BEGIN_NAMESPACE inline autocustomConstructSharedImpl(size_t size,size_t align){struct Deleter {voidoperator()(QVariant::PrivateShared *p)const{QVariant::PrivateShared::free(p); }};// this is exception-safestd::unique_ptr<QVariant::PrivateShared, Deleter> ptr; ptr.reset(QVariant::PrivateShared::create(size, align));return ptr;}template<typename F>staticQVariant::PrivateShared *customConstructShared(size_t size,size_t align, F &&construct){auto ptr =customConstructSharedImpl(size, align);construct(ptr->data());return ptr.release();}inlineintQVariant::PrivateShared::computeOffset(PrivateShared *ps,size_t align){returnint(((quintptr(ps) +sizeof(PrivateShared) + align -1) & ~(align -1)) -quintptr(ps));}inlinesize_tQVariant::PrivateShared::computeAllocationSize(size_t size,size_t align){ size +=sizeof(PrivateShared);if(align >sizeof(PrivateShared)) {// The alignment is larger than the alignment we can guarantee for the pointer// directly following PrivateShared, so we need to allocate some additional// memory to be able to fit the object into the available memory with suitable// alignment. size += align -sizeof(PrivateShared);}return size;}inline QVariant::PrivateShared *QVariant::PrivateShared::create(size_t size,size_t align){ size =computeAllocationSize(size, align);void*data =operatornew(size);auto*ps =new(data)QVariant::PrivateShared(); ps->offset =computeOffset(ps, align);return ps;}inlinevoidQVariant::PrivateShared::free(PrivateShared *p){ p->~PrivateShared();operatordelete(p);}inline QVariant::Private::Private(constQtPrivate::QMetaTypeInterface *iface) noexcept :is_shared(false),is_null(false),packedType(quintptr(iface) >>2){Q_ASSERT((quintptr(iface) &0x3) ==0);}template<typename T>inlineQVariant::Private::Private(std::piecewise_construct_t,const T &t):is_shared(!CanUseInternalSpace<T>),is_null(std::is_same_v<T,std::nullptr_t>){// confirm noexceptnessstaticconstexprbool isNothrowQVariantConstructible =noexcept(QVariant(t));staticconstexprbool isNothrowCopyConstructible =std::is_nothrow_copy_constructible_v<T>;staticconstexprbool isNothrowCopyAssignable =std::is_nothrow_copy_assignable_v<T>;constQtPrivate::QMetaTypeInterface *iface =QtPrivate::qMetaTypeInterfaceForType<T>();Q_ASSERT((quintptr(iface) &0x3) ==0); packedType =quintptr(iface) >>2;ifconstexpr(CanUseInternalSpace<T>) {static_assert(isNothrowQVariantConstructible == isNothrowCopyConstructible);static_assert(isNothrowQVariantConstructible == isNothrowCopyAssignable);new(data.data)T(t);}else{static_assert(!isNothrowQVariantConstructible);// we allocate memory, even if T doesn't data.shared =customConstructShared(sizeof(T),alignof(T), [=](void*where) {new(where)T(t);});}} QT_END_NAMESPACE #endif// QVARIANT_P_H
|