From 092df2edaa54d8938bf54b71966ad85f12ae9069 Mon Sep 17 00:00:00 2001
From: Marco Bubke <marco.bubke@qt.io>
Date: Mon, 8 Aug 2016 16:27:07 +0200
Subject: [PATCH] Clang: Smallstring should not depend on std::ostream

We move the io operators in an extra header file because if we would
include ostream in smallstring.h we would blow the compile time.

Change-Id: Iea61ceedbbbcdd2adc6dc149794dab6e743084f8
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
---
 src/libs/clangbackendipc/filepath.h           |   1 +
 .../sourcelocationscontainer.cpp              |   2 +
 .../sourcelocationsforrenamingmessage.cpp     |   4 -
 src/libs/utils/smallstring.h                  | 115 +--------
 src/libs/utils/smallstringio.h                | 238 ++++++++++++++++++
 src/libs/utils/smallstringvector.h            |  97 +------
 src/libs/utils/utils-lib.pri                  |   3 +-
 src/libs/utils/utils.qbs                      |   1 +
 tests/unit/unittest/smallstringtest.cpp       |   4 +-
 9 files changed, 249 insertions(+), 216 deletions(-)
 create mode 100644 src/libs/utils/smallstringio.h

diff --git a/src/libs/clangbackendipc/filepath.h b/src/libs/clangbackendipc/filepath.h
index 31f6a0d55d3..dd1ab90374b 100644
--- a/src/libs/clangbackendipc/filepath.h
+++ b/src/libs/clangbackendipc/filepath.h
@@ -28,6 +28,7 @@
 #include "clangbackendipc_global.h"
 
 #include <utils/smallstring.h>
+#include <utils/smallstringio.h>
 
 namespace ClangBackEnd {
 
diff --git a/src/libs/clangbackendipc/sourcelocationscontainer.cpp b/src/libs/clangbackendipc/sourcelocationscontainer.cpp
index d174e30e624..0cc7ff58621 100644
--- a/src/libs/clangbackendipc/sourcelocationscontainer.cpp
+++ b/src/libs/clangbackendipc/sourcelocationscontainer.cpp
@@ -25,6 +25,8 @@
 
 #include "sourcelocationscontainer.h"
 
+#include <ostream>
+
 namespace ClangBackEnd {
 
 QDebug operator<<(QDebug debug, const SourceLocationsContainer &container)
diff --git a/src/libs/clangbackendipc/sourcelocationsforrenamingmessage.cpp b/src/libs/clangbackendipc/sourcelocationsforrenamingmessage.cpp
index cbf93fb6edc..eff8449354d 100644
--- a/src/libs/clangbackendipc/sourcelocationsforrenamingmessage.cpp
+++ b/src/libs/clangbackendipc/sourcelocationsforrenamingmessage.cpp
@@ -25,10 +25,6 @@
 
 #include "sourcelocationsforrenamingmessage.h"
 
-#include <QDebug>
-
-#include <ostream>
-
 namespace ClangBackEnd {
 
 QDebug operator<<(QDebug debug, const SourceLocationsForRenamingMessage &message)
diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h
index 9855d96da3d..ddda799a248 100644
--- a/src/libs/utils/smallstring.h
+++ b/src/libs/utils/smallstring.h
@@ -33,8 +33,6 @@
 #include "smallstringmemory.h"
 
 #include <QByteArray>
-#include <QDataStream>
-#include <QDebug>
 #include <QString>
 
 #include <algorithm>
@@ -42,10 +40,10 @@
 #include <cstdlib>
 #include <climits>
 #include <cstring>
-#include <iosfwd>
 #include <string>
 #include <unordered_map>
 #include <utility>
+#include <vector>
 
 #pragma push_macro("constexpr")
 #ifndef __cpp_constexpr
@@ -776,117 +774,6 @@ bool operator<(const SmallString& first, const SmallString& second) noexcept
     return comparison < 0;
 }
 
-inline
-QDataStream &operator<<(QDataStream &out, const SmallString &string)
-{
-   if (string.isEmpty())
-       out << quint32(0);
-   else
-       out.writeBytes(string.data(), qint32(string.size()));
-
-   return out;
-}
-
-inline
-QDataStream &operator>>(QDataStream &in, SmallString &string)
-{
-    quint32 size;
-
-    in >> size;
-
-    if (size > 0 ) {
-        string.resize(size);
-
-        char *data = string.data();
-
-        in.readRawData(data, size);
-    }
-
-    return in;
-}
-
-inline
-QDebug &operator<<(QDebug &debug, const SmallString &string)
-{
-    using QT_USE_NAMESPACE::operator<<;
-
-    debug.nospace() << "\"" << string.data() << "\"";
-
-    return debug;
-}
-
-inline
-std::ostream &operator<<(std::ostream &stream, const SmallString &string)
-{
-    using std::operator<<;
-
-    return stream << string.data();
-}
-
-inline
-void PrintTo(const SmallString &string, ::std::ostream *os)
-{
-    *os << "'" << string.data() << "'";
-}
-
-} // namespace Utils
-
-namespace std {
-
-template<> struct hash<Utils::SmallString>
-{
-    using argument_type = Utils::SmallString;
-    using result_type = uint;
-    result_type operator()(const argument_type& string) const
-    {
-        return qHashBits(string.data(), string.size());
-    }
-};
-
-template<typename Key,
-         typename Value,
-         typename Hash = hash<Key>,
-         typename KeyEqual = equal_to<Key>,
-         typename Allocator = allocator<pair<const Key, Value>>>
-QDataStream &operator<<(QDataStream &out, const unordered_map<Key, Value, Hash, KeyEqual, Allocator> &map)
-{
-    out << quint64(map.size());
-
-    for (auto &&entry : map)
-        out << entry.first << entry.second;
-
-    return out;
-}
-
-template<typename Key,
-         typename Value,
-         typename Hash = hash<Key>,
-         typename KeyEqual = equal_to<Key>,
-         typename Allocator = allocator<pair<const Key, Value>>>
-QDataStream &operator>>(QDataStream &in, unordered_map<Key, Value, Hash, KeyEqual, Allocator> &map)
-{
-    quint64 size;
-
-    in >> size;
-
-    map.reserve(size);
-
-    for (quint64 i = 0; i < size; ++i) {
-        Key key;
-        Value value;
-
-        in >> key >> value;
-
-        map.insert(make_pair(move(key), move(value)));
-    }
-
-    return in;
-}
-
-} // namespace std
-
-namespace Utils {
-
 template<typename Key,
          typename Value,
          typename Hash = std::hash<Key>,
diff --git a/src/libs/utils/smallstringio.h b/src/libs/utils/smallstringio.h
new file mode 100644
index 00000000000..80553b82b7e
--- /dev/null
+++ b/src/libs/utils/smallstringio.h
@@ -0,0 +1,238 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "smallstringvector.h"
+
+#include <QDataStream>
+#include <QDebug>
+
+#include <ostream>
+
+namespace Utils {
+
+inline
+QDataStream &operator<<(QDataStream &out, const SmallString &string)
+{
+   if (string.isEmpty())
+       out << quint32(0);
+   else
+       out.writeBytes(string.data(), qint32(string.size()));
+
+   return out;
+}
+
+inline
+QDataStream &operator>>(QDataStream &in, SmallString &string)
+{
+    quint32 size;
+
+    in >> size;
+
+    if (size > 0 ) {
+        string.resize(size);
+
+        char *data = string.data();
+
+        in.readRawData(data, size);
+    }
+
+    return in;
+}
+
+inline
+QDebug &operator<<(QDebug &debug, const SmallString &string)
+{
+    using QT_USE_NAMESPACE::operator<<;
+
+    debug.nospace() << "\"" << string.data() << "\"";
+
+    return debug;
+}
+
+inline
+std::ostream &operator<<(std::ostream &stream, const SmallString &string)
+{
+    using std::operator<<;
+
+    return stream << std::string(string.data());
+}
+
+inline
+void PrintTo(const SmallString &string, ::std::ostream *os)
+{
+    *os << "'" << string.data() << "'";
+}
+
+inline QDataStream &operator<<(QDataStream &out, const SmallStringVector &stringVector)
+{
+    out << quint64(stringVector.size());
+
+    for (auto &&string : stringVector)
+        out << string;
+
+    return out;
+}
+
+inline
+QDataStream &operator>>(QDataStream &in, SmallStringVector &stringVector)
+{
+    stringVector.clear();
+
+    quint64 size;
+
+    in >> size;
+
+    stringVector.reserve(size);
+
+    for (quint64 i = 0; i < size; ++i) {
+        SmallString string;
+
+        in >> string;
+
+        stringVector.push_back(std::move(string));
+    }
+
+    return in;
+}
+
+inline
+QDebug operator<<(QDebug debug, const SmallStringVector &stringVector)
+{
+    debug << "StringVector(" << stringVector.join(Utils::SmallString(", ")).constData() << ")";
+
+    return debug;
+}
+
+inline
+void PrintTo(const SmallStringVector &textVector, ::std::ostream* os)
+{
+    *os << "StringVector(" << textVector.join(Utils::SmallString(", ")).constData() << ")";
+}
+
+} // namespace Utils
+
+namespace std {
+
+template<> struct hash<Utils::SmallString>
+{
+    using argument_type = Utils::SmallString;
+    using result_type = uint;
+    result_type operator()(const argument_type& string) const
+    {
+        return qHashBits(string.data(), string.size());
+    }
+};
+
+template<typename Key,
+         typename Value,
+         typename Hash = hash<Key>,
+         typename KeyEqual = equal_to<Key>,
+         typename Allocator = allocator<pair<const Key, Value>>>
+QDataStream &operator<<(QDataStream &out, const unordered_map<Key, Value, Hash, KeyEqual, Allocator> &map)
+{
+    out << quint64(map.size());
+
+    for (auto &&entry : map)
+        out << entry.first << entry.second;
+
+    return out;
+}
+
+template<typename Key,
+         typename Value,
+         typename Hash = hash<Key>,
+         typename KeyEqual = equal_to<Key>,
+         typename Allocator = allocator<pair<const Key, Value>>>
+QDataStream &operator>>(QDataStream &in, unordered_map<Key, Value, Hash, KeyEqual, Allocator> &map)
+{
+    quint64 size;
+
+    in >> size;
+
+    map.reserve(size);
+
+    for (quint64 i = 0; i < size; ++i) {
+        Key key;
+        Value value;
+
+        in >> key >> value;
+
+        map.insert(make_pair(move(key), move(value)));
+    }
+
+    return in;
+}
+
+template<typename Type>
+QDataStream &operator<<(QDataStream &out, const vector<Type> &vector)
+{
+    out << quint64(vector.size());
+
+    for (auto &&entry : vector)
+        out << entry;
+
+    return out;
+}
+
+template<typename Type>
+QDataStream &operator>>(QDataStream &in, vector<Type> &vector)
+{
+    vector.clear();
+
+    quint64 size;
+
+    in >> size;
+
+    vector.reserve(size);
+
+    for (quint64 i = 0; i < size; ++i) {
+        Type entry;
+
+        in >> entry;
+
+        vector.push_back(move(entry));
+    }
+
+    return in;
+}
+
+QT_BEGIN_NAMESPACE
+
+template<typename Type>
+QDebug &operator<<(QDebug &debug, const std::vector<Type> &vector)
+{
+    debug.noquote() << "[";
+    for (auto &&entry : vector)
+        debug.noquote() << entry << ", ";
+    debug.noquote() << "]";
+
+    return debug;
+}
+
+QT_END_NAMESPACE
+
+} // namespace std
diff --git a/src/libs/utils/smallstringvector.h b/src/libs/utils/smallstringvector.h
index 897bcef84fb..c81074532c0 100644
--- a/src/libs/utils/smallstringvector.h
+++ b/src/libs/utils/smallstringvector.h
@@ -31,6 +31,8 @@
 
 #include <vector>
 
+#include <QStringList>
+
 #pragma push_macro("noexcept")
 #ifndef __cpp_noexcept
 #define noexcept
@@ -148,101 +150,6 @@ private:
     }
 };
 
-inline QDataStream &operator<<(QDataStream &out, const SmallStringVector &stringVector)
-{
-    out << quint64(stringVector.size());
-
-    for (auto &&string : stringVector)
-        out << string;
-
-    return out;
-}
-
-inline QDataStream &operator>>(QDataStream &in, SmallStringVector &stringVector)
-{
-    stringVector.clear();
-
-    quint64 size;
-
-    in >> size;
-
-    stringVector.reserve(size);
-
-    for (quint64 i = 0; i < size; ++i) {
-        SmallString string;
-
-        in >> string;
-
-        stringVector.push_back(std::move(string));
-    }
-
-    return in;
-}
-
-inline QDebug operator<<(QDebug debug, const SmallStringVector &stringVector)
-{
-    debug << "StringVector(" << stringVector.join(Utils::SmallString(", ")).constData() << ")";
-
-    return debug;
-}
-
-inline void PrintTo(const SmallStringVector &textVector, ::std::ostream* os)
-{
-    *os << "StringVector(" << textVector.join(Utils::SmallString(", ")).constData() << ")";
-}
-
 } // namespace Utils;
 
-namespace std {
-
-template<typename Type>
-QDataStream &operator<<(QDataStream &out, const vector<Type> &vector)
-{
-    out << quint64(vector.size());
-
-    for (auto &&entry : vector)
-        out << entry;
-
-    return out;
-}
-
-template<typename Type>
-QDataStream &operator>>(QDataStream &in, vector<Type> &vector)
-{
-    vector.clear();
-
-    quint64 size;
-
-    in >> size;
-
-    vector.reserve(size);
-
-    for (quint64 i = 0; i < size; ++i) {
-        Type entry;
-
-        in >> entry;
-
-        vector.push_back(move(entry));
-    }
-
-    return in;
-}
-
-} // namespace std
-
-QT_BEGIN_NAMESPACE
-
-template<typename Type>
-QDebug &operator<<(QDebug &debug, const std::vector<Type> &vector)
-{
-    debug.noquote() << "[";
-    for (auto &&entry : vector)
-        debug.noquote() << entry << ", ";
-    debug.noquote() << "]";
-
-    return debug;
-}
-
-QT_END_NAMESPACE
-
 #pragma pop_macro("noexcept")
diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri
index 9139016cc34..231aa953cd6 100644
--- a/src/libs/utils/utils-lib.pri
+++ b/src/libs/utils/utils-lib.pri
@@ -217,7 +217,8 @@ HEADERS += \
     $$PWD/smallstringmemory.h \
     $$PWD/smallstringvector.h \
     $$PWD/smallstringlayout.h \
-    $$PWD/sizedarray.h
+    $$PWD/sizedarray.h \
+    $$PWD/smallstringio.h
 
 FORMS += $$PWD/filewizardpage.ui \
     $$PWD/projectintropage.ui \
diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs
index 8b41c2f6028..bbad8dafc7a 100644
--- a/src/libs/utils/utils.qbs
+++ b/src/libs/utils/utils.qbs
@@ -194,6 +194,7 @@ Project {
             "sleep.h",
             "smallstring.h",
             "smallstringiterator.h",
+            "smallstringio.h",
             "smallstringliteral.h",
             "smallstringlayout.h",
             "smallstringmemory.h",
diff --git a/tests/unit/unittest/smallstringtest.cpp b/tests/unit/unittest/smallstringtest.cpp
index b634b84b6d4..19fbc82057c 100644
--- a/tests/unit/unittest/smallstringtest.cpp
+++ b/tests/unit/unittest/smallstringtest.cpp
@@ -29,9 +29,9 @@
 
 #include <QString>
 
-#include <utils/smallstringvector.h>
-
 #include <utils/smallstring.h>
+#include <utils/smallstringio.h>
+#include <utils/smallstringvector.h>
 
 #ifndef __cpp_constexpr
 #define constexpr
-- 
GitLab