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());