diff options
author | Neil <nyamatongwe@gmail.com> | 2018-04-21 08:43:03 +1000 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2018-04-21 08:43:03 +1000 |
commit | 8634c0958c532e7d219e649353e1f1a74d52da1b (patch) | |
tree | 91352944c8b5c727a385426431d2e62f3301f6ad /src/Document.cxx | |
parent | f00008fa5a49722171c5b288f988a64443122115 (diff) | |
download | scintilla-mirror-8634c0958c532e7d219e649353e1f1a74d52da1b.tar.gz |
Tighten definition of regular expression iterators so they are noexcept and
define all the standard member functions. This cascades to all methods called
by the iterators, affecting Document, CellBuffer, Partitioning, SplitVector and
UTF-8 and DBCS functions.
Other trivial functions declared noexcept.
Diffstat (limited to 'src/Document.cxx')
-rw-r--r-- | src/Document.cxx | 165 |
1 files changed, 96 insertions, 69 deletions
diff --git a/src/Document.cxx b/src/Document.cxx index b0efee5e7..127b6872a 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -387,7 +387,7 @@ Sci_Position SCI_METHOD Document::LineFromPosition(Sci_Position pos) const { return cb.LineFromPosition(pos); } -Sci::Line Document::SciLineFromPosition(Sci::Position pos) const { +Sci::Line Document::SciLineFromPosition(Sci::Position pos) const noexcept { // Avoids casting in callers for this very common function return cb.LineFromPosition(pos); } @@ -582,13 +582,13 @@ int Document::LenChar(Sci::Position pos) { else return widthCharBytes; } else if (dbcsCodePage) { - return IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1; + return IsDBCSLeadByteNoExcept(cb.CharAt(pos)) ? 2 : 1; } else { return 1; } } -bool Document::InGoodUTF8(Sci::Position pos, Sci::Position &start, Sci::Position &end) const { +bool Document::InGoodUTF8(Sci::Position pos, Sci::Position &start, Sci::Position &end) const noexcept { Sci::Position trail = pos; while ((trail>0) && (pos-trail < UTF8MaxBytes) && UTF8IsTrailByte(cb.UCharAt(trail-1))) trail--; @@ -661,12 +661,12 @@ Sci::Position Document::MovePositionOutsideChar(Sci::Position pos, Sci::Position // Step back until a non-lead-byte is found. Sci::Position posCheck = pos; - while ((posCheck > posStartLine) && IsDBCSLeadByte(cb.CharAt(posCheck-1))) + while ((posCheck > posStartLine) && IsDBCSLeadByteNoExcept(cb.CharAt(posCheck-1))) posCheck--; // Check from known start of character. while (posCheck < pos) { - const int mbsize = IsDBCSLeadByte(cb.CharAt(posCheck)) ? 2 : 1; + const int mbsize = IsDBCSLeadByteNoExcept(cb.CharAt(posCheck)) ? 2 : 1; if (posCheck + mbsize == pos) { return pos; } else if (posCheck + mbsize > pos) { @@ -687,13 +687,13 @@ Sci::Position Document::MovePositionOutsideChar(Sci::Position pos, Sci::Position // NextPosition moves between valid positions - it can not handle a position in the middle of a // multi-byte character. It is used to iterate through text more efficiently than MovePositionOutsideChar. // A \r\n pair is treated as two characters. -Sci::Position Document::NextPosition(Sci::Position pos, int moveDir) const { +Sci::Position Document::NextPosition(Sci::Position pos, int moveDir) const noexcept { // If out of range, just return minimum/maximum value. const int increment = (moveDir > 0) ? 1 : -1; if (pos + increment <= 0) return 0; - if (pos + increment >= Length()) - return Length(); + if (pos + increment >= cb.Length()) + return cb.Length(); if (dbcsCodePage) { if (SC_CP_UTF8 == dbcsCodePage) { @@ -731,25 +731,25 @@ Sci::Position Document::NextPosition(Sci::Position pos, int moveDir) const { } } else { if (moveDir > 0) { - const int mbsize = IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1; + const int mbsize = IsDBCSLeadByteNoExcept(cb.CharAt(pos)) ? 2 : 1; pos += mbsize; - if (pos > Length()) - pos = Length(); + if (pos > cb.Length()) + pos = cb.Length(); } else { // Anchor DBCS calculations at start of line because start of line can // not be a DBCS trail byte. - const Sci::Position posStartLine = LineStart(LineFromPosition(pos)); + const Sci::Position posStartLine = cb.LineStart(cb.LineFromPosition(pos)); // See http://msdn.microsoft.com/en-us/library/cc194792%28v=MSDN.10%29.aspx // http://msdn.microsoft.com/en-us/library/cc194790.aspx if ((pos - 1) <= posStartLine) { return pos - 1; - } else if (IsDBCSLeadByte(cb.CharAt(pos - 1))) { + } else if (IsDBCSLeadByteNoExcept(cb.CharAt(pos - 1))) { // Must actually be trail byte return pos - 2; } else { // Otherwise, step back until a non-lead-byte is found. Sci::Position posTemp = pos - 1; - while (posStartLine <= --posTemp && IsDBCSLeadByte(cb.CharAt(posTemp))) + while (posStartLine <= --posTemp && IsDBCSLeadByteNoExcept(cb.CharAt(posTemp))) ; // Now posTemp+1 must point to the beginning of a character, // so figure out whether we went back an even or an odd @@ -765,7 +765,7 @@ Sci::Position Document::NextPosition(Sci::Position pos, int moveDir) const { return pos; } -bool Document::NextCharacter(Sci::Position &pos, int moveDir) const { +bool Document::NextCharacter(Sci::Position &pos, int moveDir) const noexcept { // Returns true if pos changed Sci::Position posNext = NextPosition(pos, moveDir); if (posNext == pos) { @@ -798,7 +798,7 @@ Document::CharacterExtracted Document::CharacterAfter(Sci::Position position) co return CharacterExtracted(UnicodeFromUTF8(charBytes), utf8status & UTF8MaskWidth); } } else { - if (IsDBCSLeadByte(leadByte) && ((position + 1) < Length())) { + if (IsDBCSLeadByteNoExcept(leadByte) && ((position + 1) < Length())) { return CharacterExtracted::DBCS(leadByte, cb.UCharAt(position + 1)); } else { return CharacterExtracted(leadByte, 1); @@ -912,7 +912,7 @@ int SCI_METHOD Document::GetCharacterAndWidth(Sci_Position position, Sci_Positio } } } else { - if (IsDBCSLeadByte(leadByte)) { + if (IsDBCSLeadByteNoExcept(leadByte)) { bytesInCharacter = 2; character = (leadByte << 8) | cb.UCharAt(position+1); } else { @@ -933,6 +933,12 @@ int SCI_METHOD Document::CodePage() const { } bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const { + // Used by lexers so must match IDocument method exactly + return IsDBCSLeadByteNoExcept(ch); +} + +bool Document::IsDBCSLeadByteNoExcept(char ch) const noexcept { + // Used inside core Scintilla // Byte ranges found in Wikipedia articles with relevant search strings in each case const unsigned char uch = static_cast<unsigned char>(ch); switch (dbcsCodePage) { @@ -960,7 +966,7 @@ bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const { return false; } -static inline bool IsSpaceOrTab(int ch) { +static inline bool IsSpaceOrTab(int ch) noexcept { return ch == ' ' || ch == '\t'; } @@ -996,7 +1002,7 @@ int Document::SafeSegment(const char *text, int length, int lengthSegment) const if (dbcsCodePage == SC_CP_UTF8) { j += UTF8BytesOfLead[ch]; } else if (dbcsCodePage) { - j += IsDBCSLeadByte(ch) ? 2 : 1; + j += IsDBCSLeadByteNoExcept(ch) ? 2 : 1; } else { j++; } @@ -1306,7 +1312,7 @@ void Document::DelCharBack(Sci::Position pos) { } } -static Sci::Position NextTab(Sci::Position pos, Sci::Position tabSize) { +static Sci::Position NextTab(Sci::Position pos, Sci::Position tabSize) noexcept { return ((pos / tabSize) + 1) * tabSize; } @@ -1818,7 +1824,7 @@ void Document::SetCaseFolder(CaseFolder *pcf_) { pcf.reset(pcf_); } -Document::CharacterExtracted Document::ExtractCharacter(Sci::Position position) const { +Document::CharacterExtracted Document::ExtractCharacter(Sci::Position position) const noexcept { const unsigned char leadByte = cb.UCharAt(position); if (UTF8IsAscii(leadByte)) { // Common case: ASCII character @@ -1894,8 +1900,8 @@ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, con std::vector<char> searchThing((lengthFind+1) * UTF8MaxBytes * maxFoldingExpansion + 1); const size_t lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind); - char bytes[UTF8MaxBytes + 1]; - char folded[UTF8MaxBytes * maxFoldingExpansion + 1]; + char bytes[UTF8MaxBytes + 1] = ""; + char folded[UTF8MaxBytes * maxFoldingExpansion + 1] = ""; while (forward ? (pos < endPos) : (pos >= endPos)) { int widthFirstCharacter = 0; Sci::Position posIndexDocument = pos; @@ -1955,7 +1961,7 @@ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, con (indexSearch < lenSearch)) { char bytes[maxBytesCharacter + 1]; bytes[0] = cb.CharAt(pos + indexDocument); - const Sci::Position widthChar = IsDBCSLeadByte(bytes[0]) ? 2 : 1; + const Sci::Position widthChar = IsDBCSLeadByteNoExcept(bytes[0]) ? 2 : 1; if (widthChar == 2) bytes[1] = cb.CharAt(pos + indexDocument + 1); if ((pos + indexDocument + widthChar) > limitPos) @@ -2295,7 +2301,7 @@ void Document::NotifyModified(DocModification mh) { } // Used for word part navigation. -static bool IsASCIIPunctuationCharacter(unsigned int ch) { +static bool IsASCIIPunctuationCharacter(unsigned int ch) noexcept { switch (ch) { case '!': case '"': @@ -2429,7 +2435,7 @@ Sci::Position Document::WordPartRight(Sci::Position pos) const { return pos; } -static bool IsLineEndChar(char c) { +static bool IsLineEndChar(char c) noexcept { return (c == '\n' || c == '\r'); } @@ -2446,7 +2452,7 @@ Sci::Position Document::ExtendStyleRange(Sci::Position pos, int delta, bool sing return pos; } -static char BraceOpposite(char ch) { +static char BraceOpposite(char ch) noexcept { switch (ch) { case '(': return ')'; @@ -2506,9 +2512,11 @@ Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxRe class BuiltinRegex : public RegexSearchBase { public: explicit BuiltinRegex(CharClassify *charClassTable) : search(charClassTable) {} - - ~BuiltinRegex() override { - } + BuiltinRegex(const BuiltinRegex &) = delete; + BuiltinRegex(BuiltinRegex &&) = delete; + BuiltinRegex &operator=(const BuiltinRegex &) = delete; + BuiltinRegex &operator=(BuiltinRegex &&) = delete; + ~BuiltinRegex() override = default; Sci::Position FindText(Document *doc, Sci::Position minPos, Sci::Position maxPos, const char *s, bool caseSensitive, bool word, bool wordStart, int flags, @@ -2569,14 +2577,18 @@ class DocumentIndexer : public CharacterIndexer { Document *pdoc; Sci::Position end; public: - DocumentIndexer(Document *pdoc_, Sci::Position end_) : + DocumentIndexer(Document *pdoc_, Sci::Position end_) noexcept : pdoc(pdoc_), end(end_) { } - ~DocumentIndexer() override { - } + DocumentIndexer(const DocumentIndexer &) = delete; + DocumentIndexer(DocumentIndexer &&) = delete; + DocumentIndexer &operator=(const DocumentIndexer &) = delete; + DocumentIndexer &operator=(DocumentIndexer &&) = delete; - char CharAt(Sci::Position index) const override { + ~DocumentIndexer() override = default; + + char CharAt(Sci::Position index) const noexcept override { if (index < 0 || index >= end) return 0; else @@ -2596,45 +2608,53 @@ public: const Document *doc; Sci::Position position; - ByteIterator(const Document *doc_ = 0, Sci::Position position_ = 0) : doc(doc_), position(position_) { + + ByteIterator(const Document *doc_=nullptr, Sci::Position position_=0) noexcept : + doc(doc_), position(position_) { } ByteIterator(const ByteIterator &other) noexcept { doc = other.doc; position = other.position; } - ByteIterator &operator=(const ByteIterator &other) { + ByteIterator(ByteIterator &&other) noexcept { + doc = other.doc; + position = other.position; + } + ByteIterator &operator=(const ByteIterator &other) noexcept { if (this != &other) { doc = other.doc; position = other.position; } return *this; } - char operator*() const { + ByteIterator &operator=(ByteIterator &&) noexcept = default; + ~ByteIterator() = default; + char operator*() const noexcept { return doc->CharAt(position); } - ByteIterator &operator++() { + ByteIterator &operator++() noexcept { position++; return *this; } - ByteIterator operator++(int) { + ByteIterator operator++(int) noexcept { ByteIterator retVal(*this); position++; return retVal; } - ByteIterator &operator--() { + ByteIterator &operator--() noexcept { position--; return *this; } - bool operator==(const ByteIterator &other) const { + bool operator==(const ByteIterator &other) const noexcept { return doc == other.doc && position == other.position; } - bool operator!=(const ByteIterator &other) const { + bool operator!=(const ByteIterator &other) const noexcept { return doc != other.doc || position != other.position; } - Sci::Position Pos() const { + Sci::Position Pos() const noexcept { return position; } - Sci::Position PosRoundUp() const { + Sci::Position PosRoundUp() const noexcept { return position; } }; @@ -2671,15 +2691,15 @@ public: typedef wchar_t* pointer; typedef wchar_t& reference; - UTF8Iterator(const Document *doc_ = 0, Sci::Position position_ = 0) : - doc(doc_), position(position_), characterIndex(0), lenBytes(0), lenCharacters(0) { + UTF8Iterator(const Document *doc_=nullptr, Sci::Position position_=0) noexcept : + doc(doc_), position(position_), characterIndex(0), lenBytes(0), lenCharacters(0), buffered{} { buffered[0] = 0; buffered[1] = 0; if (doc) { ReadCharacter(); } } - UTF8Iterator(const UTF8Iterator &other) { + UTF8Iterator(const UTF8Iterator &other) noexcept : buffered{} { doc = other.doc; position = other.position; characterIndex = other.characterIndex; @@ -2688,7 +2708,8 @@ public: buffered[0] = other.buffered[0]; buffered[1] = other.buffered[1]; } - UTF8Iterator &operator=(const UTF8Iterator &other) { + UTF8Iterator(UTF8Iterator &&other) noexcept = default; + UTF8Iterator &operator=(const UTF8Iterator &other) noexcept { if (this != &other) { doc = other.doc; position = other.position; @@ -2700,11 +2721,13 @@ public: } return *this; } - wchar_t operator*() const { + UTF8Iterator &operator=(UTF8Iterator &&) noexcept = default; + ~UTF8Iterator() = default; + wchar_t operator*() const noexcept { assert(lenCharacters != 0); return buffered[characterIndex]; } - UTF8Iterator &operator++() { + UTF8Iterator &operator++() noexcept { if ((characterIndex + 1) < (lenCharacters)) { characterIndex++; } else { @@ -2714,7 +2737,7 @@ public: } return *this; } - UTF8Iterator operator++(int) { + UTF8Iterator operator++(int) noexcept { UTF8Iterator retVal(*this); if ((characterIndex + 1) < (lenCharacters)) { characterIndex++; @@ -2725,7 +2748,7 @@ public: } return retVal; } - UTF8Iterator &operator--() { + UTF8Iterator &operator--() noexcept { if (characterIndex) { characterIndex--; } else { @@ -2735,29 +2758,29 @@ public: } return *this; } - bool operator==(const UTF8Iterator &other) const { + bool operator==(const UTF8Iterator &other) const noexcept { // Only test the determining fields, not the character widths and values derived from this return doc == other.doc && position == other.position && characterIndex == other.characterIndex; } - bool operator!=(const UTF8Iterator &other) const { + bool operator!=(const UTF8Iterator &other) const noexcept { // Only test the determining fields, not the character widths and values derived from this return doc != other.doc || position != other.position || characterIndex != other.characterIndex; } - Sci::Position Pos() const { + Sci::Position Pos() const noexcept { return position; } - Sci::Position PosRoundUp() const { + Sci::Position PosRoundUp() const noexcept { if (characterIndex) return position + lenBytes; // Force to end of character else return position; } private: - void ReadCharacter() { + void ReadCharacter() noexcept { const Document::CharacterExtracted charExtracted = doc->ExtractCharacter(position); lenBytes = charExtracted.widthBytes; if (charExtracted.character == unicodeReplacementChar) { @@ -2783,46 +2806,50 @@ public: typedef wchar_t* pointer; typedef wchar_t& reference; - UTF8Iterator(const Document *doc_=0, Sci::Position position_=0) : doc(doc_), position(position_) { + UTF8Iterator(const Document *doc_=nullptr, Sci::Position position_=0) noexcept : + doc(doc_), position(position_) { } UTF8Iterator(const UTF8Iterator &other) noexcept { doc = other.doc; position = other.position; } - UTF8Iterator &operator=(const UTF8Iterator &other) { + UTF8Iterator(UTF8Iterator &&other) noexcept = default; + UTF8Iterator &operator=(const UTF8Iterator &other) noexcept { if (this != &other) { doc = other.doc; position = other.position; } return *this; } - wchar_t operator*() const { - Document::CharacterExtracted charExtracted = doc->ExtractCharacter(position); + UTF8Iterator &operator=(UTF8Iterator &&) noexcept = default; + ~UTF8Iterator() = default; + wchar_t operator*() const noexcept { + const Document::CharacterExtracted charExtracted = doc->ExtractCharacter(position); return charExtracted.character; } - UTF8Iterator &operator++() { + UTF8Iterator &operator++() noexcept { position = doc->NextPosition(position, 1); return *this; } - UTF8Iterator operator++(int) { + UTF8Iterator operator++(int) noexcept { UTF8Iterator retVal(*this); position = doc->NextPosition(position, 1); return retVal; } - UTF8Iterator &operator--() { + UTF8Iterator &operator--() noexcept { position = doc->NextPosition(position, -1); return *this; } - bool operator==(const UTF8Iterator &other) const { + bool operator==(const UTF8Iterator &other) const noexcept { return doc == other.doc && position == other.position; } - bool operator!=(const UTF8Iterator &other) const { + bool operator!=(const UTF8Iterator &other) const noexcept { return doc != other.doc || position != other.position; } - Sci::Position Pos() const { + Sci::Position Pos() const noexcept { return position; } - Sci::Position PosRoundUp() const { + Sci::Position PosRoundUp() const noexcept { return position; } }; @@ -2893,7 +2920,7 @@ bool MatchOnLines(const Document *doc, const Regex ®exp, const RESearchRange return matched; } -Sci::Position Cxx11RegexFindText(Document *doc, Sci::Position minPos, Sci::Position maxPos, const char *s, +Sci::Position Cxx11RegexFindText(const Document *doc, Sci::Position minPos, Sci::Position maxPos, const char *s, bool caseSensitive, Sci::Position *length, RESearch &search) { const RESearchRange resr(doc, minPos, maxPos); try { |