diff --git a/src/buffer/katetextblock.h b/src/buffer/katetextblock.h --- a/src/buffer/katetextblock.h +++ b/src/buffer/katetextblock.h @@ -21,6 +21,8 @@ #ifndef KATE_TEXTBLOCK_H #define KATE_TEXTBLOCK_H +#include + #include #include @@ -206,7 +208,7 @@ */ void removeCursor(Kate::TextCursor *cursor) { - m_cursors.remove(cursor); + m_cursors.erase(cursor); } /** @@ -246,18 +248,20 @@ /** * Lines contained in this buffer. These are shared pointers. + * We need no sharing, use STL. */ - QVector m_lines; + std::vector m_lines; /** * Startline of this block */ int m_startLine; /** * Set of cursors for this block. + * We need no sharing, use STL. */ - QSet m_cursors; + std::unordered_set m_cursors; /** * Contains for each line-offset the ranges that were cached into it. diff --git a/src/buffer/katetextblock.cpp b/src/buffer/katetextblock.cpp --- a/src/buffer/katetextblock.cpp +++ b/src/buffer/katetextblock.cpp @@ -57,19 +57,13 @@ // right input Q_ASSERT(line >= startLine()); - // calc internal line - line = line - startLine(); - - // in range - Q_ASSERT(line < m_lines.size()); - - // get text line - return m_lines.at(line); + // get text line, at will bail out on out-of-range + return m_lines.at(line - startLine()); } void TextBlock::appendLine(const QString &textOfLine) { - m_lines.append(TextLine::create(textOfLine)); + m_lines.push_back(TextLine::create(textOfLine)); } void TextBlock::clearLines() @@ -80,7 +74,7 @@ void TextBlock::text(QString &text) const { // combine all lines - for (int i = 0; i < m_lines.size(); ++i) { + for (size_t i = 0; i < m_lines.size(); ++i) { // not first line, insert \n if (i > 0 || startLine() > 0) { text.append(QLatin1Char('\n')); @@ -153,7 +147,7 @@ // move all cursors on the line which has the text inserted // remember all ranges modified, optimize for the standard case of a few ranges QVarLengthArray changedRanges; - for (TextCursor *cursor : qAsConst(m_cursors)) { + for (TextCursor *cursor : m_cursors) { // skip cursors on lines in front of the wrapped one! if (cursor->lineInBlock() < line) { continue; @@ -212,7 +206,7 @@ // move last line of previous block to this one, might result in empty block TextLine oldFirst = m_lines.at(0); int lastLineOfPreviousBlock = previousBlock->lines() - 1; - TextLine newFirst = previousBlock->m_lines.last(); + TextLine newFirst = previousBlock->m_lines.back(); m_lines[0] = newFirst; previousBlock->m_lines.erase(previousBlock->m_lines.begin() + (previousBlock->lines() - 1)); @@ -252,7 +246,7 @@ // move all cursors because of the unwrapped line // remember all ranges modified, optimize for the standard case of a few ranges QVarLengthArray changedRanges; - for (TextCursor *cursor : qAsConst(m_cursors)) { + for (TextCursor *cursor : m_cursors) { // this is the unwrapped line if (cursor->lineInBlock() == 0) { // patch column @@ -268,8 +262,8 @@ } // move cursors of the moved line from previous block to this block now - QSet newPreviousCursors; - for (TextCursor *cursor : qAsConst(previousBlock->m_cursors)) { + for (auto it = previousBlock->m_cursors.begin(); it != previousBlock->m_cursors.end();) { + auto cursor = *it; if (cursor->lineInBlock() == lastLineOfPreviousBlock) { cursor->m_line = 0; cursor->m_block = this; @@ -281,11 +275,14 @@ range->setValidityCheckRequired(); changedRanges.push_back(range); } + + // remove from previous block + it = previousBlock->m_cursors.erase(it); } else { - newPreviousCursors.insert(cursor); + // keep in previous block + ++it; } } - previousBlock->m_cursors = newPreviousCursors; // fixup the ranges that might be effected, because they moved from last line to this block // we might need to invalidate ranges or notify about their changes @@ -343,7 +340,7 @@ // move all cursors because of the unwrapped line // remember all ranges modified, optimize for the standard case of a few ranges QVarLengthArray changedRanges; - for (TextCursor *cursor : qAsConst(m_cursors)) { + for (TextCursor *cursor : m_cursors) { // skip cursors in lines in front of removed one if (cursor->lineInBlock() < line) { continue; @@ -407,7 +404,7 @@ // move all cursors on the line which has the text inserted // remember all ranges modified, optimize for the standard case of a few ranges QVarLengthArray changedRanges; - for (TextCursor *cursor : qAsConst(m_cursors)) { + for (TextCursor *cursor : m_cursors) { // skip cursors not on this line! if (cursor->lineInBlock() != line) { continue; @@ -485,7 +482,7 @@ // move all cursors on the line which has the text removed // remember all ranges modified, optimize for the standard case of a few ranges QVarLengthArray changedRanges; - for (TextCursor *cursor : qAsConst(m_cursors)) { + for (TextCursor *cursor : m_cursors) { // skip cursors not on this line! if (cursor->lineInBlock() != line) { continue; @@ -522,8 +519,8 @@ void TextBlock::debugPrint(int blockIndex) const { // print all blocks - for (int i = 0; i < m_lines.size(); ++i) - printf("%4d - %4d : %4d : '%s'\n", blockIndex, startLine() + i + for (size_t i = 0; i < m_lines.size(); ++i) + printf("%4d - %4lld : %4d : '%s'\n", blockIndex, (unsigned long long)startLine() + i , m_lines.at(i)->text().size(), qPrintable(m_lines.at(i)->text())); } @@ -537,23 +534,26 @@ // move lines newBlock->m_lines.reserve(linesOfNewBlock); - for (int i = fromLine; i < m_lines.size(); ++i) { - newBlock->m_lines.append(m_lines.at(i)); + for (size_t i = fromLine; i < m_lines.size(); ++i) { + newBlock->m_lines.push_back(m_lines.at(i)); } m_lines.resize(fromLine); // move cursors - QSet oldBlockSet; - for (TextCursor *cursor : qAsConst(m_cursors)) { + for (auto it = m_cursors.begin(); it != m_cursors.end();) { + auto cursor = *it; if (cursor->lineInBlock() >= fromLine) { cursor->m_line = cursor->lineInBlock() - fromLine; cursor->m_block = newBlock; + + // add to new, remove from current newBlock->m_cursors.insert(cursor); + it = m_cursors.erase(it); } else { - oldBlockSet.insert(cursor); + // keep in current + ++it; } } - m_cursors = oldBlockSet; // fix ALL ranges! const QList allRanges = m_uncachedRanges.toList() + m_cachedLineForRanges.keys(); @@ -570,17 +570,17 @@ void TextBlock::mergeBlock(TextBlock *targetBlock) { // move cursors, do this first, now still lines() count is correct for target - for (TextCursor *cursor : qAsConst(m_cursors)) { + for (TextCursor *cursor : m_cursors) { cursor->m_line = cursor->lineInBlock() + targetBlock->lines(); cursor->m_block = targetBlock; targetBlock->m_cursors.insert(cursor); } m_cursors.clear(); // move lines targetBlock->m_lines.reserve(targetBlock->lines() + lines()); - for (int i = 0; i < m_lines.size(); ++i) { - targetBlock->m_lines.append(m_lines.at(i)); + for (size_t i = 0; i < m_lines.size(); ++i) { + targetBlock->m_lines.push_back(m_lines.at(i)); } m_lines.clear(); @@ -596,10 +596,20 @@ void TextBlock::deleteBlockContent() { // kill cursors, if not belonging to a range - QSet copy = m_cursors; - for (TextCursor *cursor : qAsConst(copy)) { + // we can do in-place editing of the current set of cursors as + // we remove them before deleting + for (auto it = m_cursors.begin(); it != m_cursors.end();) { + auto cursor = *it; if (!cursor->kateRange()) { + // remove it and advance to next element + it = m_cursors.erase(it); + + // delete after cursor is gone from the set + // else the destructor will modify it! delete cursor; + } else { + // keep this cursor + ++it; } } @@ -610,14 +620,20 @@ void TextBlock::clearBlockContent(TextBlock *targetBlock) { // move cursors, if not belonging to a range - QSet copy = m_cursors; - for (TextCursor *cursor : qAsConst(copy)) { + // we can do in-place editing of the current set of cursors + for (auto it = m_cursors.begin(); it != m_cursors.end();) { + auto cursor = *it; if (!cursor->kateRange()) { cursor->m_column = 0; cursor->m_line = 0; cursor->m_block = targetBlock; targetBlock->m_cursors.insert(cursor); - m_cursors.remove(cursor); + + // remove it and advance to next element + it = m_cursors.erase(it); + } else { + // keep this cursor + ++it; } } @@ -628,8 +644,7 @@ void TextBlock::markModifiedLinesAsSaved() { // mark all modified lines as saved - for (int i = 0; i < m_lines.size(); ++i) { - TextLine textLine = m_lines[i]; + for (auto &textLine : m_lines) { if (textLine->markedAsModified()) { textLine->markAsSavedOnDisk(true); }