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