SparseState.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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.
  6. **/
  7. // Copyright 2011 by Neil Hodgson <neilh@scintilla.org>
  8. // The License.txt file describes the conditions under which this software may be distributed.
  9. #ifndef SPARSESTATE_H
  10. #define SPARSESTATE_H
  11. #ifdef SCI_NAMESPACE
  12. namespace Scintilla {
  13. #endif
  14. template <typename T>
  15. class SparseState {
  16. struct State {
  17. int position;
  18. T value;
  19. State(int position_, T value_) : position(position_), value(value_) {
  20. }
  21. inline bool operator<(const State &other) const {
  22. return position < other.position;
  23. }
  24. inline bool operator==(const State &other) const {
  25. return (position == other.position) && (value == other.value);
  26. }
  27. };
  28. int positionFirst;
  29. typedef std::vector<State> stateVector;
  30. stateVector states;
  31. typename stateVector::iterator Find(int position) {
  32. State searchValue(position, T());
  33. return std::lower_bound(states.begin(), states.end(), searchValue);
  34. }
  35. public:
  36. explicit SparseState(int positionFirst_=-1) {
  37. positionFirst = positionFirst_;
  38. }
  39. void Set(int position, T value) {
  40. Delete(position);
  41. if (states.empty() || (value != states[states.size()-1].value)) {
  42. states.push_back(State(position, value));
  43. }
  44. }
  45. T ValueAt(int position) {
  46. if (states.empty())
  47. return T();
  48. if (position < states[0].position)
  49. return T();
  50. typename stateVector::iterator low = Find(position);
  51. if (low == states.end()) {
  52. return states[states.size()-1].value;
  53. } else {
  54. if (low->position > position) {
  55. --low;
  56. }
  57. return low->value;
  58. }
  59. }
  60. bool Delete(int position) {
  61. typename stateVector::iterator low = Find(position);
  62. if (low != states.end()) {
  63. states.erase(low, states.end());
  64. return true;
  65. }
  66. return false;
  67. }
  68. size_t size() const {
  69. return states.size();
  70. }
  71. // Returns true if Merge caused a significant change
  72. bool Merge(const SparseState<T> &other, int ignoreAfter) {
  73. // Changes caused beyond ignoreAfter are not significant
  74. Delete(ignoreAfter+1);
  75. bool different = true;
  76. bool changed = false;
  77. typename stateVector::iterator low = Find(other.positionFirst);
  78. if (static_cast<size_t>(states.end() - low) == other.states.size()) {
  79. // Same number in other as after positionFirst in this
  80. different = !std::equal(low, states.end(), other.states.begin());
  81. }
  82. if (different) {
  83. if (low != states.end()) {
  84. states.erase(low, states.end());
  85. changed = true;
  86. }
  87. typename stateVector::const_iterator startOther = other.states.begin();
  88. if (!states.empty() && !other.states.empty() && states.back().value == startOther->value)
  89. ++startOther;
  90. if (startOther != other.states.end()) {
  91. states.insert(states.end(), startOther, other.states.end());
  92. changed = true;
  93. }
  94. }
  95. return changed;
  96. }
  97. };
  98. #ifdef SCI_NAMESPACE
  99. }
  100. #endif
  101. #endif