Commit 8640ef19 authored by Marco Bubke's avatar Marco Bubke

Utils: Convert to SmallStringView for comparison

Change-Id: I38d9716225b81091e8e75b26c9c2258a2aefa987
Reviewed-by: Tim Jenssen's avatarTim Jenssen <tim.jenssen@qt.io>
parent 7c0331ab
......@@ -34,9 +34,9 @@ namespace Sqlite {
class SQLITE_EXPORT SqliteException
{
public:
SqliteException(Utils::SmallString &&whatErrorHasHappen,
SqliteException(const char *whatErrorHasHappen,
Utils::SmallString &&sqliteErrorMessage = Utils::SmallString())
: m_whatErrorHasHappen(std::move(whatErrorHasHappen)),
: m_whatErrorHasHappen(whatErrorHasHappen),
m_sqliteErrorMessage(std::move(sqliteErrorMessage))
{
}
......@@ -44,7 +44,7 @@ public:
void printWarning() const;
private:
Utils::SmallString m_whatErrorHasHappen;
const char *m_whatErrorHasHappen;
Utils::SmallString m_sqliteErrorMessage;
};
......
......@@ -242,11 +242,13 @@ public:
return SmallStringView(data(), size());
}
explicit
operator QString() const
{
return toQString();
}
explicit
operator std::string() const
{
return std::string(data(), size());
......@@ -589,100 +591,6 @@ public:
return *(data() + index);
}
template<size_type ArraySize>
friend bool operator==(const BasicSmallString& first, const char(&second)[ArraySize]) noexcept
{
return first == SmallStringView(second);
}
template<size_type ArraySize>
friend bool operator==(const char(&first)[ArraySize], const BasicSmallString& second) noexcept
{
return second == first;
}
template<typename Type,
typename = std::enable_if_t<std::is_pointer<Type>::value>
>
friend bool operator==(const BasicSmallString& first, Type second) noexcept
{
return first == SmallStringView(second);
}
template<typename Type,
typename = std::enable_if_t<std::is_pointer<Type>::value>
>
friend bool operator==(Type first, const BasicSmallString& second) noexcept
{
return second == first;
}
friend bool operator==(const BasicSmallString& first, const SmallStringView& second) noexcept
{
return first.size() == second.size()
&& std::memcmp(first.data(), second.data(), first.size()) == 0;
}
friend bool operator==(const SmallStringView& first, const BasicSmallString& second) noexcept
{
return second == first;
}
friend bool operator!=(const BasicSmallString& first, const SmallStringView& second) noexcept
{
return !(first == second);
}
friend bool operator!=(const SmallStringView& first, const BasicSmallString& second) noexcept
{
return second == first;
}
friend bool operator!=(const BasicSmallString& first, const BasicSmallString& second) noexcept
{
return !(first == second);
}
template<size_type ArraySize>
friend bool operator!=(const BasicSmallString& first, const char(&second)[ArraySize]) noexcept
{
return !(first == second);
}
template<size_type ArraySize>
friend bool operator!=(const char(&first)[ArraySize], const BasicSmallString& second) noexcept
{
return second != first;
}
template<typename Type,
typename = std::enable_if_t<std::is_pointer<Type>::value>
>
friend bool operator!=(const BasicSmallString& first, Type second) noexcept
{
return !(first == second);
}
template<typename Type,
typename = std::enable_if_t<std::is_pointer<Type>::value>
>
friend bool operator!=(Type first, const BasicSmallString& second) noexcept
{
return second != first;
}
friend bool operator<(const BasicSmallString& first, SmallStringView second) noexcept
{
return first.size() < second.size()
|| (first.size() == second.size() && std::memcmp(first.data(), second.data(), first.size()) < 0);
}
friend bool operator<(SmallStringView first, const BasicSmallString& second) noexcept
{
return first.size() < second.size()
|| (first.size() == second.size() && std::memcmp(first.data(), second.data(), first.size()) < 0);
}
friend BasicSmallString operator+(const BasicSmallString &first, const BasicSmallString &second)
{
BasicSmallString text;
......@@ -994,29 +902,6 @@ template<template<uint> class String, uint Size>
using isSameString = std::is_same<std::remove_reference_t<std::remove_cv_t<String<Size>>>,
BasicSmallString<Size>>;
template<template<uint> class String,
uint SizeOne,
uint SizeTwo,
typename = std::enable_if_t<isSameString<String, SizeOne>::value
|| isSameString<String, SizeTwo>::value>>
bool operator==(const String<SizeOne> &first, const String<SizeTwo> &second) noexcept
{
return first.size() == second.size()
&& std::memcmp(first.data(), second.data(), first.size()) == 0;
}
template<template<uint> class String,
uint SizeOne,
uint SizeTwo,
typename = std::enable_if_t<isSameString<String, SizeOne>::value
|| isSameString<String, SizeTwo>::value>>
bool operator<(const String<SizeOne> &first, const String<SizeTwo> &second) noexcept
{
return first.size() < second.size()
|| (first.size() == second.size() && std::memcmp(first.data(), second.data(), first.size()) < 0);
}
template<typename Key,
typename Value,
typename Hash = std::hash<Key>,
......
......@@ -29,9 +29,15 @@ namespace Utils {
using uint = unsigned int;
class SmallStringView;
template <uint Size>
class BasicSmallString;
using SmallString = BasicSmallString<31>;
using PathString = BasicSmallString<190>;
inline
int compare(SmallStringView first, SmallStringView second) noexcept;
inline
int reverseCompare(SmallStringView first, SmallStringView second) noexcept;
} // namespace Utils
......@@ -41,6 +41,7 @@ struct SmallStringIterator : public std::iterator<Category, Type, DistanceType,
{
SmallStringIterator() noexcept = default;
constexpr
SmallStringIterator(Pointer ptr) noexcept : pointer_(ptr)
{
}
......
......@@ -56,12 +56,12 @@ public:
{
}
const char *data() const
const char *data() const noexcept
{
return Q_LIKELY(isShortString()) ? m_data.shortString.string : m_data.allocated.data.pointer;
}
size_type size() const
size_type size() const noexcept
{
return Q_LIKELY(isShortString()) ? m_data.shortString.shortStringSize : m_data.allocated.data.size;
}
......
......@@ -138,7 +138,8 @@ public:
QStringList qStringList;
qStringList.reserve(int(Base::size()));
std::copy(Base::begin(), Base::end(), std::back_inserter(qStringList));
for (const auto &entry : *this)
qStringList.push_back(QString(entry));
return qStringList;
}
......
......@@ -67,6 +67,12 @@ public:
{
}
SmallStringView(const std::string &string) noexcept
: m_pointer(string.data()),
m_size(string.size())
{
}
static
SmallStringView fromUtf8(const char *const characterPointer)
{
......@@ -74,19 +80,19 @@ public:
}
constexpr
const char *data() const
const char *data() const noexcept
{
return m_pointer;
}
constexpr
size_type size() const
size_type size() const noexcept
{
return m_size;
}
constexpr
size_type isEmpty() const
size_type isEmpty() const noexcept
{
return m_size == 0;
}
......@@ -140,19 +146,19 @@ private:
};
inline
bool operator==(const SmallStringView& first, const SmallStringView& second) noexcept
bool operator==(SmallStringView first, SmallStringView second) noexcept
{
return first.size() == second.size() && std::memcmp(first.data(), second.data(), first.size()) == 0;
}
inline
bool operator!=(const SmallStringView& first, const SmallStringView& second) noexcept
bool operator!=(SmallStringView first, SmallStringView second) noexcept
{
return !(first == second);
}
inline
int compare(const SmallStringView& first, const SmallStringView& second) noexcept
int compare(SmallStringView first, SmallStringView second) noexcept
{
int sizeDifference = int(first.size() - second.size());
......@@ -162,6 +168,18 @@ int compare(const SmallStringView& first, const SmallStringView& second) noexcep
return sizeDifference;
}
inline
bool operator<(SmallStringView first, SmallStringView second) noexcept
{
return compare(first, second) < 0;
}
inline
bool operator>(SmallStringView first, SmallStringView second) noexcept
{
return second < first;
}
namespace Internal {
inline
int reverse_memcmp(const char *first, const char *second, size_t n)
......@@ -187,7 +205,7 @@ int reverse_memcmp(const char *first, const char *second, size_t n)
}
inline
int reverseCompare(const SmallStringView& first, const SmallStringView& second) noexcept
int reverseCompare(SmallStringView first, SmallStringView second) noexcept
{
int sizeDifference = int(first.size() - second.size());
......
......@@ -43,7 +43,7 @@ void PchManagerClient::alive()
void PchManagerClient::precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeadersUpdatedMessage &&message)
{
for (const ClangBackEnd::ProjectPartPch &projectPartPch : message.projectPartPchs())
precompiledHeaderUpdated(projectPartPch.id(), projectPartPch.path());
precompiledHeaderUpdated(QString(projectPartPch.id()), QString(projectPartPch.path()));
}
void PchManagerClient::precompiledHeaderRemoved(const QString &projectPartId)
......
......@@ -25,7 +25,7 @@
#pragma once
#include <clangpchmanager_global.h>
#include "clangpchmanager_global.h"
#include <filecontainerv2.h>
......
......@@ -52,9 +52,9 @@ void ClangQueryHoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorW
Contexts contexts = m_highligher->contextsForLineAndColumn(uint(line), uint(column));
if (!messages.empty())
setToolTip(QString("%1: %2").arg(messages[0].errorTypeText()).arg(messages[0].arguments().join(", ")));
setToolTip(QString("%1: %2").arg(QString(messages[0].errorTypeText())).arg(QString(messages[0].arguments().join(", "))));
else if (!contexts.empty())
setToolTip(QString("%1: %2").arg(contexts[0].contextTypeText()).arg(contexts[0].arguments().join(", ")));
setToolTip(QString("%1: %2").arg(QString(contexts[0].contextTypeText())).arg(QString(contexts[0].arguments().join(", "))));
}
} // namespace ClangRefactoring
......@@ -154,7 +154,7 @@ void RefactoringClient::addSearchResult(const ClangBackEnd::SourceRangeWithTextC
std::unordered_map<uint, QString> &filePaths)
{
m_searchHandle->addResult(filePaths[sourceRangeWithText.fileHash()],
sourceRangeWithText.text(),
QString(sourceRangeWithText.text()),
{{int(sourceRangeWithText.start().line()),
int(sourceRangeWithText.start().column() - 1),
int(sourceRangeWithText.start().offset())},
......
......@@ -66,24 +66,24 @@ template <typename Source,
typename Target>
void append(Target &target, const Source &source)
{
using ValueType = typename Target::value_type;
Source clonedSource = source.clone();
target.reserve(target.size() + source.size());
std::move(clonedSource.begin(),
clonedSource.end(),
std::back_inserter(target));
for(auto &&entry : clonedSource)
target.push_back(ValueType(std::move(entry)));
}
template <typename Source,
typename Target>
void append(Target &target, Source &source)
{
using ValueType = typename Target::value_type;
target.reserve(target.size() + source.size());
std::move(source.begin(),
source.end(),
std::back_inserter(target));
for(auto &&entry : source)
target.push_back(ValueType(entry));
}
template <typename GetterFunction>
......@@ -469,14 +469,14 @@ std::vector<uint> PchCreator::generateProjectPartPchIncludes(
auto jointFile = generateFileWithContent(jointedFilePath, jointedFileContent);
Utils::SmallStringVector arguments = generateProjectPartCommandLine(projectPart);
arguments.push_back(jointedFilePath);
FilePath filePath(jointedFilePath.clone());
FilePath filePath{Utils::PathString(jointedFilePath)};
IncludeCollector collector(m_filePathCache);
collector.setExcludedIncludes(generateProjectPartHeaderAndSourcePaths(projectPart));
collector.addFile(filePath.directory(),
filePath.name(),
collector.addFile(std::string(filePath.directory()),
std::string(filePath.name()),
{},
arguments);
......@@ -581,11 +581,11 @@ std::unique_ptr<QFile> PchCreator::generateFileWithContent(
const Utils::SmallString &filePath,
const Utils::SmallString &content)
{
std::unique_ptr<QFile> precompiledIncludeFile(new QFile(filePath));
std::unique_ptr<QFile> precompiledIncludeFile(new QFile(QString(filePath)));
precompiledIncludeFile->open(QIODevice::WriteOnly);
precompiledIncludeFile->write(content.data(), content.size());
precompiledIncludeFile->write(content.data(), qint64(content.size()));
precompiledIncludeFile->close();
return precompiledIncludeFile;
......
......@@ -70,8 +70,8 @@ unittest_public:
Process *processPointer = process.get();
process->setProcessChannelMode(QProcess::ForwardedChannels);
process->setArguments(compilerArguments);
process->setProgram(m_environment.clangCompilerPath());
process->setArguments(QStringList(compilerArguments));
process->setProgram(QString(m_environment.clangCompilerPath()));
connectProcess(processPointer, std::move(projectPartPch));
......
......@@ -50,10 +50,10 @@ ClangQueryGatherer::createSourceRangesForSource(
{
ClangQuery clangQuery(*filePathCache, std::move(query));
clangQuery.addFile(source.filePath().directory(),
source.filePath().name(),
source.takeUnsavedFileContent(),
source.takeCommandLineArguments());
clangQuery.addFile(std::string(source.filePath().directory()),
std::string(source.filePath().name()),
std::string(source.takeUnsavedFileContent()),
std::vector<std::string>(source.takeCommandLineArguments()));
clangQuery.addUnsavedFiles(unsaved);
......
......@@ -68,7 +68,7 @@ void ClangTool::addFiles(const Container &filePaths,
auto fileNameBegin = found.base();
std::vector<std::string> commandLine(arguments.begin(), arguments.end());
commandLine.push_back(filePath);
commandLine.push_back(std::string(filePath));
addFile({filePath.begin(), std::prev(fileNameBegin)},
{fileNameBegin, filePath.end()},
......
......@@ -66,7 +66,7 @@ public:
std::string takeSymbolName()
{
return std::move(symbolName);
return std::string(symbolName);
}
std::vector<USRName> takeUnifiedSymbolResolutions()
......
......@@ -56,10 +56,10 @@ void RefactoringServer::requestSourceLocationsForRenamingMessage(RequestSourceLo
{
SymbolFinder symbolFinder(message.line(), message.column());
symbolFinder.addFile(message.filePath().directory(),
message.filePath().name(),
message.unsavedContent(),
message.commandLine());
symbolFinder.addFile(std::string(message.filePath().directory()),
std::string(message.filePath().name()),
std::string(message.unsavedContent()),
std::vector<std::string>(message.commandLine()));
symbolFinder.findSymbol();
......@@ -73,10 +73,10 @@ void RefactoringServer::requestSourceRangesAndDiagnosticsForQueryMessage(
{
ClangQuery clangQuery(m_filePathCache, message.takeQuery());
clangQuery.addFile(message.source().filePath().directory(),
message.source().filePath().name(),
message.source().unsavedFileContent(),
message.source().commandLineArguments());
clangQuery.addFile(std::string(message.source().filePath().directory()),
std::string(message.source().filePath().name()),
std::string(message.source().unsavedFileContent()),
std::vector<std::string>(message.source().commandLineArguments()));
clangQuery.findLocations();
......
......@@ -68,7 +68,7 @@ TEST_F(ClangPathWatcher, ConvertWatcherEntriesToQStringList)
{
auto convertedList = watcher.convertWatcherEntriesToQStringList({watcherEntry1, watcherEntry3});
ASSERT_THAT(convertedList, ElementsAre(path1, path2));
ASSERT_THAT(convertedList, ElementsAre(QString(path1), QString(path2)));
}
TEST_F(ClangPathWatcher, UniquePaths)
......@@ -89,7 +89,7 @@ TEST_F(ClangPathWatcher, NotWatchedEntries)
TEST_F(ClangPathWatcher, AddIdPaths)
{
EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1, path2}));
EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{QString(path1), QString(path2)}));
watcher.updateIdPaths({{id1, {paths[0], paths[1]}}, {id2, {paths[0], paths[1]}}});
}
......@@ -98,7 +98,7 @@ TEST_F(ClangPathWatcher, UpdateIdPathsCallsAddPathInFileWatcher)
{
watcher.updateIdPaths({{id1, {paths[0]}}, {id2, {paths[0]}}});
EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path2}));
EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{QString(path2)}));
watcher.updateIdPaths({{id1, {paths[0], paths[1]}}, {id2, {paths[0], paths[1]}}});
}
......@@ -107,7 +107,7 @@ TEST_F(ClangPathWatcher, UpdateIdPathsAndRemoveUnusedPathsCallsRemovePathInFileW
{
watcher.updateIdPaths({{id1, {paths[0], paths[1]}}, {id2, {paths[0], paths[1]}}, {id3, {paths[0]}}});
EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path2}));
EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{QString(path2)}));
watcher.updateIdPaths({{id1, {paths[0]}}, {id2, {paths[0]}}});
}
......@@ -116,7 +116,7 @@ TEST_F(ClangPathWatcher, UpdateIdPathsAndRemoveUnusedPathsDoNotCallsRemovePathIn
{
watcher.updateIdPaths({{id1, {paths[0], paths[1]}}, {id2, {paths[0], paths[1]}}, {id3, {paths[0]}}});
EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path2}))
EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{QString(path2)}))
.Times(0);
watcher.updateIdPaths({{id1, {paths[1]}}, {id2, {paths[0]}}});
......@@ -189,14 +189,14 @@ TEST_F(ClangPathWatcher, AddEmptyEntries)
TEST_F(ClangPathWatcher, AddEntriesWithSameIdAndDifferentPaths)
{
EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1, path2}));
EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{QString(path1), QString(path2)}));
watcher.addEntries({watcherEntry1, watcherEntry3});
}
TEST_F(ClangPathWatcher, AddEntriesWithDifferentIdAndSamePaths)
{
EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1}));
EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{QString(path1)}));
watcher.addEntries({watcherEntry1, watcherEntry2});
}
......@@ -205,7 +205,7 @@ TEST_F(ClangPathWatcher, DontAddNewEntriesWithSameIdAndSamePaths)
{
watcher.addEntries({watcherEntry1});
EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1}))
EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{QString(path1)}))
.Times(0);
watcher.addEntries({watcherEntry1});
......@@ -215,7 +215,7 @@ TEST_F(ClangPathWatcher, DontAddNewEntriesWithDifferentIdAndSamePaths)
{
watcher.addEntries({watcherEntry1});
EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1}))
EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{QString(path1)}))
.Times(0);
watcher.addEntries({watcherEntry2});
......@@ -252,7 +252,7 @@ TEST_F(ClangPathWatcher, RemovePathForOneId)
{
watcher.addEntries({watcherEntry1, watcherEntry2, watcherEntry3});
EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path2}));
EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{QString(path2)}));
watcher.removeIds({id1});
}
......@@ -261,7 +261,7 @@ TEST_F(ClangPathWatcher, RemoveAllPathsForThreeId)
{
watcher.addEntries({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5});
EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path1, path2}));
EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{QString(path1), QString(path2)}));
watcher.removeIds({id1, id2, id3});
}
......@@ -270,7 +270,7 @@ TEST_F(ClangPathWatcher, RemoveOnePathForTwoId)
{
watcher.addEntries({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5});
EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path1}));
EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{QString(path1)}));
watcher.removeIds({id1, id2});
}
......
......@@ -170,7 +170,7 @@ TEST_F(ClangQueryProjectFindFilter, CallingRequestSourceRangesAndDiagnostics)
Property(&FileContainer::unsavedFileContent, exampleContent)),
Property(&Message::query, queryText))));
findFilter.requestSourceRangesAndDiagnostics(queryText, exampleContent);
findFilter.requestSourceRangesAndDiagnostics(QString(queryText), QString(exampleContent));
}
std::vector<CppTools::ProjectPart::Ptr> createProjectParts()
......
......@@ -39,3 +39,5 @@
#endif
#include "google-using-declarations.h"
#include "unittest-matchers.h"
......@@ -51,7 +51,6 @@ using testing::AtLeast;
using testing::ContainerEq;
using testing::Contains;