summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/filter.cpp146
-rw-r--r--lib/filter.h22
-rw-r--r--lib/statement.cpp12
-rw-r--r--lib/word.cpp24
4 files changed, 193 insertions, 11 deletions
diff --git a/lib/filter.cpp b/lib/filter.cpp index 1472eeb..fec0fd3 100644 --- a/lib/filter.cpp +++ b/lib/filter.cpp
@@ -92,6 +92,15 @@ namespace verbly {
92 92
93 break; 93 break;
94 } 94 }
95
96 case type::mask:
97 {
98 new(&mask_.name) std::string(other.mask_.name);
99 mask_.internal = other.mask_.internal;
100 new(&mask_.subfilter) std::unique_ptr<filter>(new filter(*other.mask_.subfilter));
101
102 break;
103 }
95 } 104 }
96 } 105 }
97 106
@@ -122,6 +131,9 @@ namespace verbly {
122 field tempCompareField; 131 field tempCompareField;
123 std::list<filter> tempChildren; 132 std::list<filter> tempChildren;
124 bool tempOrlogic; 133 bool tempOrlogic;
134 std::string tempMaskName;
135 bool tempMaskInternal;
136 std::unique_ptr<filter> tempMaskSubfilter;
125 137
126 switch (tempType) 138 switch (tempType)
127 { 139 {
@@ -201,6 +213,15 @@ namespace verbly {
201 213
202 break; 214 break;
203 } 215 }
216
217 case type::mask:
218 {
219 tempMaskName = std::move(first.mask_.name);
220 tempMaskInternal = first.mask_.internal;
221 tempMaskSubfilter = std::move(first.mask_.subfilter);
222
223 break;
224 }
204 } 225 }
205 226
206 first.~filter(); 227 first.~filter();
@@ -285,6 +306,15 @@ namespace verbly {
285 306
286 break; 307 break;
287 } 308 }
309
310 case type::mask:
311 {
312 new(&first.mask_.name) std::string(std::move(second.mask_.name));
313 first.mask_.internal = second.mask_.internal;
314 new(&first.mask_.subfilter) std::unique_ptr<filter>(std::move(second.mask_.subfilter));
315
316 break;
317 }
288 } 318 }
289 319
290 second.~filter(); 320 second.~filter();
@@ -369,6 +399,15 @@ namespace verbly {
369 399
370 break; 400 break;
371 } 401 }
402
403 case type::mask:
404 {
405 new(&first.mask_.name) std::string(std::move(tempMaskName));
406 first.mask_.internal = tempMaskInternal;
407 new(&first.mask_.subfilter) std::unique_ptr<filter>(std::move(tempMaskSubfilter));
408
409 break;
410 }
372 } 411 }
373 } 412 }
374 413
@@ -444,6 +483,17 @@ namespace verbly {
444 483
445 break; 484 break;
446 } 485 }
486
487 case type::mask:
488 {
489 using string_type = std::string;
490 using ptr_type = std::unique_ptr<filter>;
491
492 mask_.name.~string_type();
493 mask_.subfilter.~ptr_type();
494
495 break;
496 }
447 } 497 }
448 } 498 }
449 499
@@ -1024,6 +1074,44 @@ namespace verbly {
1024 } 1074 }
1025 } 1075 }
1026 1076
1077 filter::filter(std::string name, bool internal, filter subfilter) :
1078 type_(type::mask)
1079 {
1080 new(&mask_.name) std::string(std::move(name));
1081 mask_.internal = internal;
1082 new(&mask_.subfilter) std::unique_ptr<filter>(new filter(std::move(subfilter)));
1083 }
1084
1085 const std::string& filter::getMaskName() const
1086 {
1087 if (type_ == type::mask)
1088 {
1089 return mask_.name;
1090 } else {
1091 throw std::domain_error("This filter is not a mask filter");
1092 }
1093 }
1094
1095 bool filter::isMaskInternal() const
1096 {
1097 if (type_ == type::mask)
1098 {
1099 return mask_.internal;
1100 } else {
1101 throw std::domain_error("This filter is not a mask filter");
1102 }
1103 }
1104
1105 const filter& filter::getMaskFilter() const
1106 {
1107 if (type_ == type::mask)
1108 {
1109 return *mask_.subfilter;
1110 } else {
1111 throw std::domain_error("This filter is not a mask filter");
1112 }
1113 }
1114
1027 filter filter::operator!() const 1115 filter filter::operator!() const
1028 { 1116 {
1029 switch (type_) 1117 switch (type_)
@@ -1145,6 +1233,11 @@ namespace verbly {
1145 1233
1146 return result; 1234 return result;
1147 } 1235 }
1236
1237 case type::mask:
1238 {
1239 return {mask_.name, mask_.internal, !*mask_.subfilter};
1240 }
1148 } 1241 }
1149 } 1242 }
1150 1243
@@ -1168,6 +1261,7 @@ namespace verbly {
1168 } 1261 }
1169 1262
1170 case type::singleton: 1263 case type::singleton:
1264 case type::mask:
1171 { 1265 {
1172 filter result(false); 1266 filter result(false);
1173 result.group_.children.push_back(*this); 1267 result.group_.children.push_back(*this);
@@ -1205,6 +1299,7 @@ namespace verbly {
1205 } 1299 }
1206 1300
1207 case type::singleton: 1301 case type::singleton:
1302 case type::mask:
1208 { 1303 {
1209 filter result(true); 1304 filter result(true);
1210 result.group_.children.push_back(*this); 1305 result.group_.children.push_back(*this);
@@ -1232,6 +1327,11 @@ namespace verbly {
1232 } 1327 }
1233 } 1328 }
1234 1329
1330 filter filter::mask(std::string name, filter subfilter)
1331 {
1332 return {std::move(name), false, std::move(subfilter)};
1333 }
1334
1235 filter filter::normalize(object context) const 1335 filter filter::normalize(object context) const
1236 { 1336 {
1237 { 1337 {
@@ -1408,6 +1508,7 @@ namespace verbly {
1408 filter result(group_.orlogic); 1508 filter result(group_.orlogic);
1409 std::map<field, filter> positiveJoins; 1509 std::map<field, filter> positiveJoins;
1410 std::map<field, filter> negativeJoins; 1510 std::map<field, filter> negativeJoins;
1511 std::map<std::tuple<std::string, bool>, filter> masks;
1411 1512
1412 for (const filter& child : group_.children) 1513 for (const filter& child : group_.children)
1413 { 1514 {
@@ -1502,6 +1603,20 @@ namespace verbly {
1502 1603
1503 break; 1604 break;
1504 } 1605 }
1606
1607 case type::mask:
1608 {
1609 auto maskId = std::tie(normalized.mask_.name, normalized.mask_.internal);
1610
1611 if (!masks.count(maskId))
1612 {
1613 masks[maskId] = filter(group_.orlogic);
1614 }
1615
1616 masks.at(maskId) += std::move(*normalized.mask_.subfilter);
1617
1618 break;
1619 }
1505 } 1620 }
1506 } 1621 }
1507 1622
@@ -1521,8 +1636,22 @@ namespace verbly {
1521 result += !(joinOn %= joinCondition.normalize(joinOn.getJoinObject())); 1636 result += !(joinOn %= joinCondition.normalize(joinOn.getJoinObject()));
1522 } 1637 }
1523 1638
1639 for (auto& mapping : masks)
1640 {
1641 const std::string& name = std::get<0>(mapping.first);
1642 bool internal = std::get<1>(mapping.first);
1643 filter& subfilter = mapping.second;
1644
1645 result += {name, internal, std::move(subfilter)};
1646 }
1647
1524 return result; 1648 return result;
1525 } 1649 }
1650
1651 case type::mask:
1652 {
1653 return {mask_.name, mask_.internal, mask_.subfilter->normalize(context)};
1654 }
1526 } 1655 }
1527 } 1656 }
1528 } 1657 }
@@ -1552,10 +1681,27 @@ namespace verbly {
1552 if (result.group_.children.empty()) 1681 if (result.group_.children.empty())
1553 { 1682 {
1554 result = {}; 1683 result = {};
1684 } else if (result.group_.children.size() == 1)
1685 {
1686 filter tempChild = std::move(result.group_.children.front());
1687
1688 result = std::move(tempChild);
1555 } 1689 }
1556 1690
1557 return result; 1691 return result;
1558 } 1692 }
1693
1694 case type::mask:
1695 {
1696 filter subfilter = mask_.subfilter->compact();
1697
1698 if (subfilter.type_ == type::empty)
1699 {
1700 return {};
1701 } else {
1702 return {mask_.name, mask_.internal, std::move(subfilter)};
1703 }
1704 }
1559 } 1705 }
1560 } 1706 }
1561 1707
diff --git a/lib/filter.h b/lib/filter.h index a12a822..942fe18 100644 --- a/lib/filter.h +++ b/lib/filter.h
@@ -14,7 +14,8 @@ namespace verbly {
14 enum class type { 14 enum class type {
15 empty, 15 empty,
16 singleton, 16 singleton,
17 group 17 group,
18 mask
18 }; 19 };
19 20
20 enum class comparison { 21 enum class comparison {
@@ -106,6 +107,16 @@ namespace verbly {
106 107
107 const_iterator end() const; 108 const_iterator end() const;
108 109
110 // Mask
111
112 filter(std::string name, bool internal, filter subfilter);
113
114 const std::string& getMaskName() const;
115
116 bool isMaskInternal() const;
117
118 const filter& getMaskFilter() const;
119
109 // Negation 120 // Negation
110 121
111 filter operator!() const; 122 filter operator!() const;
@@ -118,6 +129,10 @@ namespace verbly {
118 filter& operator&=(filter condition); 129 filter& operator&=(filter condition);
119 filter& operator|=(filter condition); 130 filter& operator|=(filter condition);
120 131
132 // Maskifying
133
134 static filter mask(std::string name, filter subfilter);
135
121 // Utility 136 // Utility
122 137
123 filter normalize(object context) const; 138 filter normalize(object context) const;
@@ -141,6 +156,11 @@ namespace verbly {
141 std::list<filter> children; 156 std::list<filter> children;
142 bool orlogic; 157 bool orlogic;
143 } group_; 158 } group_;
159 struct {
160 std::string name;
161 bool internal;
162 std::unique_ptr<filter> subfilter;
163 } mask_;
144 }; 164 };
145 type type_ = type::empty; 165 type type_ = type::empty;
146 166
diff --git a/lib/statement.cpp b/lib/statement.cpp index e84a402..5dd3789 100644 --- a/lib/statement.cpp +++ b/lib/statement.cpp
@@ -594,6 +594,18 @@ namespace verbly {
594 594
595 return grp; 595 return grp;
596 } 596 }
597
598 case filter::type::mask:
599 {
600 condition result = parseFilter(clause.getMaskFilter());
601
602 if (result.getType() == condition::type::empty)
603 {
604 return {};
605 } else {
606 return result;
607 }
608 }
597 } 609 }
598 } 610 }
599 611
diff --git a/lib/word.cpp b/lib/word.cpp index dc269c9..6f0fe22 100644 --- a/lib/word.cpp +++ b/lib/word.cpp
@@ -172,20 +172,24 @@ namespace verbly {
172 172
173 filter word::synonyms_field::operator%=(filter joinCondition) const 173 filter word::synonyms_field::operator%=(filter joinCondition) const
174 { 174 {
175 return (verbly::notion::words %= ( 175 return (verbly::word::notions %=
176 std::move(joinCondition) 176 filter("synonyms", true,
177 && (filter( 177 (verbly::notion::words %= (
178 verbly::word::id, 178 std::move(joinCondition)
179 filter::comparison::field_does_not_equal, 179 && (filter(
180 verbly::word::id)))); 180 verbly::word::id,
181 filter::comparison::field_does_not_equal,
182 verbly::word::id))))));
181 } 183 }
182 184
183 word::synonyms_field::operator filter() const 185 word::synonyms_field::operator filter() const
184 { 186 {
185 return (verbly::notion::words %= filter( 187 return (verbly::word::notions %=
186 verbly::word::id, 188 filter("synonyms", true,
187 filter::comparison::field_does_not_equal, 189 (verbly::notion::words %= filter(
188 verbly::word::id)); 190 verbly::word::id,
191 filter::comparison::field_does_not_equal,
192 verbly::word::id))));
189 } 193 }
190 194
191}; 195};