xref: /MusicPlayer2/scintilla/lexlib/SparseState.h (revision 8af74909132ed5e696cb05b6689ae4baf14c1c96)
1*8af74909SZhong Yang // Scintilla source code edit control
2*8af74909SZhong Yang /** @file SparseState.h
3*8af74909SZhong Yang  ** Hold lexer state that may change rarely.
4*8af74909SZhong Yang  ** This is often per-line state such as whether a particular type of section has been entered.
5*8af74909SZhong Yang  ** A state continues until it is changed.
6*8af74909SZhong Yang  **/
7*8af74909SZhong Yang // Copyright 2011 by Neil Hodgson <[email protected]>
8*8af74909SZhong Yang // The License.txt file describes the conditions under which this software may be distributed.
9*8af74909SZhong Yang 
10*8af74909SZhong Yang #ifndef SPARSESTATE_H
11*8af74909SZhong Yang #define SPARSESTATE_H
12*8af74909SZhong Yang 
13*8af74909SZhong Yang namespace Scintilla {
14*8af74909SZhong Yang 
15*8af74909SZhong Yang template <typename T>
16*8af74909SZhong Yang class SparseState {
17*8af74909SZhong Yang 	struct State {
18*8af74909SZhong Yang 		Sci_Position position;
19*8af74909SZhong Yang 		T value;
StateState20*8af74909SZhong Yang 		constexpr State(Sci_Position position_, T value_) noexcept : position(position_), value(value_) {
21*8af74909SZhong Yang 		}
22*8af74909SZhong Yang 		inline bool operator<(const State &other) const noexcept {
23*8af74909SZhong Yang 			return position < other.position;
24*8af74909SZhong Yang 		}
25*8af74909SZhong Yang 		inline bool operator==(const State &other) const noexcept {
26*8af74909SZhong Yang 			return (position == other.position) && (value == other.value);
27*8af74909SZhong Yang 		}
28*8af74909SZhong Yang 	};
29*8af74909SZhong Yang 	Sci_Position positionFirst;
30*8af74909SZhong Yang 	typedef std::vector<State> stateVector;
31*8af74909SZhong Yang 	stateVector states;
32*8af74909SZhong Yang 
Find(Sci_Position position)33*8af74909SZhong Yang 	typename stateVector::iterator Find(Sci_Position position) {
34*8af74909SZhong Yang 		const State searchValue(position, T());
35*8af74909SZhong Yang 		return std::lower_bound(states.begin(), states.end(), searchValue);
36*8af74909SZhong Yang 	}
37*8af74909SZhong Yang 
38*8af74909SZhong Yang public:
39*8af74909SZhong Yang 	explicit SparseState(Sci_Position positionFirst_=-1) {
40*8af74909SZhong Yang 		positionFirst = positionFirst_;
41*8af74909SZhong Yang 	}
Set(Sci_Position position,T value)42*8af74909SZhong Yang 	void Set(Sci_Position position, T value) {
43*8af74909SZhong Yang 		Delete(position);
44*8af74909SZhong Yang 		if (states.empty() || (value != states[states.size()-1].value)) {
45*8af74909SZhong Yang 			states.push_back(State(position, value));
46*8af74909SZhong Yang 		}
47*8af74909SZhong Yang 	}
ValueAt(Sci_Position position)48*8af74909SZhong Yang 	T ValueAt(Sci_Position position) {
49*8af74909SZhong Yang 		if (states.empty())
50*8af74909SZhong Yang 			return T();
51*8af74909SZhong Yang 		if (position < states[0].position)
52*8af74909SZhong Yang 			return T();
53*8af74909SZhong Yang 		typename stateVector::iterator low = Find(position);
54*8af74909SZhong Yang 		if (low == states.end()) {
55*8af74909SZhong Yang 			return states[states.size()-1].value;
56*8af74909SZhong Yang 		} else {
57*8af74909SZhong Yang 			if (low->position > position) {
58*8af74909SZhong Yang 				--low;
59*8af74909SZhong Yang 			}
60*8af74909SZhong Yang 			return low->value;
61*8af74909SZhong Yang 		}
62*8af74909SZhong Yang 	}
Delete(Sci_Position position)63*8af74909SZhong Yang 	bool Delete(Sci_Position position) {
64*8af74909SZhong Yang 		typename stateVector::iterator low = Find(position);
65*8af74909SZhong Yang 		if (low != states.end()) {
66*8af74909SZhong Yang 			states.erase(low, states.end());
67*8af74909SZhong Yang 			return true;
68*8af74909SZhong Yang 		}
69*8af74909SZhong Yang 		return false;
70*8af74909SZhong Yang 	}
size()71*8af74909SZhong Yang 	size_t size() const {
72*8af74909SZhong Yang 		return states.size();
73*8af74909SZhong Yang 	}
74*8af74909SZhong Yang 
75*8af74909SZhong Yang 	// Returns true if Merge caused a significant change
Merge(const SparseState<T> & other,Sci_Position ignoreAfter)76*8af74909SZhong Yang 	bool Merge(const SparseState<T> &other, Sci_Position ignoreAfter) {
77*8af74909SZhong Yang 		// Changes caused beyond ignoreAfter are not significant
78*8af74909SZhong Yang 		Delete(ignoreAfter+1);
79*8af74909SZhong Yang 
80*8af74909SZhong Yang 		bool different = true;
81*8af74909SZhong Yang 		bool changed = false;
82*8af74909SZhong Yang 		typename stateVector::iterator low = Find(other.positionFirst);
83*8af74909SZhong Yang 		if (static_cast<size_t>(states.end() - low) == other.states.size()) {
84*8af74909SZhong Yang 			// Same number in other as after positionFirst in this
85*8af74909SZhong Yang 			different = !std::equal(low, states.end(), other.states.begin());
86*8af74909SZhong Yang 		}
87*8af74909SZhong Yang 		if (different) {
88*8af74909SZhong Yang 			if (low != states.end()) {
89*8af74909SZhong Yang 				states.erase(low, states.end());
90*8af74909SZhong Yang 				changed = true;
91*8af74909SZhong Yang 			}
92*8af74909SZhong Yang 			typename stateVector::const_iterator startOther = other.states.begin();
93*8af74909SZhong Yang 			if (!states.empty() && !other.states.empty() && states.back().value == startOther->value)
94*8af74909SZhong Yang 				++startOther;
95*8af74909SZhong Yang 			if (startOther != other.states.end()) {
96*8af74909SZhong Yang 				states.insert(states.end(), startOther, other.states.end());
97*8af74909SZhong Yang 				changed = true;
98*8af74909SZhong Yang 			}
99*8af74909SZhong Yang 		}
100*8af74909SZhong Yang 		return changed;
101*8af74909SZhong Yang 	}
102*8af74909SZhong Yang };
103*8af74909SZhong Yang 
104*8af74909SZhong Yang }
105*8af74909SZhong Yang 
106*8af74909SZhong Yang #endif
107