mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-30 20:15:35 +08:00
136 lines
4.8 KiB
C++
136 lines
4.8 KiB
C++
/* Copyright (C) 2019
|
|
* swift Project Community / Contributors
|
|
*
|
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
|
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
|
|
* or distributed except according to the terms contained in the LICENSE file.
|
|
*/
|
|
|
|
//! \file
|
|
|
|
#ifndef BLACKMISC_DATASTREAM_H
|
|
#define BLACKMISC_DATASTREAM_H
|
|
|
|
#include "blackmisc/typetraits.h"
|
|
#include <QDataStream>
|
|
|
|
namespace BlackMisc
|
|
{
|
|
class CEmpty;
|
|
|
|
namespace Mixin
|
|
{
|
|
/*!
|
|
* CRTP class template to generate non-member QDataStream streaming operators.
|
|
*
|
|
* \tparam Derived Must implement public methods marshalToDataStream(QDataStream &) and unmarshalFromDataStream(QDataStream &).
|
|
*/
|
|
template <class Derived>
|
|
class DataStreamOperators
|
|
{
|
|
public:
|
|
//! Marshal a value to a QDataStream.
|
|
friend QDataStream &operator <<(QDataStream &stream, const Derived &value)
|
|
{
|
|
value.marshalToDataStream(stream);
|
|
return stream;
|
|
}
|
|
|
|
//! Unmarshal a value from a QDataStream.
|
|
friend QDataStream &operator >>(QDataStream &stream, Derived &value)
|
|
{
|
|
value.unmarshalFromDataStream(stream);
|
|
return stream;
|
|
}
|
|
};
|
|
|
|
/*!
|
|
* CRTP class template to generate QDataStream marshalling methods using CMetaClass.
|
|
*
|
|
* \see BLACKMISC_DECLARE_USING_MIXIN_DATASTREAM
|
|
*/
|
|
template <class Derived>
|
|
class DataStreamByMetaClass : public DataStreamOperators<Derived>
|
|
{
|
|
public:
|
|
//! Marshal a value to a QDataStream.
|
|
void marshalToDataStream(QDataStream &stream) const
|
|
{
|
|
baseMarshal(static_cast<const TBaseOfT<Derived> *>(derived()), stream);
|
|
constexpr auto meta = introspect<Derived>().without(MetaFlags<DisabledForMarshalling>());
|
|
meta.forEachMember([ &, this ](auto member) { stream << member.in(*this->derived()); });
|
|
}
|
|
|
|
//! Unmarshal a value from a QDataStream.
|
|
void unmarshalFromDataStream(QDataStream &stream)
|
|
{
|
|
baseUnmarshal(static_cast<TBaseOfT<Derived> *>(derived()), stream);
|
|
constexpr auto meta = introspect<Derived>().without(MetaFlags<DisabledForMarshalling>());
|
|
meta.forEachMember([ &, this ](auto member) { stream >> member.in(*this->derived()); });
|
|
}
|
|
|
|
private:
|
|
const Derived *derived() const { return static_cast<const Derived *>(this); }
|
|
Derived *derived() { return static_cast<Derived *>(this); }
|
|
|
|
template <typename T> static void baseMarshal(const T *base, QDataStream &stream) { base->marshalToDataStream(stream); }
|
|
template <typename T> static void baseUnmarshal(T *base, QDataStream &stream) { base->unmarshalFromDataStream(stream); }
|
|
static void baseMarshal(const void *, QDataStream &) {}
|
|
static void baseUnmarshal(void *, QDataStream &) {}
|
|
static void baseMarshal(const CEmpty *, QDataStream &) {}
|
|
static void baseUnmarshal(CEmpty *, QDataStream &) {}
|
|
};
|
|
|
|
/*!
|
|
* When a derived class and a base class both inherit from Mixin::DataStreamByMetaClass,
|
|
* the derived class uses this macro to disambiguate the inherited members.
|
|
*/
|
|
# define BLACKMISC_DECLARE_USING_MIXIN_DATASTREAM(DERIVED) \
|
|
using ::BlackMisc::Mixin::DataStreamByMetaClass<DERIVED>::marshalToDataStream; \
|
|
using ::BlackMisc::Mixin::DataStreamByMetaClass<DERIVED>::unmarshalFromDataStream;
|
|
}
|
|
}
|
|
|
|
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
|
/*!
|
|
* Operator for marshalling enums with QDataStream.
|
|
*/
|
|
template <typename E, typename = std::enable_if_t<std::is_enum<E>::value>>
|
|
QDataStream &operator <<(QDataStream &stream, E value)
|
|
{
|
|
return stream << static_cast<int>(value);
|
|
}
|
|
|
|
/*!
|
|
* Operator for unmarshalling enums with QDataStream.
|
|
*/
|
|
template <typename E, typename = std::enable_if_t<std::is_enum<E>::value>>
|
|
QDataStream &operator >>(QDataStream &stream, E &value)
|
|
{
|
|
int temp;
|
|
stream >> temp;
|
|
value = static_cast<E>(temp);
|
|
return stream;
|
|
}
|
|
#endif // Qt < 5.14.0
|
|
|
|
/*!
|
|
* Operator for marshalling pairs with QDataStream.
|
|
*/
|
|
template <typename T, typename U>
|
|
QDataStream &operator <<(QDataStream &stream, const std::pair<T, U> &pair)
|
|
{
|
|
return stream << pair.first << pair.second;
|
|
}
|
|
|
|
/*!
|
|
* Operator for unmarshalling pairs with QDataStream.
|
|
*/
|
|
template <typename T, typename U>
|
|
QDataStream &operator >>(QDataStream &stream, std::pair<T, U> &pair)
|
|
{
|
|
return stream >> pair.first >> pair.second;
|
|
}
|
|
|
|
#endif
|