File indexing completed on 2025-01-18 10:07:21
0001
0002
0003
0004 #ifndef QDATASTREAM_H
0005 #define QDATASTREAM_H
0006
0007 #include <QtCore/qscopedpointer.h>
0008 #include <QtCore/qiodevicebase.h>
0009 #include <QtCore/qcontainerfwd.h>
0010 #include <QtCore/qnamespace.h>
0011
0012 #include <iterator> // std::distance(), std::next()
0013
0014 #ifdef Status
0015 #error qdatastream.h must be included before any header file that defines Status
0016 #endif
0017
0018 QT_BEGIN_NAMESPACE
0019
0020 #if QT_CORE_REMOVED_SINCE(6, 3)
0021 class qfloat16;
0022 #endif
0023 class QByteArray;
0024 class QDataStream;
0025 class QIODevice;
0026 class QString;
0027
0028 #if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
0029 class QDataStreamPrivate;
0030 namespace QtPrivate {
0031 class StreamStateSaver;
0032 template <typename Container>
0033 QDataStream &readArrayBasedContainer(QDataStream &s, Container &c);
0034 template <typename Container>
0035 QDataStream &readListBasedContainer(QDataStream &s, Container &c);
0036 template <typename Container>
0037 QDataStream &readAssociativeContainer(QDataStream &s, Container &c);
0038 template <typename Container>
0039 QDataStream &writeSequentialContainer(QDataStream &s, const Container &c);
0040 template <typename Container>
0041 QDataStream &writeAssociativeContainer(QDataStream &s, const Container &c);
0042 template <typename Container>
0043 QDataStream &writeAssociativeMultiContainer(QDataStream &s, const Container &c);
0044 }
0045 class Q_CORE_EXPORT QDataStream : public QIODeviceBase
0046 {
0047 public:
0048 enum Version {
0049 Qt_1_0 = 1,
0050 Qt_2_0 = 2,
0051 Qt_2_1 = 3,
0052 Qt_3_0 = 4,
0053 Qt_3_1 = 5,
0054 Qt_3_3 = 6,
0055 Qt_4_0 = 7,
0056 Qt_4_1 = Qt_4_0,
0057 Qt_4_2 = 8,
0058 Qt_4_3 = 9,
0059 Qt_4_4 = 10,
0060 Qt_4_5 = 11,
0061 Qt_4_6 = 12,
0062 Qt_4_7 = Qt_4_6,
0063 Qt_4_8 = Qt_4_7,
0064 Qt_4_9 = Qt_4_8,
0065 Qt_5_0 = 13,
0066 Qt_5_1 = 14,
0067 Qt_5_2 = 15,
0068 Qt_5_3 = Qt_5_2,
0069 Qt_5_4 = 16,
0070 Qt_5_5 = Qt_5_4,
0071 Qt_5_6 = 17,
0072 Qt_5_7 = Qt_5_6,
0073 Qt_5_8 = Qt_5_7,
0074 Qt_5_9 = Qt_5_8,
0075 Qt_5_10 = Qt_5_9,
0076 Qt_5_11 = Qt_5_10,
0077 Qt_5_12 = 18,
0078 Qt_5_13 = 19,
0079 Qt_5_14 = Qt_5_13,
0080 Qt_5_15 = Qt_5_14,
0081 Qt_6_0 = 20,
0082 Qt_6_1 = Qt_6_0,
0083 Qt_6_2 = Qt_6_0,
0084 Qt_6_3 = Qt_6_0,
0085 Qt_6_4 = Qt_6_0,
0086 Qt_6_5 = Qt_6_0,
0087 Qt_6_6 = 21,
0088 Qt_6_7 = 22,
0089 Qt_DefaultCompiledVersion = Qt_6_7
0090 #if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
0091 #error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
0092 #endif
0093 };
0094
0095 enum ByteOrder {
0096 BigEndian = QSysInfo::BigEndian,
0097 LittleEndian = QSysInfo::LittleEndian
0098 };
0099
0100 enum Status {
0101 Ok,
0102 ReadPastEnd,
0103 ReadCorruptData,
0104 WriteFailed,
0105 SizeLimitExceeded,
0106 };
0107
0108 enum FloatingPointPrecision {
0109 SinglePrecision,
0110 DoublePrecision
0111 };
0112
0113 QDataStream();
0114 explicit QDataStream(QIODevice *);
0115 QDataStream(QByteArray *, OpenMode flags);
0116 QDataStream(const QByteArray &);
0117 ~QDataStream();
0118
0119 QIODevice *device() const;
0120 void setDevice(QIODevice *);
0121
0122 bool atEnd() const;
0123
0124 Status status() const;
0125 void setStatus(Status status);
0126 void resetStatus();
0127
0128 FloatingPointPrecision floatingPointPrecision() const;
0129 void setFloatingPointPrecision(FloatingPointPrecision precision);
0130
0131 ByteOrder byteOrder() const;
0132 void setByteOrder(ByteOrder);
0133
0134 int version() const;
0135 void setVersion(int);
0136
0137 QDataStream &operator>>(char &i);
0138 QDataStream &operator>>(qint8 &i);
0139 QDataStream &operator>>(quint8 &i);
0140 QDataStream &operator>>(qint16 &i);
0141 QDataStream &operator>>(quint16 &i);
0142 QDataStream &operator>>(qint32 &i);
0143 inline QDataStream &operator>>(quint32 &i);
0144 QDataStream &operator>>(qint64 &i);
0145 QDataStream &operator>>(quint64 &i);
0146 QDataStream &operator>>(std::nullptr_t &ptr) { ptr = nullptr; return *this; }
0147
0148 QDataStream &operator>>(bool &i);
0149 #if QT_CORE_REMOVED_SINCE(6, 3)
0150 QDataStream &operator>>(qfloat16 &f);
0151 #endif
0152 QDataStream &operator>>(float &f);
0153 QDataStream &operator>>(double &f);
0154 QDataStream &operator>>(char *&str);
0155 QDataStream &operator>>(char16_t &c);
0156 QDataStream &operator>>(char32_t &c);
0157
0158 QDataStream &operator<<(char i);
0159 QDataStream &operator<<(qint8 i);
0160 QDataStream &operator<<(quint8 i);
0161 QDataStream &operator<<(qint16 i);
0162 QDataStream &operator<<(quint16 i);
0163 QDataStream &operator<<(qint32 i);
0164 inline QDataStream &operator<<(quint32 i);
0165 QDataStream &operator<<(qint64 i);
0166 QDataStream &operator<<(quint64 i);
0167 QDataStream &operator<<(std::nullptr_t) { return *this; }
0168 QDataStream &operator<<(bool i);
0169 #if QT_CORE_REMOVED_SINCE(6, 3)
0170 QDataStream &operator<<(qfloat16 f);
0171 #endif
0172 QDataStream &operator<<(float f);
0173 QDataStream &operator<<(double f);
0174 QDataStream &operator<<(const char *str);
0175 QDataStream &operator<<(char16_t c);
0176 QDataStream &operator<<(char32_t c);
0177 QDataStream &operator<<(const volatile void *) = delete;
0178
0179 #if QT_DEPRECATED_SINCE(6, 11)
0180 QT_DEPRECATED_VERSION_X_6_11("Use an overload that takes qint64 length.")
0181 QDataStream &readBytes(char *&, uint &len);
0182 #endif
0183 #if QT_CORE_REMOVED_SINCE(6, 7)
0184 QDataStream &writeBytes(const char *, uint len);
0185 int skipRawData(int len);
0186 int readRawData(char *, int len);
0187 int writeRawData(const char *, int len);
0188 #endif
0189 QDataStream &readBytes(char *&, qint64 &len);
0190 qint64 readRawData(char *, qint64 len);
0191 QDataStream &writeBytes(const char *, qint64 len);
0192 qint64 writeRawData(const char *, qint64 len);
0193 qint64 skipRawData(qint64 len);
0194
0195 void startTransaction();
0196 bool commitTransaction();
0197 void rollbackTransaction();
0198 void abortTransaction();
0199
0200 bool isDeviceTransactionStarted() const;
0201 private:
0202 Q_DISABLE_COPY(QDataStream)
0203
0204 QScopedPointer<QDataStreamPrivate> d;
0205
0206 QIODevice *dev;
0207 bool owndev;
0208 bool noswap;
0209 ByteOrder byteorder;
0210 int ver;
0211 Status q_status;
0212 #if QT_CORE_REMOVED_SINCE(6, 7)
0213 int readBlock(char *data, int len);
0214 #endif
0215 qint64 readBlock(char *data, qint64 len);
0216 static inline qint64 readQSizeType(QDataStream &s);
0217 static inline bool writeQSizeType(QDataStream &s, qint64 value);
0218 static constexpr quint32 NullCode = 0xffffffffu;
0219 static constexpr quint32 ExtendedSize = 0xfffffffeu;
0220
0221 friend class QtPrivate::StreamStateSaver;
0222 Q_CORE_EXPORT friend QDataStream &operator<<(QDataStream &out, const QString &str);
0223 Q_CORE_EXPORT friend QDataStream &operator>>(QDataStream &in, QString &str);
0224 Q_CORE_EXPORT friend QDataStream &operator<<(QDataStream &out, const QByteArray &ba);
0225 Q_CORE_EXPORT friend QDataStream &operator>>(QDataStream &in, QByteArray &ba);
0226 template <typename Container>
0227 friend QDataStream &QtPrivate::readArrayBasedContainer(QDataStream &s, Container &c);
0228 template <typename Container>
0229 friend QDataStream &QtPrivate::readListBasedContainer(QDataStream &s, Container &c);
0230 template <typename Container>
0231 friend QDataStream &QtPrivate::readAssociativeContainer(QDataStream &s, Container &c);
0232 template <typename Container>
0233 friend QDataStream &QtPrivate::writeSequentialContainer(QDataStream &s, const Container &c);
0234 template <typename Container>
0235 friend QDataStream &QtPrivate::writeAssociativeContainer(QDataStream &s, const Container &c);
0236 template <typename Container>
0237 friend QDataStream &QtPrivate::writeAssociativeMultiContainer(QDataStream &s,
0238 const Container &c);
0239 };
0240
0241 namespace QtPrivate {
0242
0243 class StreamStateSaver
0244 {
0245 Q_DISABLE_COPY_MOVE(StreamStateSaver)
0246 public:
0247 inline StreamStateSaver(QDataStream *s) : stream(s), oldStatus(s->status())
0248 {
0249 if (!stream->isDeviceTransactionStarted())
0250 stream->resetStatus();
0251 }
0252 inline ~StreamStateSaver()
0253 {
0254 if (oldStatus != QDataStream::Ok) {
0255 stream->resetStatus();
0256 stream->setStatus(oldStatus);
0257 }
0258 }
0259
0260 private:
0261 QDataStream *stream;
0262 QDataStream::Status oldStatus;
0263 };
0264
0265 template <typename Container>
0266 QDataStream &readArrayBasedContainer(QDataStream &s, Container &c)
0267 {
0268 StreamStateSaver stateSaver(&s);
0269
0270 c.clear();
0271 qint64 size = QDataStream::readQSizeType(s);
0272 qsizetype n = size;
0273 if (size != n || size < 0) {
0274 s.setStatus(QDataStream::SizeLimitExceeded);
0275 return s;
0276 }
0277 c.reserve(n);
0278 for (qsizetype i = 0; i < n; ++i) {
0279 typename Container::value_type t;
0280 s >> t;
0281 if (s.status() != QDataStream::Ok) {
0282 c.clear();
0283 break;
0284 }
0285 c.append(t);
0286 }
0287
0288 return s;
0289 }
0290
0291 template <typename Container>
0292 QDataStream &readListBasedContainer(QDataStream &s, Container &c)
0293 {
0294 StreamStateSaver stateSaver(&s);
0295
0296 c.clear();
0297 qint64 size = QDataStream::readQSizeType(s);
0298 qsizetype n = size;
0299 if (size != n || size < 0) {
0300 s.setStatus(QDataStream::SizeLimitExceeded);
0301 return s;
0302 }
0303 for (qsizetype i = 0; i < n; ++i) {
0304 typename Container::value_type t;
0305 s >> t;
0306 if (s.status() != QDataStream::Ok) {
0307 c.clear();
0308 break;
0309 }
0310 c << t;
0311 }
0312
0313 return s;
0314 }
0315
0316 template <typename Container>
0317 QDataStream &readAssociativeContainer(QDataStream &s, Container &c)
0318 {
0319 StreamStateSaver stateSaver(&s);
0320
0321 c.clear();
0322 qint64 size = QDataStream::readQSizeType(s);
0323 qsizetype n = size;
0324 if (size != n || size < 0) {
0325 s.setStatus(QDataStream::SizeLimitExceeded);
0326 return s;
0327 }
0328 for (qsizetype i = 0; i < n; ++i) {
0329 typename Container::key_type k;
0330 typename Container::mapped_type t;
0331 s >> k >> t;
0332 if (s.status() != QDataStream::Ok) {
0333 c.clear();
0334 break;
0335 }
0336 c.insert(k, t);
0337 }
0338
0339 return s;
0340 }
0341
0342 template <typename Container>
0343 QDataStream &writeSequentialContainer(QDataStream &s, const Container &c)
0344 {
0345 if (!QDataStream::writeQSizeType(s, c.size()))
0346 return s;
0347 for (const typename Container::value_type &t : c)
0348 s << t;
0349
0350 return s;
0351 }
0352
0353 template <typename Container>
0354 QDataStream &writeAssociativeContainer(QDataStream &s, const Container &c)
0355 {
0356 if (!QDataStream::writeQSizeType(s, c.size()))
0357 return s;
0358 auto it = c.constBegin();
0359 auto end = c.constEnd();
0360 while (it != end) {
0361 s << it.key() << it.value();
0362 ++it;
0363 }
0364
0365 return s;
0366 }
0367
0368 template <typename Container>
0369 QDataStream &writeAssociativeMultiContainer(QDataStream &s, const Container &c)
0370 {
0371 if (!QDataStream::writeQSizeType(s, c.size()))
0372 return s;
0373 auto it = c.constBegin();
0374 auto end = c.constEnd();
0375 while (it != end) {
0376 const auto rangeStart = it++;
0377 while (it != end && rangeStart.key() == it.key())
0378 ++it;
0379 const qint64 last = std::distance(rangeStart, it) - 1;
0380 for (qint64 i = last; i >= 0; --i) {
0381 auto next = std::next(rangeStart, i);
0382 s << next.key() << next.value();
0383 }
0384 }
0385
0386 return s;
0387 }
0388
0389 }
0390
0391 template<typename ...T>
0392 using QDataStreamIfHasOStreamOperators =
0393 std::enable_if_t<std::conjunction_v<QTypeTraits::has_ostream_operator<QDataStream, T>...>, QDataStream &>;
0394 template<typename Container, typename ...T>
0395 using QDataStreamIfHasOStreamOperatorsContainer =
0396 std::enable_if_t<std::conjunction_v<QTypeTraits::has_ostream_operator_container<QDataStream, Container, T>...>, QDataStream &>;
0397
0398 template<typename ...T>
0399 using QDataStreamIfHasIStreamOperators =
0400 std::enable_if_t<std::conjunction_v<QTypeTraits::has_istream_operator<QDataStream, T>...>, QDataStream &>;
0401 template<typename Container, typename ...T>
0402 using QDataStreamIfHasIStreamOperatorsContainer =
0403 std::enable_if_t<std::conjunction_v<QTypeTraits::has_istream_operator_container<QDataStream, Container, T>...>, QDataStream &>;
0404
0405
0406
0407
0408
0409 inline QIODevice *QDataStream::device() const
0410 { return dev; }
0411
0412 inline QDataStream::ByteOrder QDataStream::byteOrder() const
0413 { return byteorder; }
0414
0415 inline int QDataStream::version() const
0416 { return ver; }
0417
0418 inline void QDataStream::setVersion(int v)
0419 { ver = v; }
0420
0421 qint64 QDataStream::readQSizeType(QDataStream &s)
0422 {
0423 quint32 first;
0424 s >> first;
0425 if (first == NullCode)
0426 return -1;
0427 if (first < ExtendedSize || s.version() < QDataStream::Qt_6_7)
0428 return qint64(first);
0429 qint64 extendedLen;
0430 s >> extendedLen;
0431 return extendedLen;
0432 }
0433
0434 bool QDataStream::writeQSizeType(QDataStream &s, qint64 value)
0435 {
0436 if (value < qint64(ExtendedSize)) {
0437 s << quint32(value);
0438 } else if (s.version() >= QDataStream::Qt_6_7) {
0439 s << ExtendedSize << value;
0440 } else if (value == qint64(ExtendedSize)) {
0441 s << ExtendedSize;
0442 } else {
0443 s.setStatus(QDataStream::SizeLimitExceeded);
0444 return false;
0445 }
0446 return true;
0447 }
0448
0449 inline QDataStream &QDataStream::operator>>(char &i)
0450 { return *this >> reinterpret_cast<qint8&>(i); }
0451
0452 inline QDataStream &QDataStream::operator>>(quint8 &i)
0453 { return *this >> reinterpret_cast<qint8&>(i); }
0454
0455 inline QDataStream &QDataStream::operator>>(quint16 &i)
0456 { return *this >> reinterpret_cast<qint16&>(i); }
0457
0458 inline QDataStream &QDataStream::operator>>(quint32 &i)
0459 { return *this >> reinterpret_cast<qint32&>(i); }
0460
0461 inline QDataStream &QDataStream::operator>>(quint64 &i)
0462 { return *this >> reinterpret_cast<qint64&>(i); }
0463
0464 inline QDataStream &QDataStream::operator<<(char i)
0465 { return *this << qint8(i); }
0466
0467 inline QDataStream &QDataStream::operator<<(quint8 i)
0468 { return *this << qint8(i); }
0469
0470 inline QDataStream &QDataStream::operator<<(quint16 i)
0471 { return *this << qint16(i); }
0472
0473 inline QDataStream &QDataStream::operator<<(quint32 i)
0474 { return *this << qint32(i); }
0475
0476 inline QDataStream &QDataStream::operator<<(quint64 i)
0477 { return *this << qint64(i); }
0478
0479 template <typename Enum>
0480 inline QDataStream &operator<<(QDataStream &s, QFlags<Enum> e)
0481 { return s << typename QFlags<Enum>::Int(e); }
0482
0483 template <typename Enum>
0484 inline QDataStream &operator>>(QDataStream &s, QFlags<Enum> &e)
0485 {
0486 typename QFlags<Enum>::Int i;
0487 s >> i;
0488 e = QFlag(i);
0489 return s;
0490 }
0491
0492 template <typename T>
0493 typename std::enable_if_t<std::is_enum<T>::value, QDataStream &>
0494 operator<<(QDataStream &s, const T &t)
0495 { return s << static_cast<typename std::underlying_type<T>::type>(t); }
0496
0497 template <typename T>
0498 typename std::enable_if_t<std::is_enum<T>::value, QDataStream &>
0499 operator>>(QDataStream &s, T &t)
0500 { return s >> reinterpret_cast<typename std::underlying_type<T>::type &>(t); }
0501
0502 #ifndef Q_QDOC
0503
0504 template<typename T>
0505 inline QDataStreamIfHasIStreamOperatorsContainer<QList<T>, T> operator>>(QDataStream &s, QList<T> &v)
0506 {
0507 return QtPrivate::readArrayBasedContainer(s, v);
0508 }
0509
0510 template<typename T>
0511 inline QDataStreamIfHasOStreamOperatorsContainer<QList<T>, T> operator<<(QDataStream &s, const QList<T> &v)
0512 {
0513 return QtPrivate::writeSequentialContainer(s, v);
0514 }
0515
0516 template <typename T>
0517 inline QDataStreamIfHasIStreamOperatorsContainer<QSet<T>, T> operator>>(QDataStream &s, QSet<T> &set)
0518 {
0519 return QtPrivate::readListBasedContainer(s, set);
0520 }
0521
0522 template <typename T>
0523 inline QDataStreamIfHasOStreamOperatorsContainer<QSet<T>, T> operator<<(QDataStream &s, const QSet<T> &set)
0524 {
0525 return QtPrivate::writeSequentialContainer(s, set);
0526 }
0527
0528 template <class Key, class T>
0529 inline QDataStreamIfHasIStreamOperatorsContainer<QHash<Key, T>, Key, T> operator>>(QDataStream &s, QHash<Key, T> &hash)
0530 {
0531 return QtPrivate::readAssociativeContainer(s, hash);
0532 }
0533
0534 template <class Key, class T>
0535
0536 inline QDataStreamIfHasOStreamOperatorsContainer<QHash<Key, T>, Key, T> operator<<(QDataStream &s, const QHash<Key, T> &hash)
0537 {
0538 return QtPrivate::writeAssociativeContainer(s, hash);
0539 }
0540
0541 template <class Key, class T>
0542 inline QDataStreamIfHasIStreamOperatorsContainer<QMultiHash<Key, T>, Key, T> operator>>(QDataStream &s, QMultiHash<Key, T> &hash)
0543 {
0544 return QtPrivate::readAssociativeContainer(s, hash);
0545 }
0546
0547 template <class Key, class T>
0548 inline QDataStreamIfHasOStreamOperatorsContainer<QMultiHash<Key, T>, Key, T> operator<<(QDataStream &s, const QMultiHash<Key, T> &hash)
0549 {
0550 return QtPrivate::writeAssociativeMultiContainer(s, hash);
0551 }
0552
0553 template <class Key, class T>
0554 inline QDataStreamIfHasIStreamOperatorsContainer<QMap<Key, T>, Key, T> operator>>(QDataStream &s, QMap<Key, T> &map)
0555 {
0556 return QtPrivate::readAssociativeContainer(s, map);
0557 }
0558
0559 template <class Key, class T>
0560 inline QDataStreamIfHasOStreamOperatorsContainer<QMap<Key, T>, Key, T> operator<<(QDataStream &s, const QMap<Key, T> &map)
0561 {
0562 return QtPrivate::writeAssociativeContainer(s, map);
0563 }
0564
0565 template <class Key, class T>
0566 inline QDataStreamIfHasIStreamOperatorsContainer<QMultiMap<Key, T>, Key, T> operator>>(QDataStream &s, QMultiMap<Key, T> &map)
0567 {
0568 return QtPrivate::readAssociativeContainer(s, map);
0569 }
0570
0571 template <class Key, class T>
0572 inline QDataStreamIfHasOStreamOperatorsContainer<QMultiMap<Key, T>, Key, T> operator<<(QDataStream &s, const QMultiMap<Key, T> &map)
0573 {
0574 return QtPrivate::writeAssociativeMultiContainer(s, map);
0575 }
0576
0577 template <class T1, class T2>
0578 inline QDataStreamIfHasIStreamOperators<T1, T2> operator>>(QDataStream& s, std::pair<T1, T2> &p)
0579 {
0580 s >> p.first >> p.second;
0581 return s;
0582 }
0583
0584 template <class T1, class T2>
0585 inline QDataStreamIfHasOStreamOperators<T1, T2> operator<<(QDataStream& s, const std::pair<T1, T2> &p)
0586 {
0587 s << p.first << p.second;
0588 return s;
0589 }
0590
0591 #else
0592
0593 template <class T>
0594 QDataStream &operator>>(QDataStream &s, QList<T> &l);
0595
0596 template <class T>
0597 QDataStream &operator<<(QDataStream &s, const QList<T> &l);
0598
0599 template <class T>
0600 QDataStream &operator>>(QDataStream &s, QSet<T> &set);
0601
0602 template <class T>
0603 QDataStream &operator<<(QDataStream &s, const QSet<T> &set);
0604
0605 template <class Key, class T>
0606 QDataStream &operator>>(QDataStream &s, QHash<Key, T> &hash);
0607
0608 template <class Key, class T>
0609 QDataStream &operator<<(QDataStream &s, const QHash<Key, T> &hash);
0610
0611 template <class Key, class T>
0612 QDataStream &operator>>(QDataStream &s, QMultiHash<Key, T> &hash);
0613
0614 template <class Key, class T>
0615 QDataStream &operator<<(QDataStream &s, const QMultiHash<Key, T> &hash);
0616
0617 template <class Key, class T>
0618 QDataStream &operator>>(QDataStream &s, QMap<Key, T> &map);
0619
0620 template <class Key, class T>
0621 QDataStream &operator<<(QDataStream &s, const QMap<Key, T> &map);
0622
0623 template <class Key, class T>
0624 QDataStream &operator>>(QDataStream &s, QMultiMap<Key, T> &map);
0625
0626 template <class Key, class T>
0627 QDataStream &operator<<(QDataStream &s, const QMultiMap<Key, T> &map);
0628
0629 template <class T1, class T2>
0630 QDataStream &operator>>(QDataStream& s, std::pair<T1, T2> &p);
0631
0632 template <class T1, class T2>
0633 QDataStream &operator<<(QDataStream& s, const std::pair<T1, T2> &p);
0634
0635 #endif
0636
0637 inline QDataStream &operator>>(QDataStream &s, QKeyCombination &combination)
0638 {
0639 int combined;
0640 s >> combined;
0641 combination = QKeyCombination::fromCombined(combined);
0642 return s;
0643 }
0644
0645 inline QDataStream &operator<<(QDataStream &s, QKeyCombination combination)
0646 {
0647 return s << combination.toCombined();
0648 }
0649
0650 #endif
0651
0652 QT_END_NAMESPACE
0653
0654 #endif