diff options
Diffstat (limited to 'src/Decoration.cxx')
-rw-r--r-- | src/Decoration.cxx | 120 |
1 files changed, 56 insertions, 64 deletions
diff --git a/src/Decoration.cxx b/src/Decoration.cxx index 2a6060c52..f5f82832f 100644 --- a/src/Decoration.cxx +++ b/src/Decoration.cxx @@ -11,6 +11,7 @@ #include <cstdarg> #include <stdexcept> +#include <vector> #include <algorithm> #include <memory> @@ -27,7 +28,7 @@ using namespace Scintilla; #endif -Decoration::Decoration(int indicator_) : indicator(indicator_), next(0) { +Decoration::Decoration(int indicator_) : indicator(indicator_) { } Decoration::~Decoration() { @@ -37,76 +38,48 @@ bool Decoration::Empty() const { return (rs.Runs() == 1) && (rs.AllSameAs(0)); } -DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0), - lengthDocument(0), root(0), clickNotified(false) { +DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(nullptr), + lengthDocument(0), clickNotified(false) { } DecorationList::~DecorationList() { - Decoration *deco = root; - while (deco) { - Decoration *decoNext = deco->Next(); - delete deco; - deco = decoNext; - } - root = 0; - current = 0; + current = nullptr; } Decoration *DecorationList::DecorationFromIndicator(int indicator) { - for (Decoration *deco=root; deco; deco = deco->Next()) { + for (const std::unique_ptr<Decoration> &deco : decorationList) { if (deco->Indicator() == indicator) { - return deco; + return deco.get(); } } - return 0; + return nullptr; } Decoration *DecorationList::Create(int indicator, int length) { currentIndicator = indicator; - Decoration *decoNew = new Decoration(indicator); + std::unique_ptr<Decoration> decoNew(new Decoration(indicator)); decoNew->rs.InsertSpace(0, length); - Decoration *decoPrev = 0; - Decoration *deco = root; + std::vector<std::unique_ptr<Decoration>>::iterator it = std::lower_bound( + decorationList.begin(), decorationList.end(), decoNew, + [](const std::unique_ptr<Decoration> &a, const std::unique_ptr<Decoration> &b) { + return a->Indicator() < b->Indicator(); + }); + std::vector<std::unique_ptr<Decoration>>::iterator itAdded = + decorationList.insert(it, std::move(decoNew)); - while (deco && (deco->Indicator() < indicator)) { - decoPrev = deco; - deco = deco->Next(); - } - if (decoPrev == 0) { - decoNew->next = root; - root = decoNew; - } else { - decoNew->next = deco; - decoPrev->next = decoNew; - } - return decoNew; + SetView(); + + return itAdded->get(); } void DecorationList::Delete(int indicator) { - Decoration *decoToDelete = 0; - if (root) { - if (root->Indicator() == indicator) { - decoToDelete = root; - root = root->Next(); - } else { - Decoration *deco = root; - while (deco && deco->Next() && !decoToDelete) { - // decoNext ensures no warning from MSVC Code Analysis - Decoration *decoNext = deco->Next(); - if (decoNext && deco->Next()->Indicator() == indicator) { - decoToDelete = decoNext; - deco->next = decoToDelete->Next(); - } else { - deco = deco->Next(); - } - } - } - } - if (decoToDelete) { - delete decoToDelete; - current = 0; - } + decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(), + [=](const std::unique_ptr<Decoration> &deco) { + return deco->Indicator() == indicator; + }), decorationList.end()); + current = nullptr; + SetView(); } void DecorationList::SetCurrentIndicator(int indicator) { @@ -136,7 +109,7 @@ bool DecorationList::FillRange(int &position, int value, int &fillLength) { void DecorationList::InsertSpace(int position, int insertLength) { const bool atEnd = position == lengthDocument; lengthDocument += insertLength; - for (Decoration *deco=root; deco; deco = deco->Next()) { + for (const std::unique_ptr<Decoration> &deco : decorationList) { deco->rs.InsertSpace(position, insertLength); if (atEnd) { deco->rs.FillRange(position, 0, insertLength); @@ -146,28 +119,47 @@ void DecorationList::InsertSpace(int position, int insertLength) { void DecorationList::DeleteRange(int position, int deleteLength) { lengthDocument -= deleteLength; - Decoration *deco; - for (deco=root; deco; deco = deco->Next()) { + for (const std::unique_ptr<Decoration> &deco : decorationList) { deco->rs.DeleteRange(position, deleteLength); } DeleteAnyEmpty(); + if (decorationList.size() != decorationView.size()) { + // One or more empty decorations deleted so update view. + current = nullptr; + SetView(); + } +} + +void DecorationList::DeleteLexerDecorations() { + decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(), + [=](const std::unique_ptr<Decoration> &deco) { + return deco->Indicator() < INDIC_CONTAINER; + }), decorationList.end()); + current = nullptr; + SetView(); } void DecorationList::DeleteAnyEmpty() { - Decoration *deco = root; - while (deco) { - if ((lengthDocument == 0) || deco->Empty()) { - Delete(deco->Indicator()); - deco = root; - } else { - deco = deco->Next(); - } + if (lengthDocument == 0) { + decorationList.clear(); + } else { + decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(), + [=](const std::unique_ptr<Decoration> &deco) { + return deco->Empty(); + }), decorationList.end()); + } +} + +void DecorationList::SetView() { + decorationView.clear(); + for (const std::unique_ptr<Decoration> &deco : decorationList) { + decorationView.push_back(deco.get()); } } int DecorationList::AllOnFor(int position) const { int mask = 0; - for (Decoration *deco=root; deco; deco = deco->Next()) { + for (const std::unique_ptr<Decoration> &deco : decorationList) { if (deco->rs.ValueAt(position)) { if (deco->Indicator() < INDIC_IME) { mask |= 1 << deco->Indicator(); |