| OLD | NEW |
| 1 #ifndef SkRecordPattern_DEFINED | 1 #ifndef SkRecordPattern_DEFINED |
| 2 #define SkRecordPattern_DEFINED | 2 #define SkRecordPattern_DEFINED |
| 3 | 3 |
| 4 #include "SkTLogic.h" | 4 #include "SkTLogic.h" |
| 5 | 5 |
| 6 namespace SkRecords { | 6 namespace SkRecords { |
| 7 | 7 |
| 8 // First, some matchers. These match a single command in the SkRecord, | 8 // First, some matchers. These match a single command in the SkRecord, |
| 9 // and may hang onto some data from it. If so, you can get the data by calling
.get(). | 9 // and may hang onto some data from it. If so, you can get the data by calling
.get(). |
| 10 | 10 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 template <typename A, typename B> | 78 template <typename A, typename B> |
| 79 struct Or { | 79 struct Or { |
| 80 template <typename T> | 80 template <typename T> |
| 81 bool operator()(T* ptr) { return A()(ptr) || B()(ptr); } | 81 bool operator()(T* ptr) { return A()(ptr) || B()(ptr); } |
| 82 }; | 82 }; |
| 83 | 83 |
| 84 // Matches if any of A, B or C does. Stores nothing. | 84 // Matches if any of A, B or C does. Stores nothing. |
| 85 template <typename A, typename B, typename C> | 85 template <typename A, typename B, typename C> |
| 86 struct Or3 : Or<A, Or<B, C> > {}; | 86 struct Or3 : Or<A, Or<B, C> > {}; |
| 87 | 87 |
| 88 // We'll use this to choose which implementation of Star suits each Matcher. | 88 // Star is a special matcher that greedily matches Matcher 0 or more times. Sto
res nothing. |
| 89 SK_CREATE_TYPE_DETECTOR(type); | 89 template <typename Matcher> |
| 90 | 90 struct Star { |
| 91 // Star is a special matcher that matches Matcher 0 or more times _greedily_ in
the SkRecord. | |
| 92 // This version stores nothing. It's enabled when Matcher stores nothing. | |
| 93 template <typename Matcher, typename = void> | |
| 94 class Star { | |
| 95 public: | |
| 96 void reset() {} | |
| 97 | |
| 98 template <typename T> | 91 template <typename T> |
| 99 bool operator()(T* ptr) { return Matcher()(ptr); } | 92 bool operator()(T* ptr) { return Matcher()(ptr); } |
| 100 }; | 93 }; |
| 101 | 94 |
| 102 // This version stores a list of matches. It's enabled if Matcher stores someth
ing. | |
| 103 template <typename Matcher> | |
| 104 class Star<Matcher, SK_WHEN(HasType_type<Matcher>, void)> { | |
| 105 public: | |
| 106 typedef SkTDArray<typename Matcher::type*> type; | |
| 107 type* get() { return &fMatches; } | |
| 108 | |
| 109 void reset() { fMatches.rewind(); } | |
| 110 | |
| 111 template <typename T> | |
| 112 bool operator()(T* ptr) { | |
| 113 Matcher matcher; | |
| 114 if (matcher(ptr)) { | |
| 115 fMatches.push(matcher.get()); | |
| 116 return true; | |
| 117 } | |
| 118 return false; | |
| 119 } | |
| 120 | |
| 121 private: | |
| 122 type fMatches; | |
| 123 }; | |
| 124 | |
| 125 | |
| 126 // Cons builds a list of Matchers. | 95 // Cons builds a list of Matchers. |
| 127 // It first matches Matcher (something from above), then Pattern (another Cons o
r Nil). | 96 // It first matches Matcher (something from above), then Pattern (another Cons o
r Nil). |
| 128 // | 97 // |
| 129 // This is the main entry point to pattern matching, and so provides a couple of
extra API bits: | 98 // This is the main entry point to pattern matching, and so provides a couple of
extra API bits: |
| 130 // - search scans through the record to look for matches; | 99 // - search scans through the record to look for matches; |
| 131 // - first, second, and third return the data stored by their respective matche
rs in the pattern. | 100 // - first, second, and third return the data stored by their respective matche
rs in the pattern. |
| 132 // | 101 // |
| 133 // These Cons build lists analogously to Lisp's "cons". See Pattern# for the "l
ist" equivalent. | 102 // These Cons build lists analogously to Lisp's "cons". See Pattern# for the "l
ist" equivalent. |
| 134 template <typename Matcher, typename Pattern> | 103 template <typename Matcher, typename Pattern> |
| 135 class Cons { | 104 class Cons { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 if (record->mutate<bool>(i, fHead)) { | 137 if (record->mutate<bool>(i, fHead)) { |
| 169 return i+1; | 138 return i+1; |
| 170 } | 139 } |
| 171 } | 140 } |
| 172 return 0; | 141 return 0; |
| 173 } | 142 } |
| 174 | 143 |
| 175 // If head is a Star, walk i until it doesn't match. | 144 // If head is a Star, walk i until it doesn't match. |
| 176 template <typename T> | 145 template <typename T> |
| 177 unsigned matchHead(Star<T>*, SkRecord* record, unsigned i) { | 146 unsigned matchHead(Star<T>*, SkRecord* record, unsigned i) { |
| 178 fHead.reset(); | |
| 179 while (i < record->count()) { | 147 while (i < record->count()) { |
| 180 if (!record->mutate<bool>(i, fHead)) { | 148 if (!record->mutate<bool>(i, fHead)) { |
| 181 return i; | 149 return i; |
| 182 } | 150 } |
| 183 i++; | 151 i++; |
| 184 } | 152 } |
| 185 return 0; | 153 return 0; |
| 186 } | 154 } |
| 187 | 155 |
| 188 Matcher fHead; | 156 Matcher fHead; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 206 | 174 |
| 207 template <typename A, typename B> | 175 template <typename A, typename B> |
| 208 struct Pattern2 : Cons<A, Pattern1<B> > {}; | 176 struct Pattern2 : Cons<A, Pattern1<B> > {}; |
| 209 | 177 |
| 210 template <typename A, typename B, typename C> | 178 template <typename A, typename B, typename C> |
| 211 struct Pattern3 : Cons<A, Pattern2<B, C> > {}; | 179 struct Pattern3 : Cons<A, Pattern2<B, C> > {}; |
| 212 | 180 |
| 213 } // namespace SkRecords | 181 } // namespace SkRecords |
| 214 | 182 |
| 215 #endif//SkRecordPattern_DEFINED | 183 #endif//SkRecordPattern_DEFINED |
| OLD | NEW |