1
// Scintilla source code edit control
2
/** @file SparseState.h
3
** Hold lexer state that may change rarely.
4
** This is often per-line state such as whether a particular type of section has been entered.
5
** A state continues until it is changed.
7
// Copyright 2011 by Neil Hodgson <neilh@scintilla.org>
8
// The License.txt file describes the conditions under which this software may be distributed.
22
State(int position_, T value_) : position(position_), value(value_) {
24
inline bool operator<(const State &other) const {
25
return position < other.position;
27
inline bool operator==(const State &other) const {
28
return (position == other.position) && (value == other.value);
32
typedef std::vector<State> stateVector;
35
typename stateVector::iterator Find(int position) {
36
State searchValue(position, T());
37
return std::lower_bound(states.begin(), states.end(), searchValue);
41
explicit SparseState(int positionFirst_=-1) {
42
positionFirst = positionFirst_;
44
void Set(int position, T value) {
46
if (states.empty() || (value != states[states.size()-1].value)) {
47
states.push_back(State(position, value));
50
T ValueAt(int position) {
53
if (position < states[0].position)
55
typename stateVector::iterator low = Find(position);
56
if (low == states.end()) {
57
return states[states.size()-1].value;
59
if (low->position > position) {
65
bool Delete(int position) {
66
typename stateVector::iterator low = Find(position);
67
if (low != states.end()) {
68
states.erase(low, states.end());
77
// Returns true if Merge caused a significant change
78
bool Merge(const SparseState<T> &other, int ignoreAfter) {
79
// Changes caused beyond ignoreAfter are not significant
80
Delete(ignoreAfter+1);
82
bool different = true;
84
typename stateVector::iterator low = Find(other.positionFirst);
85
if (static_cast<size_t>(states.end() - low) == other.states.size()) {
86
// Same number in other as after positionFirst in this
87
different = !std::equal(low, states.end(), other.states.begin());
90
if (low != states.end()) {
91
states.erase(low, states.end());
94
typename stateVector::const_iterator startOther = other.states.begin();
95
if (!states.empty() && !other.states.empty() && states.back().value == startOther->value)
97
if (startOther != other.states.end()) {
98
states.insert(states.end(), startOther, other.states.end());