diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2017-01-23 11:20:20 -0500 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2017-01-23 11:20:20 -0500 |
commit | d19c329607d611901540e5d3d746c1a94a0b6210 (patch) | |
tree | 05c845164e3f3df9dc38668a0278d15d0caaacfe /lib | |
parent | 71064d07ad84b1d31471298f8cc5b497cbe85505 (diff) | |
download | verbly-d19c329607d611901540e5d3d746c1a94a0b6210.tar.gz verbly-d19c329607d611901540e5d3d746c1a94a0b6210.tar.bz2 verbly-d19c329607d611901540e5d3d746c1a94a0b6210.zip |
Fixed normalization of negative join filters
Previously, negative join filters were folded in with positive joins by AND/ORing them together and negating the negative joins. Checking for the existence of something that doesn't match a condition is different from checking for the non-existence of something that does match a condition, so now normalization considers positive and negative join filters to be distinct classes of filters and does not fold them together. Also made some whitespace changes.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/filter.cpp | 375 |
1 files changed, 192 insertions, 183 deletions
diff --git a/lib/filter.cpp b/lib/filter.cpp index 959fa05..1af7314 100644 --- a/lib/filter.cpp +++ b/lib/filter.cpp | |||
@@ -14,19 +14,19 @@ namespace verbly { | |||
14 | filter::filter(const filter& other) | 14 | filter::filter(const filter& other) |
15 | { | 15 | { |
16 | type_ = other.type_; | 16 | type_ = other.type_; |
17 | 17 | ||
18 | switch (type_) | 18 | switch (type_) |
19 | { | 19 | { |
20 | case type::empty: | 20 | case type::empty: |
21 | { | 21 | { |
22 | break; | 22 | break; |
23 | } | 23 | } |
24 | 24 | ||
25 | case type::singleton: | 25 | case type::singleton: |
26 | { | 26 | { |
27 | new(&singleton_.filterField) field(other.singleton_.filterField); | 27 | new(&singleton_.filterField) field(other.singleton_.filterField); |
28 | singleton_.filterType = other.singleton_.filterType; | 28 | singleton_.filterType = other.singleton_.filterType; |
29 | 29 | ||
30 | switch (singleton_.filterType) | 30 | switch (singleton_.filterType) |
31 | { | 31 | { |
32 | case comparison::int_equals: | 32 | case comparison::int_equals: |
@@ -37,74 +37,74 @@ namespace verbly { | |||
37 | case comparison::int_is_less_than: | 37 | case comparison::int_is_less_than: |
38 | { | 38 | { |
39 | singleton_.intValue = other.singleton_.intValue; | 39 | singleton_.intValue = other.singleton_.intValue; |
40 | 40 | ||
41 | break; | 41 | break; |
42 | } | 42 | } |
43 | 43 | ||
44 | case comparison::boolean_equals: | 44 | case comparison::boolean_equals: |
45 | { | 45 | { |
46 | singleton_.boolValue = other.singleton_.boolValue; | 46 | singleton_.boolValue = other.singleton_.boolValue; |
47 | 47 | ||
48 | break; | 48 | break; |
49 | } | 49 | } |
50 | 50 | ||
51 | case comparison::string_equals: | 51 | case comparison::string_equals: |
52 | case comparison::string_does_not_equal: | 52 | case comparison::string_does_not_equal: |
53 | case comparison::string_is_like: | 53 | case comparison::string_is_like: |
54 | case comparison::string_is_not_like: | 54 | case comparison::string_is_not_like: |
55 | { | 55 | { |
56 | new(&singleton_.stringValue) std::string(other.singleton_.stringValue); | 56 | new(&singleton_.stringValue) std::string(other.singleton_.stringValue); |
57 | 57 | ||
58 | break; | 58 | break; |
59 | } | 59 | } |
60 | 60 | ||
61 | case comparison::is_null: | 61 | case comparison::is_null: |
62 | case comparison::is_not_null: | 62 | case comparison::is_not_null: |
63 | { | 63 | { |
64 | break; | 64 | break; |
65 | } | 65 | } |
66 | 66 | ||
67 | case comparison::matches: | 67 | case comparison::matches: |
68 | case comparison::does_not_match: | 68 | case comparison::does_not_match: |
69 | case comparison::hierarchally_matches: | 69 | case comparison::hierarchally_matches: |
70 | case comparison::does_not_hierarchally_match: | 70 | case comparison::does_not_hierarchally_match: |
71 | { | 71 | { |
72 | new(&singleton_.join) std::unique_ptr<filter>(new filter(*other.singleton_.join)); | 72 | new(&singleton_.join) std::unique_ptr<filter>(new filter(*other.singleton_.join)); |
73 | 73 | ||
74 | break; | 74 | break; |
75 | } | 75 | } |
76 | } | 76 | } |
77 | 77 | ||
78 | break; | 78 | break; |
79 | } | 79 | } |
80 | 80 | ||
81 | case type::group: | 81 | case type::group: |
82 | { | 82 | { |
83 | new(&group_.children) std::list<filter>(other.group_.children); | 83 | new(&group_.children) std::list<filter>(other.group_.children); |
84 | group_.orlogic = other.group_.orlogic; | 84 | group_.orlogic = other.group_.orlogic; |
85 | 85 | ||
86 | break; | 86 | break; |
87 | } | 87 | } |
88 | } | 88 | } |
89 | } | 89 | } |
90 | 90 | ||
91 | filter::filter(filter&& other) : filter() | 91 | filter::filter(filter&& other) : filter() |
92 | { | 92 | { |
93 | swap(*this, other); | 93 | swap(*this, other); |
94 | } | 94 | } |
95 | 95 | ||
96 | filter& filter::operator=(filter other) | 96 | filter& filter::operator=(filter other) |
97 | { | 97 | { |
98 | swap(*this, other); | 98 | swap(*this, other); |
99 | 99 | ||
100 | return *this; | 100 | return *this; |
101 | } | 101 | } |
102 | 102 | ||
103 | void swap(filter& first, filter& second) | 103 | void swap(filter& first, filter& second) |
104 | { | 104 | { |
105 | using type = filter::type; | 105 | using type = filter::type; |
106 | using comparison = filter::comparison; | 106 | using comparison = filter::comparison; |
107 | 107 | ||
108 | type tempType = first.type_; | 108 | type tempType = first.type_; |
109 | field tempField; | 109 | field tempField; |
110 | comparison tempComparison; | 110 | comparison tempComparison; |
@@ -114,19 +114,19 @@ namespace verbly { | |||
114 | bool tempBoolValue; | 114 | bool tempBoolValue; |
115 | std::list<filter> tempChildren; | 115 | std::list<filter> tempChildren; |
116 | bool tempOrlogic; | 116 | bool tempOrlogic; |
117 | 117 | ||
118 | switch (tempType) | 118 | switch (tempType) |
119 | { | 119 | { |
120 | case type::empty: | 120 | case type::empty: |
121 | { | 121 | { |
122 | break; | 122 | break; |
123 | } | 123 | } |
124 | 124 | ||
125 | case type::singleton: | 125 | case type::singleton: |
126 | { | 126 | { |
127 | tempField = std::move(first.singleton_.filterField); | 127 | tempField = std::move(first.singleton_.filterField); |
128 | tempComparison = first.singleton_.filterType; | 128 | tempComparison = first.singleton_.filterType; |
129 | 129 | ||
130 | switch (tempComparison) | 130 | switch (tempComparison) |
131 | { | 131 | { |
132 | case comparison::int_equals: | 132 | case comparison::int_equals: |
@@ -137,72 +137,72 @@ namespace verbly { | |||
137 | case comparison::int_is_less_than: | 137 | case comparison::int_is_less_than: |
138 | { | 138 | { |
139 | tempIntValue = first.singleton_.intValue; | 139 | tempIntValue = first.singleton_.intValue; |
140 | 140 | ||
141 | break; | 141 | break; |
142 | } | 142 | } |
143 | 143 | ||
144 | case comparison::boolean_equals: | 144 | case comparison::boolean_equals: |
145 | { | 145 | { |
146 | tempBoolValue = first.singleton_.boolValue; | 146 | tempBoolValue = first.singleton_.boolValue; |
147 | 147 | ||
148 | break; | 148 | break; |
149 | } | 149 | } |
150 | 150 | ||
151 | case comparison::string_equals: | 151 | case comparison::string_equals: |
152 | case comparison::string_does_not_equal: | 152 | case comparison::string_does_not_equal: |
153 | case comparison::string_is_like: | 153 | case comparison::string_is_like: |
154 | case comparison::string_is_not_like: | 154 | case comparison::string_is_not_like: |
155 | { | 155 | { |
156 | tempStringValue = std::move(first.singleton_.stringValue); | 156 | tempStringValue = std::move(first.singleton_.stringValue); |
157 | 157 | ||
158 | break; | 158 | break; |
159 | } | 159 | } |
160 | 160 | ||
161 | case comparison::is_null: | 161 | case comparison::is_null: |
162 | case comparison::is_not_null: | 162 | case comparison::is_not_null: |
163 | { | 163 | { |
164 | break; | 164 | break; |
165 | } | 165 | } |
166 | 166 | ||
167 | case comparison::matches: | 167 | case comparison::matches: |
168 | case comparison::does_not_match: | 168 | case comparison::does_not_match: |
169 | case comparison::hierarchally_matches: | 169 | case comparison::hierarchally_matches: |
170 | case comparison::does_not_hierarchally_match: | 170 | case comparison::does_not_hierarchally_match: |
171 | { | 171 | { |
172 | tempJoin = std::move(first.singleton_.join); | 172 | tempJoin = std::move(first.singleton_.join); |
173 | 173 | ||
174 | break; | 174 | break; |
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
178 | break; | 178 | break; |
179 | } | 179 | } |
180 | 180 | ||
181 | case type::group: | 181 | case type::group: |
182 | { | 182 | { |
183 | tempChildren = std::move(first.group_.children); | 183 | tempChildren = std::move(first.group_.children); |
184 | tempOrlogic = first.group_.orlogic; | 184 | tempOrlogic = first.group_.orlogic; |
185 | 185 | ||
186 | break; | 186 | break; |
187 | } | 187 | } |
188 | } | 188 | } |
189 | 189 | ||
190 | first.~filter(); | 190 | first.~filter(); |
191 | 191 | ||
192 | first.type_ = second.type_; | 192 | first.type_ = second.type_; |
193 | 193 | ||
194 | switch (first.type_) | 194 | switch (first.type_) |
195 | { | 195 | { |
196 | case type::empty: | 196 | case type::empty: |
197 | { | 197 | { |
198 | break; | 198 | break; |
199 | } | 199 | } |
200 | 200 | ||
201 | case type::singleton: | 201 | case type::singleton: |
202 | { | 202 | { |
203 | new(&first.singleton_.filterField) field(std::move(second.singleton_.filterField)); | 203 | new(&first.singleton_.filterField) field(std::move(second.singleton_.filterField)); |
204 | first.singleton_.filterType = second.singleton_.filterType; | 204 | first.singleton_.filterType = second.singleton_.filterType; |
205 | 205 | ||
206 | switch (first.singleton_.filterType) | 206 | switch (first.singleton_.filterType) |
207 | { | 207 | { |
208 | case comparison::int_equals: | 208 | case comparison::int_equals: |
@@ -213,72 +213,72 @@ namespace verbly { | |||
213 | case comparison::int_is_less_than: | 213 | case comparison::int_is_less_than: |
214 | { | 214 | { |
215 | first.singleton_.intValue = second.singleton_.intValue; | 215 | first.singleton_.intValue = second.singleton_.intValue; |
216 | 216 | ||
217 | break; | 217 | break; |
218 | } | 218 | } |
219 | 219 | ||
220 | case comparison::boolean_equals: | 220 | case comparison::boolean_equals: |
221 | { | 221 | { |
222 | first.singleton_.boolValue = second.singleton_.boolValue; | 222 | first.singleton_.boolValue = second.singleton_.boolValue; |
223 | 223 | ||
224 | break; | 224 | break; |
225 | } | 225 | } |
226 | 226 | ||
227 | case comparison::string_equals: | 227 | case comparison::string_equals: |
228 | case comparison::string_does_not_equal: | 228 | case comparison::string_does_not_equal: |
229 | case comparison::string_is_like: | 229 | case comparison::string_is_like: |
230 | case comparison::string_is_not_like: | 230 | case comparison::string_is_not_like: |
231 | { | 231 | { |
232 | new(&first.singleton_.stringValue) std::string(std::move(second.singleton_.stringValue)); | 232 | new(&first.singleton_.stringValue) std::string(std::move(second.singleton_.stringValue)); |
233 | 233 | ||
234 | break; | 234 | break; |
235 | } | 235 | } |
236 | 236 | ||
237 | case comparison::is_null: | 237 | case comparison::is_null: |
238 | case comparison::is_not_null: | 238 | case comparison::is_not_null: |
239 | { | 239 | { |
240 | break; | 240 | break; |
241 | } | 241 | } |
242 | 242 | ||
243 | case comparison::matches: | 243 | case comparison::matches: |
244 | case comparison::does_not_match: | 244 | case comparison::does_not_match: |
245 | case comparison::hierarchally_matches: | 245 | case comparison::hierarchally_matches: |
246 | case comparison::does_not_hierarchally_match: | 246 | case comparison::does_not_hierarchally_match: |
247 | { | 247 | { |
248 | new(&first.singleton_.join) std::unique_ptr<filter>(std::move(second.singleton_.join)); | 248 | new(&first.singleton_.join) std::unique_ptr<filter>(std::move(second.singleton_.join)); |
249 | 249 | ||
250 | break; | 250 | break; |
251 | } | 251 | } |
252 | } | 252 | } |
253 | 253 | ||
254 | break; | 254 | break; |
255 | } | 255 | } |
256 | 256 | ||
257 | case type::group: | 257 | case type::group: |
258 | { | 258 | { |
259 | new(&first.group_.children) std::list<filter>(std::move(second.group_.children)); | 259 | new(&first.group_.children) std::list<filter>(std::move(second.group_.children)); |
260 | first.group_.orlogic = second.group_.orlogic; | 260 | first.group_.orlogic = second.group_.orlogic; |
261 | 261 | ||
262 | break; | 262 | break; |
263 | } | 263 | } |
264 | } | 264 | } |
265 | 265 | ||
266 | second.~filter(); | 266 | second.~filter(); |
267 | 267 | ||
268 | second.type_ = tempType; | 268 | second.type_ = tempType; |
269 | 269 | ||
270 | switch (second.type_) | 270 | switch (second.type_) |
271 | { | 271 | { |
272 | case type::empty: | 272 | case type::empty: |
273 | { | 273 | { |
274 | break; | 274 | break; |
275 | } | 275 | } |
276 | 276 | ||
277 | case type::singleton: | 277 | case type::singleton: |
278 | { | 278 | { |
279 | new(&second.singleton_.filterField) field(std::move(tempField)); | 279 | new(&second.singleton_.filterField) field(std::move(tempField)); |
280 | second.singleton_.filterType = tempComparison; | 280 | second.singleton_.filterType = tempComparison; |
281 | 281 | ||
282 | switch (second.singleton_.filterType) | 282 | switch (second.singleton_.filterType) |
283 | { | 283 | { |
284 | case comparison::int_equals: | 284 | case comparison::int_equals: |
@@ -289,57 +289,57 @@ namespace verbly { | |||
289 | case comparison::int_is_less_than: | 289 | case comparison::int_is_less_than: |
290 | { | 290 | { |
291 | second.singleton_.intValue = tempIntValue; | 291 | second.singleton_.intValue = tempIntValue; |
292 | 292 | ||
293 | break; | 293 | break; |
294 | } | 294 | } |
295 | 295 | ||
296 | case comparison::boolean_equals: | 296 | case comparison::boolean_equals: |
297 | { | 297 | { |
298 | second.singleton_.boolValue = tempBoolValue; | 298 | second.singleton_.boolValue = tempBoolValue; |
299 | 299 | ||
300 | break; | 300 | break; |
301 | } | 301 | } |
302 | 302 | ||
303 | case comparison::string_equals: | 303 | case comparison::string_equals: |
304 | case comparison::string_does_not_equal: | 304 | case comparison::string_does_not_equal: |
305 | case comparison::string_is_like: | 305 | case comparison::string_is_like: |
306 | case comparison::string_is_not_like: | 306 | case comparison::string_is_not_like: |
307 | { | 307 | { |
308 | new(&second.singleton_.stringValue) std::string(std::move(tempStringValue)); | 308 | new(&second.singleton_.stringValue) std::string(std::move(tempStringValue)); |
309 | 309 | ||
310 | break; | 310 | break; |
311 | } | 311 | } |
312 | 312 | ||
313 | case comparison::is_null: | 313 | case comparison::is_null: |
314 | case comparison::is_not_null: | 314 | case comparison::is_not_null: |
315 | { | 315 | { |
316 | break; | 316 | break; |
317 | } | 317 | } |
318 | 318 | ||
319 | case comparison::matches: | 319 | case comparison::matches: |
320 | case comparison::does_not_match: | 320 | case comparison::does_not_match: |
321 | case comparison::hierarchally_matches: | 321 | case comparison::hierarchally_matches: |
322 | case comparison::does_not_hierarchally_match: | 322 | case comparison::does_not_hierarchally_match: |
323 | { | 323 | { |
324 | new(&second.singleton_.join) std::unique_ptr<filter>(std::move(tempJoin)); | 324 | new(&second.singleton_.join) std::unique_ptr<filter>(std::move(tempJoin)); |
325 | 325 | ||
326 | break; | 326 | break; |
327 | } | 327 | } |
328 | } | 328 | } |
329 | 329 | ||
330 | break; | 330 | break; |
331 | } | 331 | } |
332 | 332 | ||
333 | case type::group: | 333 | case type::group: |
334 | { | 334 | { |
335 | new(&second.group_.children) std::list<filter>(std::move(tempChildren)); | 335 | new(&second.group_.children) std::list<filter>(std::move(tempChildren)); |
336 | second.group_.orlogic = tempOrlogic; | 336 | second.group_.orlogic = tempOrlogic; |
337 | 337 | ||
338 | break; | 338 | break; |
339 | } | 339 | } |
340 | } | 340 | } |
341 | } | 341 | } |
342 | 342 | ||
343 | filter::~filter() | 343 | filter::~filter() |
344 | { | 344 | { |
345 | switch (type_) | 345 | switch (type_) |
@@ -348,11 +348,11 @@ namespace verbly { | |||
348 | { | 348 | { |
349 | break; | 349 | break; |
350 | } | 350 | } |
351 | 351 | ||
352 | case type::singleton: | 352 | case type::singleton: |
353 | { | 353 | { |
354 | singleton_.filterField.~field(); | 354 | singleton_.filterField.~field(); |
355 | 355 | ||
356 | switch (singleton_.filterType) | 356 | switch (singleton_.filterType) |
357 | { | 357 | { |
358 | case comparison::int_equals: | 358 | case comparison::int_equals: |
@@ -367,50 +367,50 @@ namespace verbly { | |||
367 | { | 367 | { |
368 | break; | 368 | break; |
369 | } | 369 | } |
370 | 370 | ||
371 | case comparison::string_equals: | 371 | case comparison::string_equals: |
372 | case comparison::string_does_not_equal: | 372 | case comparison::string_does_not_equal: |
373 | case comparison::string_is_like: | 373 | case comparison::string_is_like: |
374 | case comparison::string_is_not_like: | 374 | case comparison::string_is_not_like: |
375 | { | 375 | { |
376 | using string_type = std::string; | 376 | using string_type = std::string; |
377 | 377 | ||
378 | singleton_.stringValue.~string_type(); | 378 | singleton_.stringValue.~string_type(); |
379 | 379 | ||
380 | break; | 380 | break; |
381 | } | 381 | } |
382 | 382 | ||
383 | case comparison::matches: | 383 | case comparison::matches: |
384 | case comparison::does_not_match: | 384 | case comparison::does_not_match: |
385 | case comparison::hierarchally_matches: | 385 | case comparison::hierarchally_matches: |
386 | case comparison::does_not_hierarchally_match: | 386 | case comparison::does_not_hierarchally_match: |
387 | { | 387 | { |
388 | using ptr_type = std::unique_ptr<filter>; | 388 | using ptr_type = std::unique_ptr<filter>; |
389 | 389 | ||
390 | singleton_.join.~ptr_type(); | 390 | singleton_.join.~ptr_type(); |
391 | 391 | ||
392 | break; | 392 | break; |
393 | } | 393 | } |
394 | } | 394 | } |
395 | 395 | ||
396 | break; | 396 | break; |
397 | } | 397 | } |
398 | 398 | ||
399 | case type::group: | 399 | case type::group: |
400 | { | 400 | { |
401 | using list_type = std::list<filter>; | 401 | using list_type = std::list<filter>; |
402 | 402 | ||
403 | group_.children.~list_type(); | 403 | group_.children.~list_type(); |
404 | 404 | ||
405 | break; | 405 | break; |
406 | } | 406 | } |
407 | } | 407 | } |
408 | } | 408 | } |
409 | 409 | ||
410 | filter::filter() | 410 | filter::filter() |
411 | { | 411 | { |
412 | } | 412 | } |
413 | 413 | ||
414 | filter::filter( | 414 | filter::filter( |
415 | field filterField, | 415 | field filterField, |
416 | comparison filterType, | 416 | comparison filterType, |
@@ -431,10 +431,10 @@ namespace verbly { | |||
431 | new(&singleton_.filterField) field(std::move(filterField)); | 431 | new(&singleton_.filterField) field(std::move(filterField)); |
432 | singleton_.filterType = filterType; | 432 | singleton_.filterType = filterType; |
433 | singleton_.intValue = filterValue; | 433 | singleton_.intValue = filterValue; |
434 | 434 | ||
435 | break; | 435 | break; |
436 | } | 436 | } |
437 | 437 | ||
438 | case comparison::boolean_equals: | 438 | case comparison::boolean_equals: |
439 | case comparison::string_equals: | 439 | case comparison::string_equals: |
440 | case comparison::string_does_not_equal: | 440 | case comparison::string_does_not_equal: |
@@ -454,7 +454,7 @@ namespace verbly { | |||
454 | throw std::domain_error("Cannot match a non-integer field against an integer value"); | 454 | throw std::domain_error("Cannot match a non-integer field against an integer value"); |
455 | } | 455 | } |
456 | } | 456 | } |
457 | 457 | ||
458 | filter::filter( | 458 | filter::filter( |
459 | field filterField, | 459 | field filterField, |
460 | comparison filterType, | 460 | comparison filterType, |
@@ -473,10 +473,10 @@ namespace verbly { | |||
473 | new(&singleton_.filterField) field(std::move(filterField)); | 473 | new(&singleton_.filterField) field(std::move(filterField)); |
474 | singleton_.filterType = filterType; | 474 | singleton_.filterType = filterType; |
475 | new(&singleton_.stringValue) std::string(std::move(filterValue)); | 475 | new(&singleton_.stringValue) std::string(std::move(filterValue)); |
476 | 476 | ||
477 | break; | 477 | break; |
478 | } | 478 | } |
479 | 479 | ||
480 | case comparison::int_equals: | 480 | case comparison::int_equals: |
481 | case comparison::int_does_not_equal: | 481 | case comparison::int_does_not_equal: |
482 | case comparison::int_is_at_least: | 482 | case comparison::int_is_at_least: |
@@ -498,7 +498,7 @@ namespace verbly { | |||
498 | throw std::domain_error("Cannot match a non-string field against an string value"); | 498 | throw std::domain_error("Cannot match a non-string field against an string value"); |
499 | } | 499 | } |
500 | } | 500 | } |
501 | 501 | ||
502 | filter::filter( | 502 | filter::filter( |
503 | field filterField, | 503 | field filterField, |
504 | comparison filterType, | 504 | comparison filterType, |
@@ -514,10 +514,10 @@ namespace verbly { | |||
514 | new(&singleton_.filterField) field(std::move(filterField)); | 514 | new(&singleton_.filterField) field(std::move(filterField)); |
515 | singleton_.filterType = filterType; | 515 | singleton_.filterType = filterType; |
516 | singleton_.boolValue = filterValue; | 516 | singleton_.boolValue = filterValue; |
517 | 517 | ||
518 | break; | 518 | break; |
519 | } | 519 | } |
520 | 520 | ||
521 | case comparison::string_equals: | 521 | case comparison::string_equals: |
522 | case comparison::string_does_not_equal: | 522 | case comparison::string_does_not_equal: |
523 | case comparison::string_is_like: | 523 | case comparison::string_is_like: |
@@ -542,7 +542,7 @@ namespace verbly { | |||
542 | throw std::domain_error("Cannot match a non-boolean field against a boolean value"); | 542 | throw std::domain_error("Cannot match a non-boolean field against a boolean value"); |
543 | } | 543 | } |
544 | } | 544 | } |
545 | 545 | ||
546 | filter::filter( | 546 | filter::filter( |
547 | field filterField, | 547 | field filterField, |
548 | comparison filterType) : | 548 | comparison filterType) : |
@@ -557,10 +557,10 @@ namespace verbly { | |||
557 | { | 557 | { |
558 | new(&singleton_.filterField) field(std::move(filterField)); | 558 | new(&singleton_.filterField) field(std::move(filterField)); |
559 | singleton_.filterType = filterType; | 559 | singleton_.filterType = filterType; |
560 | 560 | ||
561 | break; | 561 | break; |
562 | } | 562 | } |
563 | 563 | ||
564 | case comparison::string_equals: | 564 | case comparison::string_equals: |
565 | case comparison::string_does_not_equal: | 565 | case comparison::string_does_not_equal: |
566 | case comparison::string_is_like: | 566 | case comparison::string_is_like: |
@@ -584,7 +584,7 @@ namespace verbly { | |||
584 | throw std::domain_error("Cannot check nullity/non-nullity of non-nullable field"); | 584 | throw std::domain_error("Cannot check nullity/non-nullity of non-nullable field"); |
585 | } | 585 | } |
586 | } | 586 | } |
587 | 587 | ||
588 | filter::filter( | 588 | filter::filter( |
589 | field joinOn, | 589 | field joinOn, |
590 | comparison filterType, | 590 | comparison filterType, |
@@ -604,10 +604,10 @@ namespace verbly { | |||
604 | new(&singleton_.filterField) field(std::move(joinOn)); | 604 | new(&singleton_.filterField) field(std::move(joinOn)); |
605 | singleton_.filterType = filterType; | 605 | singleton_.filterType = filterType; |
606 | new(&singleton_.join) std::unique_ptr<filter>(new filter(joinCondition.normalize(singleton_.filterField.getJoinObject()))); | 606 | new(&singleton_.join) std::unique_ptr<filter>(new filter(joinCondition.normalize(singleton_.filterField.getJoinObject()))); |
607 | 607 | ||
608 | break; | 608 | break; |
609 | } | 609 | } |
610 | 610 | ||
611 | case comparison::int_equals: | 611 | case comparison::int_equals: |
612 | case comparison::int_does_not_equal: | 612 | case comparison::int_does_not_equal: |
613 | case comparison::int_is_at_least: | 613 | case comparison::int_is_at_least: |
@@ -627,10 +627,10 @@ namespace verbly { | |||
627 | throw std::invalid_argument("Incorrect constructor for given comparison"); | 627 | throw std::invalid_argument("Incorrect constructor for given comparison"); |
628 | } | 628 | } |
629 | } | 629 | } |
630 | 630 | ||
631 | break; | 631 | break; |
632 | } | 632 | } |
633 | 633 | ||
634 | case field::type::hierarchal_join: | 634 | case field::type::hierarchal_join: |
635 | { | 635 | { |
636 | switch (filterType) | 636 | switch (filterType) |
@@ -641,10 +641,10 @@ namespace verbly { | |||
641 | new(&singleton_.filterField) field(std::move(joinOn)); | 641 | new(&singleton_.filterField) field(std::move(joinOn)); |
642 | singleton_.filterType = filterType; | 642 | singleton_.filterType = filterType; |
643 | new(&singleton_.join) std::unique_ptr<filter>(new filter(joinCondition.normalize(singleton_.filterField.getObject()))); | 643 | new(&singleton_.join) std::unique_ptr<filter>(new filter(joinCondition.normalize(singleton_.filterField.getObject()))); |
644 | 644 | ||
645 | break; | 645 | break; |
646 | } | 646 | } |
647 | 647 | ||
648 | case comparison::int_equals: | 648 | case comparison::int_equals: |
649 | case comparison::int_does_not_equal: | 649 | case comparison::int_does_not_equal: |
650 | case comparison::int_is_at_least: | 650 | case comparison::int_is_at_least: |
@@ -664,10 +664,10 @@ namespace verbly { | |||
664 | throw std::invalid_argument("Incorrect constructor for given comparison"); | 664 | throw std::invalid_argument("Incorrect constructor for given comparison"); |
665 | } | 665 | } |
666 | } | 666 | } |
667 | 667 | ||
668 | break; | 668 | break; |
669 | } | 669 | } |
670 | 670 | ||
671 | case field::type::undefined: | 671 | case field::type::undefined: |
672 | case field::type::string: | 672 | case field::type::string: |
673 | case field::type::integer: | 673 | case field::type::integer: |
@@ -677,7 +677,7 @@ namespace verbly { | |||
677 | } | 677 | } |
678 | } | 678 | } |
679 | } | 679 | } |
680 | 680 | ||
681 | field filter::getField() const | 681 | field filter::getField() const |
682 | { | 682 | { |
683 | if (type_ == type::singleton) | 683 | if (type_ == type::singleton) |
@@ -687,7 +687,7 @@ namespace verbly { | |||
687 | throw std::domain_error("This filter does not have a field"); | 687 | throw std::domain_error("This filter does not have a field"); |
688 | } | 688 | } |
689 | } | 689 | } |
690 | 690 | ||
691 | filter::comparison filter::getComparison() const | 691 | filter::comparison filter::getComparison() const |
692 | { | 692 | { |
693 | if (type_ == type::singleton) | 693 | if (type_ == type::singleton) |
@@ -697,7 +697,7 @@ namespace verbly { | |||
697 | throw std::domain_error("This filter does not have a comparison"); | 697 | throw std::domain_error("This filter does not have a comparison"); |
698 | } | 698 | } |
699 | } | 699 | } |
700 | 700 | ||
701 | filter filter::getJoinCondition() const | 701 | filter filter::getJoinCondition() const |
702 | { | 702 | { |
703 | if (type_ == type::singleton) | 703 | if (type_ == type::singleton) |
@@ -711,7 +711,7 @@ namespace verbly { | |||
711 | { | 711 | { |
712 | return *singleton_.join; | 712 | return *singleton_.join; |
713 | } | 713 | } |
714 | 714 | ||
715 | case comparison::string_equals: | 715 | case comparison::string_equals: |
716 | case comparison::string_does_not_equal: | 716 | case comparison::string_does_not_equal: |
717 | case comparison::string_is_like: | 717 | case comparison::string_is_like: |
@@ -733,7 +733,7 @@ namespace verbly { | |||
733 | throw std::domain_error("This filter does not have a join condition"); | 733 | throw std::domain_error("This filter does not have a join condition"); |
734 | } | 734 | } |
735 | } | 735 | } |
736 | 736 | ||
737 | std::string filter::getStringArgument() const | 737 | std::string filter::getStringArgument() const |
738 | { | 738 | { |
739 | if (type_ == type::singleton) | 739 | if (type_ == type::singleton) |
@@ -747,7 +747,7 @@ namespace verbly { | |||
747 | { | 747 | { |
748 | return singleton_.stringValue; | 748 | return singleton_.stringValue; |
749 | } | 749 | } |
750 | 750 | ||
751 | case comparison::int_equals: | 751 | case comparison::int_equals: |
752 | case comparison::int_does_not_equal: | 752 | case comparison::int_does_not_equal: |
753 | case comparison::int_is_at_least: | 753 | case comparison::int_is_at_least: |
@@ -769,7 +769,7 @@ namespace verbly { | |||
769 | throw std::domain_error("This filter does not have a string argument"); | 769 | throw std::domain_error("This filter does not have a string argument"); |
770 | } | 770 | } |
771 | } | 771 | } |
772 | 772 | ||
773 | int filter::getIntegerArgument() const | 773 | int filter::getIntegerArgument() const |
774 | { | 774 | { |
775 | if (type_ == type::singleton) | 775 | if (type_ == type::singleton) |
@@ -785,7 +785,7 @@ namespace verbly { | |||
785 | { | 785 | { |
786 | return singleton_.intValue; | 786 | return singleton_.intValue; |
787 | } | 787 | } |
788 | 788 | ||
789 | case comparison::string_equals: | 789 | case comparison::string_equals: |
790 | case comparison::string_does_not_equal: | 790 | case comparison::string_does_not_equal: |
791 | case comparison::string_is_like: | 791 | case comparison::string_is_like: |
@@ -805,7 +805,7 @@ namespace verbly { | |||
805 | throw std::domain_error("This filter does not have an integer argument"); | 805 | throw std::domain_error("This filter does not have an integer argument"); |
806 | } | 806 | } |
807 | } | 807 | } |
808 | 808 | ||
809 | bool filter::getBooleanArgument() const | 809 | bool filter::getBooleanArgument() const |
810 | { | 810 | { |
811 | if ((type_ == type::singleton) && (singleton_.filterType == comparison::boolean_equals)) | 811 | if ((type_ == type::singleton) && (singleton_.filterType == comparison::boolean_equals)) |
@@ -815,13 +815,13 @@ namespace verbly { | |||
815 | throw std::domain_error("This filter does not have a boolean argument"); | 815 | throw std::domain_error("This filter does not have a boolean argument"); |
816 | } | 816 | } |
817 | } | 817 | } |
818 | 818 | ||
819 | filter::filter(bool orlogic) : type_(type::group) | 819 | filter::filter(bool orlogic) : type_(type::group) |
820 | { | 820 | { |
821 | new(&group_.children) std::list<filter>(); | 821 | new(&group_.children) std::list<filter>(); |
822 | group_.orlogic = orlogic; | 822 | group_.orlogic = orlogic; |
823 | } | 823 | } |
824 | 824 | ||
825 | bool filter::getOrlogic() const | 825 | bool filter::getOrlogic() const |
826 | { | 826 | { |
827 | if (type_ == type::group) | 827 | if (type_ == type::group) |
@@ -831,27 +831,27 @@ namespace verbly { | |||
831 | throw std::domain_error("This filter is not a group filter"); | 831 | throw std::domain_error("This filter is not a group filter"); |
832 | } | 832 | } |
833 | } | 833 | } |
834 | 834 | ||
835 | filter filter::operator+(filter condition) const | 835 | filter filter::operator+(filter condition) const |
836 | { | 836 | { |
837 | filter result(*this); | 837 | filter result(*this); |
838 | result += std::move(condition); | 838 | result += std::move(condition); |
839 | 839 | ||
840 | return result; | 840 | return result; |
841 | } | 841 | } |
842 | 842 | ||
843 | filter& filter::operator+=(filter condition) | 843 | filter& filter::operator+=(filter condition) |
844 | { | 844 | { |
845 | if (type_ == type::group) | 845 | if (type_ == type::group) |
846 | { | 846 | { |
847 | group_.children.push_back(std::move(condition)); | 847 | group_.children.push_back(std::move(condition)); |
848 | 848 | ||
849 | return *this; | 849 | return *this; |
850 | } else { | 850 | } else { |
851 | throw std::domain_error("Children can only be added to group filters"); | 851 | throw std::domain_error("Children can only be added to group filters"); |
852 | } | 852 | } |
853 | } | 853 | } |
854 | 854 | ||
855 | filter::const_iterator filter::begin() const | 855 | filter::const_iterator filter::begin() const |
856 | { | 856 | { |
857 | if (type_ == type::group) | 857 | if (type_ == type::group) |
@@ -861,7 +861,7 @@ namespace verbly { | |||
861 | throw std::domain_error("This filter has no children"); | 861 | throw std::domain_error("This filter has no children"); |
862 | } | 862 | } |
863 | } | 863 | } |
864 | 864 | ||
865 | filter::const_iterator filter::end() const | 865 | filter::const_iterator filter::end() const |
866 | { | 866 | { |
867 | if (type_ == type::group) | 867 | if (type_ == type::group) |
@@ -880,7 +880,7 @@ namespace verbly { | |||
880 | { | 880 | { |
881 | return {}; | 881 | return {}; |
882 | } | 882 | } |
883 | 883 | ||
884 | case type::singleton: | 884 | case type::singleton: |
885 | { | 885 | { |
886 | switch (singleton_.filterType) | 886 | switch (singleton_.filterType) |
@@ -889,113 +889,113 @@ namespace verbly { | |||
889 | { | 889 | { |
890 | return filter(singleton_.filterField, comparison::int_does_not_equal, singleton_.intValue); | 890 | return filter(singleton_.filterField, comparison::int_does_not_equal, singleton_.intValue); |
891 | } | 891 | } |
892 | 892 | ||
893 | case comparison::int_does_not_equal: | 893 | case comparison::int_does_not_equal: |
894 | { | 894 | { |
895 | return filter(singleton_.filterField, comparison::int_equals, singleton_.intValue); | 895 | return filter(singleton_.filterField, comparison::int_equals, singleton_.intValue); |
896 | } | 896 | } |
897 | 897 | ||
898 | case comparison::int_is_at_least: | 898 | case comparison::int_is_at_least: |
899 | { | 899 | { |
900 | return filter(singleton_.filterField, comparison::int_is_less_than, singleton_.intValue); | 900 | return filter(singleton_.filterField, comparison::int_is_less_than, singleton_.intValue); |
901 | } | 901 | } |
902 | 902 | ||
903 | case comparison::int_is_greater_than: | 903 | case comparison::int_is_greater_than: |
904 | { | 904 | { |
905 | return filter(singleton_.filterField, comparison::int_is_at_most, singleton_.intValue); | 905 | return filter(singleton_.filterField, comparison::int_is_at_most, singleton_.intValue); |
906 | } | 906 | } |
907 | 907 | ||
908 | case comparison::int_is_at_most: | 908 | case comparison::int_is_at_most: |
909 | { | 909 | { |
910 | return filter(singleton_.filterField, comparison::int_is_greater_than, singleton_.intValue); | 910 | return filter(singleton_.filterField, comparison::int_is_greater_than, singleton_.intValue); |
911 | } | 911 | } |
912 | 912 | ||
913 | case comparison::int_is_less_than: | 913 | case comparison::int_is_less_than: |
914 | { | 914 | { |
915 | return filter(singleton_.filterField, comparison::int_is_at_least, singleton_.intValue); | 915 | return filter(singleton_.filterField, comparison::int_is_at_least, singleton_.intValue); |
916 | } | 916 | } |
917 | 917 | ||
918 | case comparison::boolean_equals: | 918 | case comparison::boolean_equals: |
919 | { | 919 | { |
920 | return filter(singleton_.filterField, comparison::boolean_equals, !singleton_.boolValue); | 920 | return filter(singleton_.filterField, comparison::boolean_equals, !singleton_.boolValue); |
921 | } | 921 | } |
922 | 922 | ||
923 | case comparison::string_equals: | 923 | case comparison::string_equals: |
924 | { | 924 | { |
925 | return filter(singleton_.filterField, comparison::string_does_not_equal, singleton_.stringValue); | 925 | return filter(singleton_.filterField, comparison::string_does_not_equal, singleton_.stringValue); |
926 | } | 926 | } |
927 | 927 | ||
928 | case comparison::string_does_not_equal: | 928 | case comparison::string_does_not_equal: |
929 | { | 929 | { |
930 | return filter(singleton_.filterField, comparison::string_equals, singleton_.stringValue); | 930 | return filter(singleton_.filterField, comparison::string_equals, singleton_.stringValue); |
931 | } | 931 | } |
932 | 932 | ||
933 | case comparison::string_is_like: | 933 | case comparison::string_is_like: |
934 | { | 934 | { |
935 | return filter(singleton_.filterField, comparison::string_is_not_like, singleton_.stringValue); | 935 | return filter(singleton_.filterField, comparison::string_is_not_like, singleton_.stringValue); |
936 | } | 936 | } |
937 | 937 | ||
938 | case comparison::string_is_not_like: | 938 | case comparison::string_is_not_like: |
939 | { | 939 | { |
940 | return filter(singleton_.filterField, comparison::string_is_like, singleton_.stringValue); | 940 | return filter(singleton_.filterField, comparison::string_is_like, singleton_.stringValue); |
941 | } | 941 | } |
942 | 942 | ||
943 | case comparison::is_null: | 943 | case comparison::is_null: |
944 | { | 944 | { |
945 | return filter(singleton_.filterField, comparison::is_not_null); | 945 | return filter(singleton_.filterField, comparison::is_not_null); |
946 | } | 946 | } |
947 | 947 | ||
948 | case comparison::is_not_null: | 948 | case comparison::is_not_null: |
949 | { | 949 | { |
950 | return filter(singleton_.filterField, comparison::is_null); | 950 | return filter(singleton_.filterField, comparison::is_null); |
951 | } | 951 | } |
952 | 952 | ||
953 | case comparison::matches: | 953 | case comparison::matches: |
954 | { | 954 | { |
955 | return filter(singleton_.filterField, comparison::does_not_match, *singleton_.join); | 955 | return filter(singleton_.filterField, comparison::does_not_match, *singleton_.join); |
956 | } | 956 | } |
957 | 957 | ||
958 | case comparison::does_not_match: | 958 | case comparison::does_not_match: |
959 | { | 959 | { |
960 | return filter(singleton_.filterField, comparison::matches, *singleton_.join); | 960 | return filter(singleton_.filterField, comparison::matches, *singleton_.join); |
961 | } | 961 | } |
962 | 962 | ||
963 | case comparison::hierarchally_matches: | 963 | case comparison::hierarchally_matches: |
964 | { | 964 | { |
965 | return filter(singleton_.filterField, comparison::does_not_hierarchally_match, *singleton_.join); | 965 | return filter(singleton_.filterField, comparison::does_not_hierarchally_match, *singleton_.join); |
966 | } | 966 | } |
967 | 967 | ||
968 | case comparison::does_not_hierarchally_match: | 968 | case comparison::does_not_hierarchally_match: |
969 | { | 969 | { |
970 | return filter(singleton_.filterField, comparison::hierarchally_matches, *singleton_.join); | 970 | return filter(singleton_.filterField, comparison::hierarchally_matches, *singleton_.join); |
971 | } | 971 | } |
972 | } | 972 | } |
973 | } | 973 | } |
974 | 974 | ||
975 | case type::group: | 975 | case type::group: |
976 | { | 976 | { |
977 | filter result(!group_.orlogic); | 977 | filter result(!group_.orlogic); |
978 | 978 | ||
979 | for (const filter& child : group_.children) | 979 | for (const filter& child : group_.children) |
980 | { | 980 | { |
981 | result += !child; | 981 | result += !child; |
982 | } | 982 | } |
983 | 983 | ||
984 | return result; | 984 | return result; |
985 | } | 985 | } |
986 | } | 986 | } |
987 | } | 987 | } |
988 | 988 | ||
989 | filter& filter::operator&=(filter condition) | 989 | filter& filter::operator&=(filter condition) |
990 | { | 990 | { |
991 | return (*this = (*this && std::move(condition))); | 991 | return (*this = (*this && std::move(condition))); |
992 | } | 992 | } |
993 | 993 | ||
994 | filter& filter::operator|=(filter condition) | 994 | filter& filter::operator|=(filter condition) |
995 | { | 995 | { |
996 | return (*this = (*this || std::move(condition))); | 996 | return (*this = (*this || std::move(condition))); |
997 | } | 997 | } |
998 | 998 | ||
999 | filter filter::operator&&(filter condition) const | 999 | filter filter::operator&&(filter condition) const |
1000 | { | 1000 | { |
1001 | switch (type_) | 1001 | switch (type_) |
@@ -1004,16 +1004,16 @@ namespace verbly { | |||
1004 | { | 1004 | { |
1005 | return condition; | 1005 | return condition; |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | case type::singleton: | 1008 | case type::singleton: |
1009 | { | 1009 | { |
1010 | filter result(false); | 1010 | filter result(false); |
1011 | result.group_.children.push_back(*this); | 1011 | result.group_.children.push_back(*this); |
1012 | result.group_.children.push_back(std::move(condition)); | 1012 | result.group_.children.push_back(std::move(condition)); |
1013 | 1013 | ||
1014 | return result; | 1014 | return result; |
1015 | } | 1015 | } |
1016 | 1016 | ||
1017 | case type::group: | 1017 | case type::group: |
1018 | { | 1018 | { |
1019 | if (group_.orlogic) | 1019 | if (group_.orlogic) |
@@ -1026,13 +1026,13 @@ namespace verbly { | |||
1026 | } else { | 1026 | } else { |
1027 | filter result(*this); | 1027 | filter result(*this); |
1028 | result.group_.children.push_back(std::move(condition)); | 1028 | result.group_.children.push_back(std::move(condition)); |
1029 | 1029 | ||
1030 | return result; | 1030 | return result; |
1031 | } | 1031 | } |
1032 | } | 1032 | } |
1033 | } | 1033 | } |
1034 | } | 1034 | } |
1035 | 1035 | ||
1036 | filter filter::operator||(filter condition) const | 1036 | filter filter::operator||(filter condition) const |
1037 | { | 1037 | { |
1038 | switch (type_) | 1038 | switch (type_) |
@@ -1041,16 +1041,16 @@ namespace verbly { | |||
1041 | { | 1041 | { |
1042 | return condition; | 1042 | return condition; |
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | case type::singleton: | 1045 | case type::singleton: |
1046 | { | 1046 | { |
1047 | filter result(true); | 1047 | filter result(true); |
1048 | result.group_.children.push_back(*this); | 1048 | result.group_.children.push_back(*this); |
1049 | result.group_.children.push_back(std::move(condition)); | 1049 | result.group_.children.push_back(std::move(condition)); |
1050 | 1050 | ||
1051 | return result; | 1051 | return result; |
1052 | } | 1052 | } |
1053 | 1053 | ||
1054 | case type::group: | 1054 | case type::group: |
1055 | { | 1055 | { |
1056 | if (!group_.orlogic) | 1056 | if (!group_.orlogic) |
@@ -1063,13 +1063,13 @@ namespace verbly { | |||
1063 | } else { | 1063 | } else { |
1064 | filter result(*this); | 1064 | filter result(*this); |
1065 | result.group_.children.push_back(std::move(condition)); | 1065 | result.group_.children.push_back(std::move(condition)); |
1066 | 1066 | ||
1067 | return result; | 1067 | return result; |
1068 | } | 1068 | } |
1069 | } | 1069 | } |
1070 | } | 1070 | } |
1071 | } | 1071 | } |
1072 | 1072 | ||
1073 | filter filter::normalize(object context) const | 1073 | filter filter::normalize(object context) const |
1074 | { | 1074 | { |
1075 | { | 1075 | { |
@@ -1096,7 +1096,7 @@ namespace verbly { | |||
1096 | // recontexualization. | 1096 | // recontexualization. |
1097 | return *this; | 1097 | return *this; |
1098 | } | 1098 | } |
1099 | 1099 | ||
1100 | case object::notion: | 1100 | case object::notion: |
1101 | { | 1101 | { |
1102 | switch (singleton_.filterField.getObject()) | 1102 | switch (singleton_.filterField.getObject()) |
@@ -1106,7 +1106,7 @@ namespace verbly { | |||
1106 | { | 1106 | { |
1107 | return *this; | 1107 | return *this; |
1108 | } | 1108 | } |
1109 | 1109 | ||
1110 | case object::word: | 1110 | case object::word: |
1111 | case object::group: | 1111 | case object::group: |
1112 | case object::frame: | 1112 | case object::frame: |
@@ -1118,7 +1118,7 @@ namespace verbly { | |||
1118 | } | 1118 | } |
1119 | } | 1119 | } |
1120 | } | 1120 | } |
1121 | 1121 | ||
1122 | case object::word: | 1122 | case object::word: |
1123 | { | 1123 | { |
1124 | switch (singleton_.filterField.getObject()) | 1124 | switch (singleton_.filterField.getObject()) |
@@ -1127,19 +1127,19 @@ namespace verbly { | |||
1127 | { | 1127 | { |
1128 | return (verbly::word::notion %= *this); | 1128 | return (verbly::word::notion %= *this); |
1129 | } | 1129 | } |
1130 | 1130 | ||
1131 | case object::undefined: | 1131 | case object::undefined: |
1132 | case object::word: | 1132 | case object::word: |
1133 | { | 1133 | { |
1134 | return *this; | 1134 | return *this; |
1135 | } | 1135 | } |
1136 | 1136 | ||
1137 | case object::group: | 1137 | case object::group: |
1138 | case object::frame: | 1138 | case object::frame: |
1139 | { | 1139 | { |
1140 | return (verbly::word::group %= *this); | 1140 | return (verbly::word::group %= *this); |
1141 | } | 1141 | } |
1142 | 1142 | ||
1143 | case object::lemma: | 1143 | case object::lemma: |
1144 | case object::form: | 1144 | case object::form: |
1145 | case object::pronunciation: | 1145 | case object::pronunciation: |
@@ -1147,7 +1147,7 @@ namespace verbly { | |||
1147 | return (verbly::word::lemma %= *this); | 1147 | return (verbly::word::lemma %= *this); |
1148 | } | 1148 | } |
1149 | } | 1149 | } |
1150 | 1150 | ||
1151 | case object::group: | 1151 | case object::group: |
1152 | { | 1152 | { |
1153 | switch (singleton_.filterField.getObject()) | 1153 | switch (singleton_.filterField.getObject()) |
@@ -1157,7 +1157,7 @@ namespace verbly { | |||
1157 | { | 1157 | { |
1158 | return *this; | 1158 | return *this; |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | case object::notion: | 1161 | case object::notion: |
1162 | case object::word: | 1162 | case object::word: |
1163 | case object::lemma: | 1163 | case object::lemma: |
@@ -1166,14 +1166,14 @@ namespace verbly { | |||
1166 | { | 1166 | { |
1167 | return (verbly::group::word %= *this); | 1167 | return (verbly::group::word %= *this); |
1168 | } | 1168 | } |
1169 | 1169 | ||
1170 | case object::frame: | 1170 | case object::frame: |
1171 | { | 1171 | { |
1172 | return (verbly::group::frame %= *this); | 1172 | return (verbly::group::frame %= *this); |
1173 | } | 1173 | } |
1174 | } | 1174 | } |
1175 | } | 1175 | } |
1176 | 1176 | ||
1177 | case object::frame: | 1177 | case object::frame: |
1178 | { | 1178 | { |
1179 | switch (singleton_.filterField.getObject()) | 1179 | switch (singleton_.filterField.getObject()) |
@@ -1183,7 +1183,7 @@ namespace verbly { | |||
1183 | { | 1183 | { |
1184 | return *this; | 1184 | return *this; |
1185 | } | 1185 | } |
1186 | 1186 | ||
1187 | case object::notion: | 1187 | case object::notion: |
1188 | case object::word: | 1188 | case object::word: |
1189 | case object::group: | 1189 | case object::group: |
@@ -1195,7 +1195,7 @@ namespace verbly { | |||
1195 | } | 1195 | } |
1196 | } | 1196 | } |
1197 | } | 1197 | } |
1198 | 1198 | ||
1199 | case object::lemma: | 1199 | case object::lemma: |
1200 | { | 1200 | { |
1201 | switch (singleton_.filterField.getObject()) | 1201 | switch (singleton_.filterField.getObject()) |
@@ -1207,7 +1207,7 @@ namespace verbly { | |||
1207 | { | 1207 | { |
1208 | return verbly::lemma::word %= *this; | 1208 | return verbly::lemma::word %= *this; |
1209 | } | 1209 | } |
1210 | 1210 | ||
1211 | case object::undefined: | 1211 | case object::undefined: |
1212 | case object::lemma: | 1212 | case object::lemma: |
1213 | { | 1213 | { |
@@ -1221,7 +1221,7 @@ namespace verbly { | |||
1221 | } | 1221 | } |
1222 | } | 1222 | } |
1223 | } | 1223 | } |
1224 | 1224 | ||
1225 | case object::form: | 1225 | case object::form: |
1226 | { | 1226 | { |
1227 | switch (singleton_.filterField.getObject()) | 1227 | switch (singleton_.filterField.getObject()) |
@@ -1234,7 +1234,7 @@ namespace verbly { | |||
1234 | { | 1234 | { |
1235 | return verbly::form::lemma(inflection::base) %= *this; | 1235 | return verbly::form::lemma(inflection::base) %= *this; |
1236 | } | 1236 | } |
1237 | 1237 | ||
1238 | case object::undefined: | 1238 | case object::undefined: |
1239 | case object::form: | 1239 | case object::form: |
1240 | { | 1240 | { |
@@ -1247,7 +1247,7 @@ namespace verbly { | |||
1247 | } | 1247 | } |
1248 | } | 1248 | } |
1249 | } | 1249 | } |
1250 | 1250 | ||
1251 | case object::pronunciation: | 1251 | case object::pronunciation: |
1252 | { | 1252 | { |
1253 | switch (singleton_.filterField.getObject()) | 1253 | switch (singleton_.filterField.getObject()) |
@@ -1261,7 +1261,7 @@ namespace verbly { | |||
1261 | { | 1261 | { |
1262 | return verbly::pronunciation::form %= *this; | 1262 | return verbly::pronunciation::form %= *this; |
1263 | } | 1263 | } |
1264 | 1264 | ||
1265 | case object::undefined: | 1265 | case object::undefined: |
1266 | case object::pronunciation: | 1266 | case object::pronunciation: |
1267 | { | 1267 | { |
@@ -1276,7 +1276,8 @@ namespace verbly { | |||
1276 | case type::group: | 1276 | case type::group: |
1277 | { | 1277 | { |
1278 | filter result(group_.orlogic); | 1278 | filter result(group_.orlogic); |
1279 | std::map<field, filter> joins; | 1279 | std::map<field, filter> positiveJoins; |
1280 | std::map<field, filter> negativeJoins; | ||
1280 | 1281 | ||
1281 | for (const filter& child : group_.children) | 1282 | for (const filter& child : group_.children) |
1282 | { | 1283 | { |
@@ -1291,28 +1292,28 @@ namespace verbly { | |||
1291 | { | 1292 | { |
1292 | case comparison::matches: | 1293 | case comparison::matches: |
1293 | { | 1294 | { |
1294 | if (!joins.count(normalized.singleton_.filterField)) | 1295 | if (!positiveJoins.count(normalized.singleton_.filterField)) |
1295 | { | 1296 | { |
1296 | joins[normalized.getField()] = filter(group_.orlogic); | 1297 | positiveJoins[normalized.getField()] = filter(group_.orlogic); |
1297 | } | 1298 | } |
1298 | 1299 | ||
1299 | joins.at(normalized.getField()) += std::move(*normalized.singleton_.join); | 1300 | positiveJoins.at(normalized.getField()) += std::move(*normalized.singleton_.join); |
1300 | 1301 | ||
1301 | break; | 1302 | break; |
1302 | } | 1303 | } |
1303 | 1304 | ||
1304 | case comparison::does_not_match: | 1305 | case comparison::does_not_match: |
1305 | { | 1306 | { |
1306 | if (!joins.count(normalized.singleton_.filterField)) | 1307 | if (!negativeJoins.count(normalized.singleton_.filterField)) |
1307 | { | 1308 | { |
1308 | joins[normalized.getField()] = filter(group_.orlogic); | 1309 | negativeJoins[normalized.getField()] = filter(group_.orlogic); |
1309 | } | 1310 | } |
1310 | 1311 | ||
1311 | joins.at(normalized.getField()) += !*normalized.singleton_.join; | 1312 | negativeJoins.at(normalized.getField()) += std::move(*normalized.singleton_.join); |
1312 | 1313 | ||
1313 | break; | 1314 | break; |
1314 | } | 1315 | } |
1315 | 1316 | ||
1316 | case comparison::int_equals: | 1317 | case comparison::int_equals: |
1317 | case comparison::int_does_not_equal: | 1318 | case comparison::int_does_not_equal: |
1318 | case comparison::int_is_at_least: | 1319 | case comparison::int_is_at_least: |
@@ -1330,25 +1331,25 @@ namespace verbly { | |||
1330 | case comparison::does_not_hierarchally_match: | 1331 | case comparison::does_not_hierarchally_match: |
1331 | { | 1332 | { |
1332 | result += std::move(normalized); | 1333 | result += std::move(normalized); |
1333 | 1334 | ||
1334 | break; | 1335 | break; |
1335 | } | 1336 | } |
1336 | } | 1337 | } |
1337 | 1338 | ||
1338 | break; | 1339 | break; |
1339 | } | 1340 | } |
1340 | 1341 | ||
1341 | case type::group: | 1342 | case type::group: |
1342 | case type::empty: | 1343 | case type::empty: |
1343 | { | 1344 | { |
1344 | result += std::move(normalized); | 1345 | result += std::move(normalized); |
1345 | 1346 | ||
1346 | break; | 1347 | break; |
1347 | } | 1348 | } |
1348 | } | 1349 | } |
1349 | } | 1350 | } |
1350 | 1351 | ||
1351 | for (auto& mapping : joins) | 1352 | for (auto& mapping : positiveJoins) |
1352 | { | 1353 | { |
1353 | const field& joinOn = mapping.first; | 1354 | const field& joinOn = mapping.first; |
1354 | filter& joinCondition = mapping.second; | 1355 | filter& joinCondition = mapping.second; |
@@ -1356,6 +1357,14 @@ namespace verbly { | |||
1356 | result += (joinOn %= joinCondition.normalize(joinOn.getJoinObject())); | 1357 | result += (joinOn %= joinCondition.normalize(joinOn.getJoinObject())); |
1357 | } | 1358 | } |
1358 | 1359 | ||
1360 | for (auto& mapping : negativeJoins) | ||
1361 | { | ||
1362 | const field& joinOn = mapping.first; | ||
1363 | filter& joinCondition = mapping.second; | ||
1364 | |||
1365 | result += !(joinOn %= joinCondition.normalize(joinOn.getJoinObject())); | ||
1366 | } | ||
1367 | |||
1359 | return result; | 1368 | return result; |
1360 | } | 1369 | } |
1361 | } | 1370 | } |