/****************************************************************************
**
** 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$
**
****************************************************************************/

#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 <QtCore/qglobal.h>
#include <QtCore/qvariant.h>
#include <QtCore/private/qmetatype_p.h>
#include <QtCore/qdebug.h>

#include "qmetatypeswitcher_p.h"

QT_BEGIN_NAMESPACE

template<typename T>
struct QVariantIntegrator
{
    static const bool CanUseInternalSpace = sizeof(T) <= sizeof(QVariant::Private::Data)
            && ((QTypeInfoQuery<T>::isRelocatable) || std::is_enum<T>::value);
    typedef std::integral_constant<bool, CanUseInternalSpace> CanUseInternalSpace_t;
};
Q_STATIC_ASSERT(QVariantIntegrator<double>::CanUseInternalSpace);
Q_STATIC_ASSERT(QVariantIntegrator<long int>::CanUseInternalSpace);
Q_STATIC_ASSERT(QVariantIntegrator<qulonglong>::CanUseInternalSpace);

#ifdef Q_CC_SUN // Sun CC picks the wrong overload, so introduce awful hack

// takes a type, returns the internal void* pointer cast
// to a pointer of the input type
template <typename T>
inline T *v_cast(const QVariant::Private *nd, T * = 0)
{
    QVariant::Private *d = const_cast<QVariant::Private *>(nd);
    return !QVariantIntegrator<T>::CanUseInternalSpace
            ? static_cast<T *>(d->data.shared->ptr)
            : static_cast<T *>(static_cast<void *>(&d->data.c));
}

#else // every other compiler in this world

template <typename T>
inline const T *v_cast(const QVariant::Private *d, T * = nullptr)
{
    return !QVariantIntegrator<T>::CanUseInternalSpace
            ? static_cast<const T *>(d->data.shared->ptr)
            : static_cast<const T *>(static_cast<const void *>(&d->data.c));
}

template <typename T>
inline T *v_cast(QVariant::Private *d, T * = nullptr)
{
    return !QVariantIntegrator<T>::CanUseInternalSpace
            ? static_cast<T *>(d->data.shared->ptr)
            : static_cast<T *>(static_cast<void *>(&d->data.c));
}

#endif

enum QVariantConstructionFlags : uint {
    Default = 0x0,
    PointerType = 0x1,
    ShouldDeleteVariantData = 0x2 // only used in Q*Iterable
};

//a simple template that avoids to allocate 2 memory chunks when creating a QVariant
template <class T> class QVariantPrivateSharedEx : public QVariant::PrivateShared
{
public:
    QVariantPrivateSharedEx() : QVariant::PrivateShared(&m_t), m_t() { }
    QVariantPrivateSharedEx(const T&t) : QVariant::PrivateShared(&m_t), m_t(t) { }

private:
    T m_t;
};

template <class T>
inline void v_construct_helper(QVariant::Private *x, const T &t, std::true_type)
{
    new (&x->data) T(t);
    x->is_shared = false;
}

template <class T>
inline void v_construct_helper(QVariant::Private *x, const T &t, std::false_type)
{
    x->data.shared = new QVariantPrivateSharedEx<T>(t);
    x->is_shared = true;
}

template <class T>
inline void v_construct_helper(QVariant::Private *x, std::true_type)
{
    new (&x->data) T();
    x->is_shared = false;
}

template <class T>
inline void v_construct_helper(QVariant::Private *x, std::false_type)
{
    x->data.shared = new QVariantPrivateSharedEx<T>;
    x->is_shared = true;
}

template <class T>
inline void v_construct(QVariant::Private *x, const T &t)
{
    // dispatch
    v_construct_helper(x, t, typename QVariantIntegrator<T>::CanUseInternalSpace_t());
}

// constructs a new variant if copy is 0, otherwise copy-constructs
template <class T>
inline void v_construct(QVariant::Private *x, const void *copy, T * = nullptr)
{
    if (copy)
        v_construct<T>(x, *static_cast<const T *>(copy));
    else
        v_construct_helper<T>(x, typename QVariantIntegrator<T>::CanUseInternalSpace_t());
}

// deletes the internal structures
template <class T>
inline void v_clear(QVariant::Private *d, T* = nullptr)
{

    if (!QVariantIntegrator<T>::CanUseInternalSpace) {
        //now we need to cast
        //because QVariant::PrivateShared doesn't have a virtual destructor
        delete static_cast<QVariantPrivateSharedEx<T>*>(d->data.shared);
    } else {
        v_cast<T>(d)->~T();
    }

}

template <typename T>
struct PrimitiveIsNull
{
public:
    static bool isNull(const QVariant::Private *d)
    {
        return d->is_null;
    }
};

template <typename T>
struct PrimitiveIsNull<T*>
{
public:
    static bool isNull(const QVariant::Private *d)
    {
        return d->is_null || d->data.ptr == nullptr;
    }
};

template <>
struct PrimitiveIsNull<std::nullptr_t>
{
public:
    static bool isNull(const QVariant::Private *)
    {
        return true;
    }
};

template<class Filter>
class QVariantComparator {
    template<typename T, bool IsAcceptedType = Filter::template Acceptor<T>::IsAccepted>
    struct FilteredComparator {
        static bool compare(const QVariant::Private *a, const QVariant::Private *b)
        {
            return *v_cast<T>(a) == *v_cast<T>(b);
        }
    };
    template<typename T>
    struct FilteredComparator<T, /* IsAcceptedType = */ false> {
        static bool compare(const QVariant::Private *, const QVariant::Private *)
        {
            // It is not possible to construct a QVariant containing not fully defined type
            Q_ASSERT(false);
            return false;
        }
    };
public:
    QVariantComparator(const QVariant::Private *a, const QVariant::Private *b)
        : m_a(a), m_b(b)
    {
        Q_ASSERT(a->type == b->type);
    }

    template<typename T>
    bool delegate(const T*)
    {
        return FilteredComparator<T>::compare(m_a, m_b);
    }

    bool delegate(const void*) { Q_ASSERT(false); return true; }
    bool delegate(const QMetaTypeSwitcher::UnknownType*)
    {
        return true; // for historical reason invalid variant == invalid variant
    }
    bool delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return false; }
protected:
    const QVariant::Private *m_a;
    const QVariant::Private *m_b;
};


Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler();

template<class Filter>
class QVariantIsNull
{
    /// \internal
    /// This class checks if a type T has method called isNull. Result is kept in the Value property
    /// TODO Can we somehow generalize it? A macro version?
    template<typename T>
    class HasIsNullMethod {
        struct Yes { char unused[1]; };
        struct No { char unused[2]; };
        Q_STATIC_ASSERT(sizeof(Yes) != sizeof(No));

        template<class C> static decltype(static_cast<const C*>(nullptr)->isNull(), Yes()) test(int);
        template<class C> static No test(...);
    public:
        static const bool Value = (sizeof(test<T>(0)) == sizeof(Yes));
    };

    // TODO This part should go to autotests during HasIsNullMethod generalization.
    Q_STATIC_ASSERT(!HasIsNullMethod<bool>::Value);
    struct SelfTest1 { bool isNull() const; };
    Q_STATIC_ASSERT(HasIsNullMethod<SelfTest1>::Value);
    struct SelfTest2 {};
    Q_STATIC_ASSERT(!HasIsNullMethod<SelfTest2>::Value);
    struct SelfTest3 : public SelfTest1 {};
    Q_STATIC_ASSERT(HasIsNullMethod<SelfTest3>::Value);
    struct SelfTestFinal1 final { bool isNull() const; };
    Q_STATIC_ASSERT(HasIsNullMethod<SelfTestFinal1>::Value);
    struct SelfTestFinal2 final {};
    Q_STATIC_ASSERT(!HasIsNullMethod<SelfTestFinal2>::Value);
    struct SelfTestFinal3 final : public SelfTest1 {};
    Q_STATIC_ASSERT(HasIsNullMethod<SelfTestFinal3>::Value);

    template<typename T, bool HasIsNull = HasIsNullMethod<T>::Value>
    struct CallFilteredIsNull
    {
        static bool isNull(const QVariant::Private *d)
        {
            return v_cast<T>(d)->isNull();
        }
    };
    template<typename T>
    struct CallFilteredIsNull<T, /* HasIsNull = */ false>
    {
        static bool isNull(const QVariant::Private *d)
        {
            return PrimitiveIsNull<T>::isNull(d);
        }
    };

    template<typename T, bool IsAcceptedType = Filter::template Acceptor<T>::IsAccepted>
    struct CallIsNull
    {
        static bool isNull(const QVariant::Private *d)
        {
            return CallFilteredIsNull<T>::isNull(d);
        }
    };
    template<typename T>
    struct CallIsNull<T, /* IsAcceptedType = */ false>
    {
        static bool isNull(const QVariant::Private *d)
        {
            return CallFilteredIsNull<T, false>::isNull(d);
        }
    };

public:
    QVariantIsNull(const QVariant::Private *d)
        : m_d(d)
    {}
    template<typename T>
    bool delegate(const T*)
    {
        return CallIsNull<T>::isNull(m_d);
    }
    // we need that as sizof(void) is undefined and it is needed in HasIsNullMethod
    bool delegate(const void *) { Q_ASSERT(false); return m_d->is_null; }
    bool delegate(const QMetaTypeSwitcher::UnknownType *) { return m_d->is_null; }
    bool delegate(const QMetaTypeSwitcher::NotBuiltinType *)
    {
        // QVariantIsNull is used only for built-in types
        Q_ASSERT(false);
        return m_d->is_null;
    }
protected:
    const QVariant::Private *m_d;
};

template<class Filter>
class QVariantConstructor
{
    template<typename T, bool IsAcceptedType = Filter::template Acceptor<T>::IsAccepted>
    struct FilteredConstructor {
        FilteredConstructor(const QVariantConstructor &tc)
        {
            v_construct<T>(tc.m_x, tc.m_copy);
            tc.m_x->is_null = !tc.m_copy;
        }
    };
    template<typename T>
    struct FilteredConstructor<T, /* IsAcceptedType = */ false> {
        FilteredConstructor(const QVariantConstructor &tc)
        {
            // ignore types that lives outside of the current library
            tc.m_x->type = QVariant::Invalid;
        }
    };
public:
    QVariantConstructor(QVariant::Private *x, const void *copy)
        : m_x(x)
        , m_copy(copy)
    {}

    template<typename T>
    void delegate(const T*)
    {
        FilteredConstructor<T>(*this);
    }

    void delegate(const QMetaTypeSwitcher::NotBuiltinType*)
    {
        // QVariantConstructor is used only for built-in types.
        Q_ASSERT(false);
    }

    void delegate(const void*)
    {
        qWarning("Trying to create a QVariant instance of QMetaType::Void type, an invalid QVariant will be constructed instead");
        m_x->type = QMetaType::UnknownType;
        m_x->is_shared = false;
        m_x->is_null = !m_copy;
    }

    void delegate(const QMetaTypeSwitcher::UnknownType*)
    {
        if (m_x->type != QMetaType::UnknownType) {
            qWarning("Trying to construct an instance of an invalid type, type id: %i", m_x->type);
            m_x->type = QMetaType::UnknownType;
        }
        m_x->is_shared = false;
        m_x->is_null = !m_copy;
    }
private:
    QVariant::Private *m_x;
    const void *m_copy;
};

template<class Filter>
class QVariantDestructor
{
    template<typename T, bool IsAcceptedType = Filter::template Acceptor<T>::IsAccepted>
    struct FilteredDestructor {
        FilteredDestructor(QVariant::Private *d)
        {
            v_clear<T>(d);
        }
    };
    template<typename T>
    struct FilteredDestructor<T, /* IsAcceptedType = */ false> {
        FilteredDestructor(QVariant::Private *)
        {
            // It is not possible to create not accepted type
            Q_ASSERT(false);
        }
    };

public:
    QVariantDestructor(QVariant::Private *d)
        : m_d(d)
    {}
    ~QVariantDestructor()
    {
        m_d->type = QVariant::Invalid;
        m_d->is_null = true;
        m_d->is_shared = false;
    }

    template<typename T>
    void delegate(const T*)
    {
        FilteredDestructor<T> cleaner(m_d);
    }

    void delegate(const QMetaTypeSwitcher::NotBuiltinType*)
    {
        // QVariantDestructor class is used only for a built-in type
        Q_ASSERT(false);
    }
    // Ignore nonconstructible type
    void delegate(const QMetaTypeSwitcher::UnknownType*) {}
    void delegate(const void*) { Q_ASSERT(false); }
private:
    QVariant::Private *m_d;
};

namespace QVariantPrivate {
Q_CORE_EXPORT void registerHandler(const int /* Modules::Names */ name, const QVariant::Handler *handler);
}

#if !defined(QT_NO_DEBUG_STREAM)
template<class Filter>
class QVariantDebugStream
{
    template<typename T, bool IsAcceptedType = Filter::template Acceptor<T>::IsAccepted>
    struct Filtered {
        Filtered(QDebug dbg, QVariant::Private *d)
        {
            dbg.nospace() << *v_cast<T>(d);
        }
    };
    template<typename T>
    struct Filtered<T, /* IsAcceptedType = */ false> {
        Filtered(QDebug /* dbg */, QVariant::Private *)
        {
            // It is not possible to construct not acccepted type, QVariantConstructor creates an invalid variant for them
            Q_ASSERT(false);
        }
    };

public:
    QVariantDebugStream(QDebug dbg, QVariant::Private *d)
        : m_debugStream(dbg)
        , m_d(d)
    {}

    template<typename T>
    void delegate(const T*)
    {
        Filtered<T> streamIt(m_debugStream, m_d);
        Q_UNUSED(streamIt);
    }

    void delegate(const QMetaTypeSwitcher::NotBuiltinType*)
    {
        // QVariantDebugStream class is used only for a built-in type
        Q_ASSERT(false);
    }
    void delegate(const QMetaTypeSwitcher::UnknownType*)
    {
        m_debugStream.nospace() << "QVariant::Invalid";
    }
    void delegate(const void*) { Q_ASSERT(false); }
private:
    QDebug m_debugStream;
    QVariant::Private *m_d;
};
#endif

QT_END_NAMESPACE

#endif // QVARIANT_P_H
