71 using Index =
typename Derived::Index;
72 using Node =
typename Derived::Node;
73 using Code =
typename Derived::Code;
74 using Key =
typename Derived::Key;
75 using Point =
typename Derived::Point;
76 static constexpr std::size_t
const N = Derived::childrenPerParent();
85 assert(semantics_.size() > node.pos && N > node.offset);
87 if (semanticsEmpty(node)) {
91 if (derived().isLeaf(node)) {
95 return semantics_[node.pos].semantics.subset(node.offset);
99 std::vector<Semantic> tmp;
100 derived().traverse(node, [
this, &tmp, p = node.pos](Index node) ->
bool {
101 if (0 == node.offset && p != node.pos) {
102 tmp.insert(std::end(tmp), std::cbegin(semantics_[node.pos].semantics),
103 std::cend(semantics_[node.pos].semantics));
105 return !semanticsEmpty(node);
108 std::sort(std::begin(tmp), std::end(tmp));
110 switch (semanticsPropagationCriteria()) {
111 case PropagationCriteria::MIN: {
112 auto last = std::unique(std::begin(tmp), std::end(tmp),
113 [](
auto a,
auto b) {
return a.label ==
b.label; });
114 return {std::begin(tmp), last};
116 case PropagationCriteria::MEAN: {
121 auto r_last = std::unique(std::rbegin(tmp), std::rend(tmp),
122 [](
auto a,
auto b) {
return a.label ==
b.label; });
123 return {r_last.base(), std::end(tmp)};
130 return semantics(derived().
index(node));
133 [[nodiscard]] SemanticSet<1> semantics(Code code)
const
135 return semantics(derived().index(code));
138 [[nodiscard]] SemanticSet<1> semantics(Key key)
const
140 return semantics(derived().index(key));
143 [[nodiscard]] SemanticSet<1> semantics(Point coord, depth_t depth = 0)
const
145 return semantics(derived().index(coord, depth));
149 template <
class ExecutionPolicy,
150 std::enable_if_t<std::is_execution_policy_v<ExecutionPolicy>,
bool> =
true>
151 [[nodiscard]] SemanticSet<1> semantics(ExecutionPolicy&& policy, Index node)
const
153 assert(semantics_.size() > node.pos && N > node.offset);
155 if (semanticsEmpty(node)) {
159 if (derived().isLeaf(node)) {
161 static_assert(N > 1);
163 return semantics_[node.pos].semantics.subset(node.offset);
167 std::vector<Semantic> tmp;
168 derived().traverse(node, [
this, &tmp, p = node.pos](Index node) ->
bool {
169 if (0 == node.offset && p != node.pos) {
170 tmp.insert(std::end(tmp), std::cbegin(semantics_[node.pos].semantics),
171 std::cend(semantics_[node.pos].semantics));
173 return !semanticsEmpty(node);
176 std::sort(policy, std::begin(tmp), std::end(tmp));
178 switch (semanticsPropagationCriteria()) {
179 case PropagationCriteria::MIN: {
181 std::unique(std::forward<ExecutionPolicy>(policy), std::begin(tmp),
182 std::end(tmp), [](
auto a,
auto b) {
return a.label ==
b.label; });
183 return {std::begin(tmp), last};
185 case PropagationCriteria::MEAN: {
190 auto r_last = std::unique(std::forward<ExecutionPolicy>(policy), std::rbegin(tmp),
192 [](
auto a,
auto b) {
return a.label ==
b.label; });
193 return {r_last.base(), std::end(tmp)};
198 template <
class ExecutionPolicy,
199 std::enable_if_t<std::is_execution_policy_v<ExecutionPolicy>,
bool> =
true>
200 [[nodiscard]] SemanticSet<1> semantics(ExecutionPolicy&& policy, Node node)
const
202 return semantics(std::forward<ExecutionPolicy>(policy), derived().index(node));
205 template <
class ExecutionPolicy,
206 std::enable_if_t<std::is_execution_policy_v<ExecutionPolicy>,
bool> =
true>
207 [[nodiscard]] SemanticSet<1> semantics(ExecutionPolicy&& policy, Code code)
const
209 return semantics(std::forward<ExecutionPolicy>(policy), derived().index(code));
212 template <
class ExecutionPolicy,
213 std::enable_if_t<std::is_execution_policy_v<ExecutionPolicy>,
bool> =
true>
214 [[nodiscard]] SemanticSet<1> semantics(ExecutionPolicy&& policy, Key key)
const
216 return semantics(std::forward<ExecutionPolicy>(policy), derived().index(key));
219 template <
class ExecutionPolicy,
220 std::enable_if_t<std::is_execution_policy_v<ExecutionPolicy>,
bool> =
true>
221 [[nodiscard]] SemanticSet<1> semantics(ExecutionPolicy&& policy, Point coord,
222 depth_t depth = 0)
const
224 return semantics(std::forward<ExecutionPolicy>(policy),
225 derived().index(coord, depth));
233 [[nodiscard]] Semantic semanticsSummary(pos_t block)
const
235 assert(semantics_.size() > block);
236 return semantics_[block].summary;
239 [[nodiscard]] Semantic semanticsSummary(Index node)
const
241 assert(semantics_.size() > node.pos && N > node.offset);
242 return derived().isChild(node) ? semantics_[node.pos].summary(node.offset)
243 : semanticsSummary(derived().children(node));
246 [[nodiscard]] Semantic semanticsSummary(Node node)
const
248 return semanticsSummary(derived().index(node));
251 [[nodiscard]] Semantic semanticsSummary(Code code)
const
253 return semanticsSummary(derived().index(code));
256 [[nodiscard]] Semantic semanticsSummary(Key key)
const
258 return semanticsSummary(derived().index(key));
261 [[nodiscard]] Semantic semanticsSummary(Point coord, depth_t depth = 0)
const
263 return semanticsSummary(derived().index(coord, depth));
270 [[nodiscard]]
bool semanticsEmpty(Index node)
const
272 assert(semantics_.size() > node.pos && N > node.offset);
273 return semantics_[node.pos].label_summary[node.offset];
276 [[nodiscard]]
bool semanticsEmpty(Node node)
const
278 return semanticsEmpty(derived().index(node));
281 [[nodiscard]]
bool semanticsEmpty(Code code)
const
283 return semanticsEmpty(derived().index(code));
286 [[nodiscard]]
bool semanticsEmpty(Key key)
const
288 return semanticsEmpty(derived().index(key));
291 [[nodiscard]]
bool semanticsEmpty(Point coord, depth_t depth = 0)
const
293 return semanticsEmpty(derived().index(coord, depth));
300 [[nodiscard]] std::size_t semanticsSize(Index node)
const
302 assert(semantics_.size() > node.pos && N > node.offset);
306 [[nodiscard]] std::size_t semanticsSize(Node node)
const
308 return semanticsSize(derived().index(node));
311 [[nodiscard]] std::size_t semanticsSize(Code code)
const
313 return semanticsSize(derived().index(code));
316 [[nodiscard]] std::size_t semanticsSize(Key key)
const
318 return semanticsSize(derived().index(key));
321 [[nodiscard]] std::size_t semanticsSize(Point coord, depth_t depth = 0)
const
323 return semanticsSize(derived().index(coord, depth));
330 [[nodiscard]] std::size_t semanticsCount(Index node, label_t label)
const
332 assert(semantics_.size() > node.pos && N > node.offset);
336 [[nodiscard]] std::size_t semanticsCount(Node node, label_t label)
const
338 return semanticsCount(derived().index(node), label);
341 [[nodiscard]] std::size_t semanticsCount(Code code, label_t label)
const
343 return semanticsCount(derived().index(code), label);
346 [[nodiscard]] std::size_t semanticsCount(Key key, label_t label)
const
348 return semanticsCount(derived().index(key), label);
351 [[nodiscard]] std::size_t semanticsCount(Point coord, label_t label,
352 depth_t depth = 0)
const
354 return semanticsCount(derived().index(coord, depth), label);
361 [[nodiscard]]
bool semanticsContains(Index node, label_t label)
const
363 assert(semantics_.size() > node.pos && N > node.offset);
367 [[nodiscard]]
bool semanticsContains(Node node, label_t label)
const
369 return semanticsContains(derived().index(node), label);
372 [[nodiscard]]
bool semanticsContains(Code code, label_t label)
const
374 return semanticsContains(derived().index(code), label);
377 [[nodiscard]]
bool semanticsContains(Key key, label_t label)
const
379 return semanticsContains(derived().index(key), label);
382 [[nodiscard]]
bool semanticsContains(Point coord, label_t label,
383 depth_t depth = 0)
const
385 return semanticsContains(derived().index(coord, depth), label);
392 [[nodiscard]]
bool semanticsContainsClass(Index node, std::string tag)
const
398 [[nodiscard]]
bool semanticsContainsClass(Index node, label_t tag)
const
407 [[nodiscard]]
bool semanticsContainsAll(Index node, std::string tag)
const
412 [[nodiscard]]
bool semanticsContainsAll(Index node, SemanticRange range)
const
414 assert(semantics_.size() > node.pos && N > node.offset);
418 [[nodiscard]]
bool semanticsContainsAll(Index node,
419 SemanticRangeSet
const& ranges)
const
421 assert(semantics_.size() > node.pos && N > node.offset);
425 [[nodiscard]]
bool semanticsContainsAll(Node node, SemanticRange range)
const
427 return semanticsContainsAll(derived().index(node), range);
430 [[nodiscard]]
bool semanticsContainsAll(Code code, SemanticRange range)
const
432 return semanticsContainsAll(derived().index(code), range);
435 [[nodiscard]]
bool semanticsContainsAll(Key key, SemanticRange range)
const
437 return semanticsContainsAll(derived().index(key), range);
440 [[nodiscard]]
bool semanticsContainsAll(Point coord, SemanticRange range,
441 depth_t depth = 0)
const
443 return semanticsContainsAll(derived().index(coord, depth), range);
450 [[nodiscard]]
bool semanticsContainsAny(Index node, SemanticRange range)
const
452 assert(semantics_.size() > node.pos && N > node.offset);
456 [[nodiscard]]
bool semanticsContainsAny(Node node, SemanticRange range)
const
458 return semanticsContainsAny(derived().index(node), range);
461 [[nodiscard]]
bool semanticsContainsAny(Code code, SemanticRange range)
const
463 return semanticsContainsAny(derived().index(code), range);
466 [[nodiscard]]
bool semanticsContainsAny(Key key, SemanticRange range)
const
468 return semanticsContainsAny(derived().index(key), range);
471 [[nodiscard]]
bool semanticsContainsAny(Point coord, SemanticRange range,
472 depth_t depth = 0)
const
474 return semanticsContainsAny(derived().index(coord, depth), range);
481 [[nodiscard]]
bool semanticsContainsNone(Index node, SemanticRange range)
const
483 assert(semantics_.size() > node.pos && N > node.offset);
487 [[nodiscard]]
bool semanticsContainsNone(Node node, SemanticRange range)
const
489 return semanticsContainsNone(derived().index(node), range);
492 [[nodiscard]]
bool semanticsContainsNone(Code code, SemanticRange range)
const
494 return semanticsContainsNone(derived().index(code), range);
497 [[nodiscard]]
bool semanticsContainsNone(Key key, SemanticRange range)
const
499 return semanticsContainsNone(derived().index(key), range);
502 [[nodiscard]]
bool semanticsContainsNone(Point coord, SemanticRange range,
503 depth_t depth = 0)
const
505 return semanticsContainsNone(derived().index(coord, depth), range);
512 [[nodiscard]]
bool semanticsContainsSome(Index node, SemanticRange range)
const
514 assert(semantics_.size() > node.pos && N > node.offset);
518 [[nodiscard]]
bool semanticsContainsSome(Node node, SemanticRange range)
const
520 return semanticsContainsSome(derived().index(node), range);
523 [[nodiscard]]
bool semanticsContainsSome(Code code, SemanticRange range)
const
525 return semanticsContainsSome(derived().index(code), range);
528 [[nodiscard]]
bool semanticsContainsSome(Key key, SemanticRange range)
const
530 return semanticsContainsSome(derived().index(key), range);
533 [[nodiscard]]
bool semanticsContainsSome(Point coord, SemanticRange range,
534 depth_t depth = 0)
const
536 return semanticsContainsSome(derived().index(coord, depth), range);
543 void semanticsSet(Index node, SemanticSet<1>
const& semantics)
547 [
this, &semantics](Index node) {
549 semantics_[node.pos].semantics.set(node.offset, semantics);
551 [
this, &semantics](pos_t block) {
553 semantics_[block].semantics.set(semantics);
557 Node semanticsSet(Node node, SemanticSet<1>
const& semantics,
bool propagate =
true)
559 return derived().apply(
561 [
this, &semantics](Index node) {
563 semantics_[node.pos].semantics.set(node.offset, semantics);
565 [
this, &semantics](pos_t block) {
567 semantics_[block].semantics.set(semantics);
572 Node semanticsSet(Code code, SemanticSet<1>
const& semantics,
bool propagate =
true)
574 return derived().apply(
576 [
this, &semantics](Index node) {
578 semantics_[node.pos].semantics.set(node.offset, semantics);
580 [
this, &semantics](pos_t block) {
582 semantics_[block].semantics.set(semantics);
587 Node semanticsSet(Key key, SemanticSet<1>
const& semantics,
bool propagate =
true)
589 return semanticsSet(derived().toCode(key), semantics, propagate);
592 Node semanticsSet(Point coord, SemanticSet<1>
const& semantics,
bool propagate =
true,
595 return semanticsSet(derived().toCode(coord, depth), semantics, propagate);
602 void semanticsInsert(Index node, Semantic sem)
604 return derived().apply(
606 [
this, sem](Index node) {
608 semantics_[node.pos].semantics.insert(node.offset, sem);
610 [
this, sem](pos_t block) {
612 semantics_[block].semantics.insert(sem);
616 void semanticsInsert(Index node, label_t label, value_t value)
618 return semanticsInsert(node, Semantic(label, value));
621 template <
class InputIt>
622 void semanticsInsert(Index node, InputIt first, InputIt last)
627 template <
class SemanticRange>
628 void semanticsInsert(Index node, SemanticRange
const& sems)
630 semanticsInsert(node, std::cbegin(sems), std::cend(sems));
633 void semanticsInsert(Index node, std::initializer_list<Semantic> ilist)
635 semanticsInsert(node, std::cbegin(ilist), std::cend(ilist));
638 Node semanticsInsert(Node node, Semantic sem,
bool propagate =
true)
640 return derived().apply(
642 [
this, sem](Index node) {
644 semantics_[node.pos].semantics.insert(node.offset, sem);
646 [
this, sem](pos_t block) {
648 semantics_[block].semantics.insert(sem);
653 Node semanticsInsert(Node node, label_t label, value_t value,
bool propagate =
true)
655 return semanticsInsert(node, Semantic(label, value), propagate);
658 Node semanticsInsert(Code code, Semantic sem,
bool propagate =
true)
660 return derived().apply(
662 [
this, sem](Index node) {
664 semantics_[node.pos].semantics.insert(node.offset, sem);
666 [
this, sem](pos_t block) {
668 semantics_[block].semantics.insert(sem);
673 Node semanticsInsert(Code code, label_t label, value_t value,
bool propagate =
true)
675 return semanticsInsert(code, Semantic(label, value), propagate);
678 Node semanticsInsert(Key key, Semantic value,
bool propagate =
true)
680 return semanticsInsert(derived().toCode(key), value, propagate);
683 Node semanticsInsert(Key key, label_t label, value_t value,
bool propagate =
true)
685 return semanticsInsert(key, Semantic(label, value), propagate);
688 Node semanticsInsert(Point coord, Semantic value,
bool propagate =
true,
691 return semanticsInsert(derived().toCode(coord, depth), value, propagate);
694 Node semanticsInsert(Point coord, label_t label, value_t value,
bool propagate =
true,
697 return semanticsInsert(coord, Semantic(label, value), propagate, depth);
704 void semanticsInsertOrAssign(Index node, Semantic sem)
709 void semanticsInsertOrAssign(Index node, label_t label, value_t value)
711 semanticsInsertOrAssign(node, Semantic(label, value));
714 template <
class InputIt>
715 void semanticsInsertOrAssign(Index node, InputIt first, InputIt last)
720 template <
class SemanticRange>
721 void semanticsInsertOrAssign(Index node, SemanticRange
const& sems)
723 semanticsInsertOrAssign(node, std::cbegin(sems), std::cend(sems));
726 void semanticsInsertOrAssign(Index node, std::initializer_list<Semantic> ilist)
728 semanticsInsert(node, std::cbegin(ilist), std::cend(ilist));
737 std::enable_if_t<std::is_invocable_r_v<value_t, UnaryFun, Semantic>,
bool> =
true>
738 void semanticsInsertOrUpdate(Index node, Semantic sem, UnaryFun f)
745 std::enable_if_t<std::is_invocable_r_v<value_t, UnaryFun, Semantic>,
bool> =
true>
746 void semanticsInsertOrUpdate(Index node, label_t label, value_t value, UnaryFun f)
748 semanticsInsertOrUpdate(node, Semantic(label, value), f);
752 class InputIt,
class UnaryFun,
753 std::enable_if_t<std::is_invocable_r_v<value_t, UnaryFun, Semantic>,
bool> =
true>
754 void semanticsInsertOrUpdate(Index node, InputIt first, InputIt last, UnaryFun f)
760 class SemanticRange,
class UnaryFun,
761 std::enable_if_t<std::is_invocable_r_v<value_t, UnaryFun, Semantic>,
bool> =
true>
762 void semanticsInsertOrUpdate(Index node, SemanticRange
const& sems, UnaryFun f)
764 semanticsInsertOrUpdate(node, std::cbegin(sems), std::cend(sems), f);
769 std::enable_if_t<std::is_invocable_r_v<value_t, UnaryFun, Semantic>,
bool> =
true>
770 void semanticsInsertOrUpdate(Index node, std::initializer_list<Semantic> ilist,
773 semanticsInsertOrUpdate(node, std::cbegin(ilist), std::cend(ilist), f);
780 void semanticsAssign(Index node, value_t value)
785 void semanticsAssign(Index node, std::string
const& tag, value_t value)
790 void semanticsAssign(Index node, SemanticRange range, value_t value)
795 void semanticsAssign(Index node, SemanticRangeSet
const& ranges, value_t value)
806 std::enable_if_t<std::is_invocable_r_v<value_t, UnaryFun, Semantic>,
bool> =
true>
807 void semanticsUpdate(Index node, UnaryFun f)
814 std::enable_if_t<std::is_invocable_r_v<value_t, UnaryFun, Semantic>,
bool> =
true>
815 void semanticsUpdate(Index node, std::string
const& tag, UnaryFun f)
838 void semanticsClear(
bool propagate =
true)
840 semanticsClear(derived().rootCode(), propagate);
843 void semanticsClear(Index node)
848 Node semanticsClear(Node node,
bool propagate =
true)
853 Node semanticsClear(Code code,
bool propagate =
true)
858 Node semanticsClear(Key key,
bool propagate =
true)
860 return semanticsClear(derived().toCode(key), propagate);
863 Node semanticsClear(Point coord,
bool propagate =
true, depth_t depth = 0)
865 return semanticsClear(derived().toCode(coord, depth), propagate);
876 template <
class InputIt>
877 void insertPoints(Index node, InputIt first, InputIt last)
879 for (
auto it = first; it != last; ++it) {
880 insertSemantics(node, it->label, it->value);
888 [[nodiscard]]
bool containsSemantics(Index node, label_t label)
const
890 switch (semanticsPropagationCriteria()) {
891 case PropagationCriteria::MIN:
892 case PropagationCriteria::MAX:
893 return semantics_[node.pos].semantic_set.contains(node.offset, label);
894 case PropagationCriteria::NONE:
895 case PropagationCriteria::S_MIN:
896 case PropagationCriteria::S_MAX: {
897 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
899 return semantics_[node.pos].semantic_set.contains(node.offset, label);
902 for (offset_t i = 0; i != N; ++i) {
903 auto child = derived().child(node, i);
904 if (containsSemantics(child, label)) {
920 template <
class InputIt>
921 [[nodiscard]]
bool allSemantics(Index node, InputIt first, InputIt last)
const
923 SemanticRangeSet ranges;
924 for (
auto it = first; it != last; ++it) {
925 ranges.insert(labels(*it));
927 return allSemantics(node, ranges);
930 [[nodiscard]]
bool allSemantics(Index node, SemanticRangeSet ranges)
const
932 switch (semanticsPropagationCriteria()) {
933 case PropagationCriteria::MIN:
934 case PropagationCriteria::MAX:
935 return semantics_[node.pos].semantic_set.all(node.offset, ranges);
937 case PropagationCriteria::NONE:
938 case PropagationCriteria::S_MIN:
939 case PropagationCriteria::S_MAX: {
940 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
942 return semantics_[node.pos].semantic_set.all(node.offset, ranges);
945 for (offset_t i = 0; i != N; ++i) {
946 auto child = derived().child(node, i);
947 if (allSemantics(child, ranges)) {
963 template <
class InputIt>
964 [[nodiscard]]
bool anySemantics(Index node, InputIt first, InputIt last)
const
966 SemanticRangeSet ranges;
967 for (
auto it = first; it != last; ++it) {
968 auto ls = labels(*it);
969 ranges.insert(ls.begin(), ls.end());
971 return anySemantics(node, ranges);
974 [[nodiscard]]
bool anySemantics(Index node, SemanticRangeSet ranges)
const
976 switch (semanticsPropagationCriteria()) {
977 case PropagationCriteria::MIN:
978 case PropagationCriteria::MAX:
979 return semantics_[node.pos].semantic_set.any(node.offset, ranges);
981 case PropagationCriteria::NONE:
982 case PropagationCriteria::S_MIN:
983 case PropagationCriteria::S_MAX: {
984 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
986 return semantics_[node.pos].semantic_set.any(node.offset, ranges);
989 for (offset_t i = 0; i != N; ++i) {
990 auto child = derived().child(node, i);
991 if (anySemantics(child, ranges)) {
1007 template <
class InputIt>
1008 [[nodiscard]]
bool noneSemantics(Index node, InputIt first, InputIt last)
const
1010 SemanticRangeSet ranges;
1011 for (
auto it = first; it != last; ++it) {
1012 ranges.insert(labels(*it));
1014 return noneSemantics(node, ranges);
1017 [[nodiscard]]
bool noneSemantics(Index node, SemanticRangeSet ranges)
const
1019 switch (semanticsPropagationCriteria()) {
1020 case PropagationCriteria::MIN:
1021 case PropagationCriteria::MAX:
1022 return semantics_[node.pos].semantic_set.none(node.offset, ranges);
1024 case PropagationCriteria::NONE:
1025 case PropagationCriteria::S_MIN:
1026 case PropagationCriteria::S_MAX: {
1027 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1029 return semantics_[node.pos].semantic_set.none(node.offset, ranges);
1032 for (offset_t i = 0; i != N; ++i) {
1033 auto child = derived().child(node, i);
1034 if (!noneSemantics(child, ranges)) {
1049 void insertSemantics(Index node, label_t label, value_t value)
1051 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1054 [
this, label, value](Index node) {
1055 semantics_[node.pos].semantic_set.insert(node.offset, label, value);
1057 [
this, label, value](pos_t pos) {
1058 semantics_[pos].semantic_set.insert(label, value);
1061 for (offset_t i{}; i != N; ++i) {
1062 insertSemantics(derived().child(node, i), label, value);
1067 Node insertSemantics(Node node, label_t label, value_t value,
bool propagate =
true)
1069 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1070 return derived().apply(
1072 [
this, label, value](Index node) {
1073 semantics_[node.pos].semantic_set.insert(node.offset, label, value);
1075 [
this, label, value](pos_t pos) {
1076 semantics_[pos].semantic_set.insert(label, value);
1080 for (offset_t i{}; i != N; ++i) {
1081 insertSemantics(derived().child(node, i), label, value, propagate);
1087 Node insertSemantics(Code code, label_t label, value_t value,
bool propagate =
true)
1089 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
1090 return derived().apply(
1092 [
this, label, value](Index node) {
1093 semantics_[node.pos].semantic_set.insert(node.offset, label, value);
1095 [
this, label, value](pos_t pos) {
1096 semantics_[pos].semantic_set.insert(label, value);
1100 for (offset_t i{}; i != N; ++i) {
1101 insertSemantics(code.child(i), label, value, propagate);
1103 return derived()(code);
1107 Node insertSemantics(Key key, label_t label, value_t value,
bool propagate =
true)
1109 return insertSemantics(derived().toCode(key), label, value, propagate);
1112 Node insertSemantics(Point coord, label_t label, value_t value,
bool propagate =
true,
1115 return insertSemantics(derived().toCode(coord, depth), label, value, propagate);
1118 Node insertSemantics(Node node, Semantic semantic,
bool propagate =
true)
1120 return insertSemantics(node, semantic.label, semantic.value, propagate);
1123 Node insertSemantics(Code code, Semantic semantic,
bool propagate =
true)
1125 return insertSemantics(code, semantic.label, semantic.value, propagate);
1128 Node insertSemantics(Key key, Semantic semantic,
bool propagate =
true)
1130 return insertSemantics(derived().toCode(key), semantic, propagate);
1133 Node insertSemantics(Point coord, Semantic semantic,
bool propagate =
true,
1136 return insertSemantics(derived().toCode(coord, depth), semantic, propagate);
1139 template <
class InputIt,
1140 typename = std::enable_if_t<std::is_base_of_v<
1141 std::input_iterator_tag,
1142 typename std::iterator_traits<InputIt>::iterator_category>>>
1143 void insertSemantics(Index node, InputIt first, InputIt last)
1145 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1148 [
this, first, last](Index node) {
1149 semantics_[node.pos].semantic_set.insert(node.offset, first, last);
1151 [
this, first, last](pos_t pos) {
1152 semantics_[pos].semantic_set.insert(first, last);
1155 for (offset_t i{}; i != N; ++i) {
1156 insertSemantics(derived().child(node, i), first, last);
1161 template <
class InputIt,
1162 typename = std::enable_if_t<std::is_base_of_v<
1163 std::input_iterator_tag,
1164 typename std::iterator_traits<InputIt>::iterator_category>>>
1165 Node insertSemantics(Node node, InputIt first, InputIt last,
bool propagate =
true)
1167 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1168 return derived().apply(
1170 [
this, first, last](Index node) {
1171 semantics_[node.pos].semantic_set.insert(node.offset, first, last);
1173 [
this, first, last](pos_t pos) {
1174 semantics_[pos].semantic_set.insert(first, last);
1178 for (offset_t i{}; i != N; ++i) {
1179 insertSemantics(derived().child(node, i), first, last, propagate);
1185 template <
class InputIt,
1186 typename = std::enable_if_t<std::is_base_of_v<
1187 std::input_iterator_tag,
1188 typename std::iterator_traits<InputIt>::iterator_category>>>
1189 Node insertSemantics(Code code, InputIt first, InputIt last,
bool propagate =
true)
1191 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
1192 return derived().apply(
1194 [
this, first, last](Index node) {
1195 semantics_[node.pos].semantic_set.insert(node.offset, first, last);
1197 [
this, first, last](pos_t pos) {
1198 semantics_[pos].semantic_set.insert(first, last);
1202 for (offset_t i{}; i != N; ++i) {
1203 insertSemantics(code.child(i), first, last, propagate);
1205 return derived()(code);
1209 template <
class InputIt,
1210 typename = std::enable_if_t<std::is_base_of_v<
1211 std::input_iterator_tag,
1212 typename std::iterator_traits<InputIt>::iterator_category>>>
1213 Node insertSemantics(Key key, InputIt first, InputIt last,
bool propagate =
true)
1215 return insertSemantics(derived().toCode(key), first, last, propagate);
1218 template <
class InputIt,
1219 typename = std::enable_if_t<std::is_base_of_v<
1220 std::input_iterator_tag,
1221 typename std::iterator_traits<InputIt>::iterator_category>>>
1222 Node insertSemantics(Point coord, InputIt first, InputIt last,
bool propagate =
true,
1225 return insertSemantics(derived().toCode(coord, depth), first, last, propagate);
1228 Node insertSemantics(Node node, std::initializer_list<Semantic> ilist,
1229 bool propagate =
true)
1231 return insertSemantics(node, std::cbegin(ilist), std::cend(ilist), propagate);
1234 Node insertSemantics(Code code, std::initializer_list<Semantic> ilist,
1235 bool propagate =
true)
1237 return insertSemantics(code, std::cbegin(ilist), std::cend(ilist), propagate);
1240 Node insertSemantics(Key key, std::initializer_list<Semantic> ilist,
1241 bool propagate =
true)
1243 return insertSemantics(derived().toCode(key), ilist, propagate);
1246 Node insertSemantics(Point coord, std::initializer_list<Semantic> ilist,
1247 bool propagate =
true, depth_t depth = 0)
1249 return insertSemantics(derived().toCode(coord, depth), ilist, propagate);
1255 void insertOrAssignSemantics(Index node, label_t label, value_t value)
1257 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1260 [
this, label, value](Index node) {
1261 semantics_[node.pos].semantic_set.insertOrAssign(node.offset, label, value);
1263 [
this, label, value](pos_t pos) {
1264 semantics_[pos].semantic_set.insertOrAssign(label, value);
1267 for (offset_t i{}; i != N; ++i) {
1268 insertOrAssignSemantics(derived().child(node, i), label, value);
1273 Node insertOrAssignSemantics(Node node, label_t label, value_t value,
1274 bool propagate =
true)
1276 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1277 return derived().apply(
1279 [
this, label, value](Index node) {
1280 semantics_[node.pos].semantic_set.insertOrAssign(node.offset, label,
1283 [
this, label, value](pos_t pos) {
1284 semantics_[pos].semantic_set.insertOrAssign(label, value);
1288 for (offset_t i{}; i != N; ++i) {
1289 insertOrAssignSemantics(derived().child(node, i), label, value, propagate);
1295 Node insertOrAssignSemantics(Code code, label_t label, value_t value,
1296 bool propagate =
true)
1298 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
1299 return derived().apply(
1301 [
this, label, value](Index node) {
1302 semantics_[node.pos].semantic_set.insertOrAssign(node.offset, label, value);
1304 [
this, label, value](pos_t pos) {
1305 semantics_[pos].semantic_set.insertOrAssign(label, value);
1309 for (offset_t i{}; i != N; ++i) {
1310 insertOrAssignSemantics(code.child(i), label, value, propagate);
1312 return derived()(code);
1316 Node insertOrAssignSemantics(Key key, label_t label, value_t value,
1317 bool propagate =
true)
1319 return insertOrAssignSemantics(derived().toCode(key), label, value, propagate);
1322 Node insertOrAssignSemantics(Point coord, label_t label, value_t value,
1323 bool propagate =
true, depth_t depth = 0)
1325 return insertOrAssignSemantics(derived().toCode(coord, depth), label, value,
1329 Node insertOrAssignSemantics(Node node, Semantic semantic,
bool propagate =
true)
1331 return insertOrAssignSemantics(node, semantic.label, semantic.value, propagate);
1334 Node insertOrAssignSemantics(Code code, Semantic semantic,
bool propagate =
true)
1336 return insertOrAssignSemantics(code, semantic.label, semantic.value, propagate);
1339 Node insertOrAssignSemantics(Key key, Semantic semantic,
bool propagate =
true)
1341 return insertOrAssignSemantics(derived().toCode(key), semantic, propagate);
1344 Node insertOrAssignSemantics(Point coord, Semantic semantic,
bool propagate =
true,
1347 return insertOrAssignSemantics(derived().toCode(coord, depth), semantic, propagate);
1350 template <
class InputIt,
1351 typename = std::enable_if_t<std::is_base_of_v<
1352 std::input_iterator_tag,
1353 typename std::iterator_traits<InputIt>::iterator_category>>>
1354 void insertOrAssignSemantics(Index node, InputIt first, InputIt last)
1356 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1359 [
this, first, last](Index node) {
1360 semantics_[node.pos].semantic_set.insertOrAssign(node.offset, first, last);
1362 [
this, first, last](pos_t pos) {
1363 semantics_[pos].semantic_set.insertOrAssign(first, last);
1366 for (offset_t i{}; i != N; ++i) {
1367 insertOrAssignSemantics(derived().child(node, i), first, last);
1372 template <
class InputIt,
1373 typename = std::enable_if_t<std::is_base_of_v<
1374 std::input_iterator_tag,
1375 typename std::iterator_traits<InputIt>::iterator_category>>>
1376 Node insertOrAssignSemantics(Node node, InputIt first, InputIt last,
1377 bool propagate =
true)
1379 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1380 return derived().apply(
1382 [
this, first, last](Index node) {
1383 semantics_[node.pos].semantic_set.insertOrAssign(node.offset, first, last);
1385 [
this, first, last](pos_t pos) {
1386 semantics_[pos].semantic_set.insertOrAssign(first, last);
1390 for (offset_t i{}; i != N; ++i) {
1391 insertOrAssignSemantics(derived().child(node, i), first, last, propagate);
1397 template <
class InputIt,
1398 typename = std::enable_if_t<std::is_base_of_v<
1399 std::input_iterator_tag,
1400 typename std::iterator_traits<InputIt>::iterator_category>>>
1401 Node insertOrAssignSemantics(Code code, InputIt first, InputIt last,
1402 bool propagate =
true)
1404 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
1405 return derived().apply(
1407 [
this, first, last](Index node) {
1408 semantics_[node.pos].semantic_set.insertOrAssign(node.offset, first, last);
1410 [
this, first, last](pos_t pos) {
1411 semantics_[pos].semantic_set.insertOrAssign(first, last);
1415 for (offset_t i{}; i != N; ++i) {
1416 insertOrAssignSemantics(code.child(i), first, last, propagate);
1418 return derived()(code);
1422 template <
class InputIt,
1423 typename = std::enable_if_t<std::is_base_of_v<
1424 std::input_iterator_tag,
1425 typename std::iterator_traits<InputIt>::iterator_category>>>
1426 Node insertOrAssignSemantics(Key key, InputIt first, InputIt last,
1427 bool propagate =
true)
1429 return insertOrAssignSemantics(derived().toCode(key), first, last, propagate);
1432 template <
class InputIt,
1433 typename = std::enable_if_t<std::is_base_of_v<
1434 std::input_iterator_tag,
1435 typename std::iterator_traits<InputIt>::iterator_category>>>
1436 Node insertOrAssignSemantics(Point coord, InputIt first, InputIt last,
1437 bool propagate =
true, depth_t depth = 0)
1439 return insertOrAssignSemantics(derived().toCode(coord, depth), first, last,
1443 Node insertOrAssignSemantics(Node node, std::initializer_list<Semantic> ilist,
1444 bool propagate =
true)
1446 return insertOrAssignSemantics(node, std::begin(ilist), std::end(ilist), propagate);
1449 Node insertOrAssignSemantics(Code code, std::initializer_list<Semantic> ilist,
1450 bool propagate =
true)
1452 return insertOrAssignSemantics(code, std::begin(ilist), std::end(ilist), propagate);
1455 Node insertOrAssignSemantics(Key key, std::initializer_list<Semantic> ilist,
1456 bool propagate =
true)
1458 return insertOrAssignSemantics(derived().toCode(key), std::begin(ilist),
1459 std::end(ilist), propagate);
1462 Node insertOrAssignSemantics(Point coord, std::initializer_list<Semantic> ilist,
1463 bool propagate =
true, depth_t depth = 0)
1465 return insertOrAssignSemantics(derived().toCode(coord, depth), std::begin(ilist),
1466 std::end(ilist), propagate);
1469 template <
class UnaryFunction,
1470 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1471 void insertOrAssignSemantics(Index node, label_t label, UnaryFunction f)
1473 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1476 [
this, label, f](Index node) {
1477 semantics_[node.pos].semantic_set.insertOrAssign(node.offset, label, f);
1479 [
this, label, f](pos_t pos) {
1480 semantics_[pos].semantic_set.insertOrAssign(label, f);
1483 for (offset_t i{}; i != N; ++i) {
1484 insertOrAssignSemantics(derived().child(node, i), label, f);
1489 template <
class UnaryFunction,
1490 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1491 Node insertOrAssignSemantics(Node node, label_t label, UnaryFunction f,
1492 bool propagate =
true)
1494 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1495 return derived().apply(
1497 [
this, label, f](Index node) {
1498 semantics_[node.pos].semantic_set.insertOrAssign(node.offset, label, f);
1500 [
this, label, f](pos_t pos) {
1501 semantics_[pos].semantic_set.insertOrAssign(label, f);
1505 for (offset_t i{}; i != N; ++i) {
1506 insertOrAssignSemantics(derived().child(node, i), label, f, propagate);
1512 template <
class UnaryFunction,
1513 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1514 Node insertOrAssignSemantics(Code code, label_t label, UnaryFunction f,
1515 bool propagate =
true)
1517 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
1518 return derived().apply(
1520 [
this, label, f](Index node) {
1521 semantics_[node.pos].semantic_set.insertOrAssign(node.offset, label, f);
1523 [
this, label, f](pos_t pos) {
1524 semantics_[pos].semantic_set.insertOrAssign(label, f);
1528 for (offset_t i{}; i != N; ++i) {
1529 insertOrAssignSemantics(code.child(i), label, f, propagate);
1531 return derived()(code);
1535 template <
class UnaryFunction,
1536 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1537 Node insertOrAssignSemantics(Key key, label_t label, UnaryFunction f,
1538 bool propagate =
true)
1540 return insertOrAssignSemantics(derived().toCode(key), label, f, propagate);
1543 template <
class UnaryFunction,
1544 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1545 Node insertOrAssignSemantics(Point coord, label_t label, UnaryFunction f,
1546 bool propagate =
true, depth_t depth = 0)
1548 return insertOrAssignSemantics(derived().toCode(coord, depth), label, f, propagate);
1551 template <
class InputIt,
class UnaryFunction,
1552 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>,
1553 typename = std::enable_if_t<std::is_base_of_v<
1554 std::input_iterator_tag,
1555 typename std::iterator_traits<InputIt>::iterator_category>>>
1556 void insertOrAssignSemantics(Index node, InputIt first, InputIt last, UnaryFunction f)
1558 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1561 [
this, first, last, f](Index node) {
1562 semantics_[node.pos].semantic_set.insertOrAssign(node.offset, first, last, f);
1564 [
this, first, last, f](pos_t pos) {
1565 semantics_[pos].semantic_set.insertOrAssign(first, last, f);
1568 for (offset_t i{}; i != N; ++i) {
1569 insertOrAssignSemantics(derived().child(node, i), first, last, f);
1574 template <
class InputIt,
class UnaryFunction,
1575 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>,
1576 typename = std::enable_if_t<std::is_base_of_v<
1577 std::input_iterator_tag,
1578 typename std::iterator_traits<InputIt>::iterator_category>>>
1579 Node insertOrAssignSemantics(Node node, InputIt first, InputIt last, UnaryFunction f,
1580 bool propagate =
true)
1582 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1583 return derived().apply(
1585 [
this, first, last, f](Index node) {
1586 semantics_[node.pos].semantic_set.insertOrAssign(node.offset, first, last, f);
1588 [
this, first, last, f](pos_t pos) {
1589 semantics_[pos].semantic_set.insertOrAssign(first, last, f);
1593 for (offset_t i{}; i != N; ++i) {
1594 insertOrAssignSemantics(derived().child(node, i), first, last, f, propagate);
1600 template <
class InputIt,
class UnaryFunction,
1601 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>,
1602 typename = std::enable_if_t<std::is_base_of_v<
1603 std::input_iterator_tag,
1604 typename std::iterator_traits<InputIt>::iterator_category>>>
1605 Node insertOrAssignSemantics(Code code, InputIt first, InputIt last, UnaryFunction f,
1606 bool propagate =
true)
1608 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
1609 return derived().apply(
1611 [
this, first, last, f](Index node) {
1612 semantics_[node.pos].semantic_set.insertOrAssign(node.offset, first, last, f);
1614 [
this, first, last, f](pos_t pos) {
1615 semantics_[pos].semantic_set.insertOrAssign(first, last, f);
1619 for (offset_t i{}; i != N; ++i) {
1620 insertOrAssignSemantics(code.child(i), first, last, f, propagate);
1622 return derived()(code);
1626 template <
class InputIt,
class UnaryFunction,
1627 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>,
1628 typename = std::enable_if_t<std::is_base_of_v<
1629 std::input_iterator_tag,
1630 typename std::iterator_traits<InputIt>::iterator_category>>>
1631 Node insertOrAssignSemantics(Key key, InputIt first, InputIt last, UnaryFunction f,
1632 bool propagate =
true)
1634 return insertOrAssignSemantics(derived().toCode(key), first, last, f, propagate);
1637 template <
class InputIt,
class UnaryFunction,
1638 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>,
1639 typename = std::enable_if_t<std::is_base_of_v<
1640 std::input_iterator_tag,
1641 typename std::iterator_traits<InputIt>::iterator_category>>>
1642 Node insertOrAssignSemantics(Point coord, InputIt first, InputIt last, UnaryFunction f,
1643 bool propagate =
true, depth_t depth = 0)
1645 return insertOrAssignSemantics(derived().toCode(coord, depth), first, last, f,
1649 template <
class UnaryFunction,
1650 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1651 Node insertOrAssignSemantics(Node node, std::initializer_list<label_t> ilist,
1652 UnaryFunction f,
bool propagate =
true)
1654 return insertOrAssignSemantics(node, std::begin(ilist), std::end(ilist), f,
1658 template <
class UnaryFunction,
1659 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1660 Node insertOrAssignSemantics(Code code, std::initializer_list<label_t> ilist,
1661 UnaryFunction f,
bool propagate =
true)
1663 return insertOrAssignSemantics(code, std::begin(ilist), std::end(ilist), f,
1667 template <
class UnaryFunction,
1668 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1669 Node insertOrAssignSemantics(Key key, std::initializer_list<label_t> ilist,
1670 UnaryFunction f,
bool propagate =
true)
1672 return insertOrAssignSemantics(derived().toCode(key), std::begin(ilist),
1673 std::end(ilist), f, propagate);
1676 template <
class UnaryFunction,
1677 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1678 Node insertOrAssignSemantics(Point coord, std::initializer_list<label_t> ilist,
1679 UnaryFunction f,
bool propagate =
true, depth_t depth = 0)
1681 return insertOrAssignSemantics(derived().toCode(coord, depth), std::begin(ilist),
1682 std::end(ilist), f, propagate);
1688 void assignSemantics(Index node, std::string
const& tag, value_t value)
1690 assignSemantics(node, labels(tag), value);
1693 Node assignSemantics(Node node, std::string
const& tag, value_t value,
1694 bool propagate =
true)
1696 return assignSemantics(node, labels(tag), value);
1699 Node assignSemantics(Code code, std::string
const& tag, value_t value,
1700 bool propagate =
true)
1702 return assignSemantics(code, labels(tag), value);
1705 Node assignSemantics(Key key, std::string
const& tag, value_t value,
1706 bool propagate =
true)
1708 return assignSemantics(derived().toCode(key), tag, value, propagate);
1711 Node assignSemantics(Point coord, std::string
const& tag, value_t value,
1712 bool propagate =
true, depth_t depth = 0)
1714 return assignSemantics(derived().toCode(coord, depth), tag, value, propagate);
1717 template <
class UnaryFunction,
1718 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1719 void assignSemantics(Index node, std::string
const& tag, UnaryFunction f)
1721 assignSemantics(node, labels(tag), f);
1724 template <
class UnaryFunction,
1725 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1726 Node assignSemantics(Node node, std::string
const& tag, UnaryFunction f,
1727 bool propagate =
true)
1729 return assignSemantics(node, labels(tag), f);
1732 template <
class UnaryFunction,
1733 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1734 Node assignSemantics(Code code, std::string
const& tag, UnaryFunction f,
1735 bool propagate =
true)
1737 return assignSemantics(code, labels(tag), f);
1740 template <
class UnaryFunction,
1741 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1742 Node assignSemantics(Key key, std::string
const& tag, UnaryFunction f,
1743 bool propagate =
true)
1745 return assignSemantics(derived().toCode(key), tag, f, propagate);
1748 template <
class UnaryFunction,
1749 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1750 Node assignSemantics(Point coord, std::string
const& tag, UnaryFunction f,
1751 bool propagate =
true, depth_t depth = 0)
1753 return assignSemantics(derived().toCode(coord, depth), tag, f, propagate);
1756 Node assignSemantics(Node node, SemanticRange range, value_t value,
1757 bool propagate =
true)
1759 return assignSemantics(node, SemanticRangeSet(range), value, propagate);
1762 Node assignSemantics(Code code, SemanticRange range, value_t value,
1763 bool propagate =
true)
1765 return assignSemantics(code, SemanticRangeSet(range), value, propagate);
1768 Node assignSemantics(Key key, SemanticRange range, value_t value,
bool propagate =
true)
1770 return assignSemantics(derived().toCode(key), range, value, propagate);
1773 Node assignSemantics(Point coord, SemanticRange range, value_t value,
1774 bool propagate =
true, depth_t depth = 0)
1776 return assignSemantics(derived().toCode(coord, depth), range, value, propagate);
1779 void assignSemantics(Index node, SemanticRangeSet
const& ranges, value_t value)
1781 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1784 [
this, ranges, value](Index node) {
1785 semantics_[node.pos].semantic_set.assign(node.offset, ranges, value);
1787 [
this, ranges, value](pos_t pos) {
1788 semantics_[pos].semantic_set.insertOrAssign(ranges, value);
1791 for (offset_t i{}; i != N; ++i) {
1792 assignSemantics(derived().child(node, i), ranges, value);
1797 Node assignSemantics(Node node, SemanticRangeSet
const& ranges, value_t value,
1798 bool propagate =
true)
1800 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1801 return derived().apply(
1803 [
this, ranges, value](Index node) {
1804 semantics_[node.pos].semantic_set.assign(node.offset, ranges, value);
1806 [
this, ranges, value](pos_t pos) {
1807 semantics_[pos].semantic_set.insertOrAssign(ranges, value);
1811 for (offset_t i{}; i != N; ++i) {
1812 assignSemantics(derived().child(node, i), ranges, value, propagate);
1818 Node assignSemantics(Code code, SemanticRangeSet
const& ranges, value_t value,
1819 bool propagate =
true)
1821 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
1822 return derived().apply(
1824 [
this, ranges, value](Index node) {
1825 semantics_[node.pos].semantic_set.assign(node.offset, ranges, value);
1827 [
this, ranges, value](pos_t pos) {
1828 semantics_[pos].semantic_set.assign(ranges, value);
1832 for (offset_t i{}; i != N; ++i) {
1833 assignSemantics(code.child(i), ranges, value, propagate);
1835 return derived()(code);
1839 Node assignSemantics(Key key, SemanticRangeSet
const& ranges, value_t value,
1840 bool propagate =
true)
1842 return assignSemantics(derived().toCode(key), ranges, value, propagate);
1845 Node assignSemantics(Point coord, SemanticRangeSet
const& ranges, value_t value,
1846 bool propagate =
true, depth_t depth = 0)
1848 return assignSemantics(derived().toCode(coord, depth), ranges, value, propagate);
1851 template <
class UnaryFunction,
1852 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1853 Node assignSemantics(Node node, SemanticRange range, UnaryFunction f,
1854 bool propagate =
true)
1856 return assignSemantics(node, SemanticRangeSet(range), f, propagate);
1859 template <
class UnaryFunction,
1860 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1861 Node assignSemantics(Code code, SemanticRange range, UnaryFunction f,
1862 bool propagate =
true)
1864 return assignSemantics(code, SemanticRangeSet(range), f, propagate);
1867 template <
class UnaryFunction,
1868 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1869 Node assignSemantics(Key key, SemanticRange range, UnaryFunction f,
1870 bool propagate =
true)
1872 return assignSemantics(derived().toCode(key), range, f, propagate);
1875 template <
class UnaryFunction,
1876 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1877 Node assignSemantics(Point coord, SemanticRange range, UnaryFunction f,
1878 bool propagate =
true, depth_t depth = 0)
1880 return assignSemantics(derived().toCode(coord, depth), range, f, propagate);
1883 template <
class UnaryFunction,
1884 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1885 void assignSemantics(Index node, SemanticRangeSet
const& ranges, UnaryFunction f)
1887 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1890 [
this, ranges, f](Index node) {
1891 semantics_[node.pos].semantic_set.assign(node.offset, ranges, f);
1893 [
this, ranges, f](pos_t pos) {
1894 semantics_[pos].semantic_set.insertOrAssign(ranges, f);
1897 for (offset_t i{}; i != N; ++i) {
1898 assignSemantics(derived().child(node, i), ranges, f);
1903 template <
class UnaryFunction,
1904 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1905 Node assignSemantics(Node node, SemanticRangeSet
const& ranges, UnaryFunction f,
1906 bool propagate =
true)
1908 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1909 return derived().apply(
1911 [
this, ranges, f](Index node) {
1912 semantics_[node.pos].semantic_set.assign(node.offset, ranges, f);
1914 [
this, ranges, f](pos_t pos) {
1915 semantics_[pos].semantic_set.assign(ranges, f);
1919 for (offset_t i{}; i != N; ++i) {
1920 assignSemantics(derived().child(node, i), ranges, f, propagate);
1926 template <
class UnaryFunction,
1927 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1928 Node assignSemantics(Code code, SemanticRangeSet
const& ranges, UnaryFunction f,
1929 bool propagate =
true)
1931 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
1932 return derived().apply(
1934 [
this, ranges, f](Index node) {
1935 semantics_[node.pos].semantic_set.assign(node.offset, ranges, f);
1937 [
this, ranges, f](pos_t pos) {
1938 semantics_[pos].semantic_set.assign(ranges, f);
1942 for (offset_t i{}; i != N; ++i) {
1943 assignSemantics(code.child(i), ranges, f, propagate);
1945 return derived()(code);
1949 template <
class UnaryFunction,
1950 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1951 Node assignSemantics(Key key, SemanticRangeSet
const& ranges, UnaryFunction f,
1952 bool propagate =
true)
1954 return assignSemantics(derived().toCode(key), ranges, f, propagate);
1957 template <
class UnaryFunction,
1958 class = std::enable_if_t<std::is_invocable<UnaryFunction, Semantic>::value>>
1959 Node assignSemantics(Point coord, SemanticRangeSet
const& ranges, UnaryFunction f,
1960 bool propagate =
true, depth_t depth = 0)
1962 return assignSemantics(derived().toCode(coord, depth), ranges, f, propagate);
1969 Node eraseSemantics(label_t label,
bool propagate =
true)
1971 return eraseSemantics(derived().rootCode(), label, propagate);
1974 void eraseSemantics(Index node, label_t label)
1976 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1979 [
this, label](Index node) {
1980 semantics_[node.pos].semantic_set.erase(node.offset, label);
1982 [
this, label](pos_t pos) { semantics_[pos].semantic_set.erase(label); });
1984 for (offset_t i{}; i != N; ++i) {
1985 eraseSemantics(derived().child(node, i), label);
1990 Node eraseSemantics(Node node, label_t label,
bool propagate =
true)
1992 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
1993 return derived().apply(
1995 [
this, label](Index node) {
1996 semantics_[node.pos].semantic_set.erase(node.offset, label);
1998 [
this, label](pos_t pos) { semantics_[pos].semantic_set.erase(label); },
2001 for (offset_t i{}; i != N; ++i) {
2002 eraseSemantics(derived().child(node, i), label, propagate);
2008 Node eraseSemantics(Code code, label_t label,
bool propagate =
true)
2010 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
2011 return derived().apply(
2013 [
this, label](Index node) {
2014 semantics_[node.pos].semantic_set.erase(node.offset, label);
2016 [
this, label](pos_t pos) { semantics_[pos].semantic_set.erase(label); },
2019 for (offset_t i{}; i != N; ++i) {
2020 eraseSemantics(code.child(i), label, propagate);
2022 return derived()(code);
2026 Node eraseSemantics(Key key, label_t label,
bool propagate =
true)
2028 return eraseSemantics(derived().toCode(key), label, propagate);
2031 Node eraseSemantics(Point coord, label_t label,
bool propagate =
true,
2034 return eraseSemantics(derived().toCode(coord, depth), label, propagate);
2037 template <
class InputIt,
2038 typename = std::enable_if_t<std::is_base_of_v<
2039 std::input_iterator_tag,
2040 typename std::iterator_traits<InputIt>::iterator_category>>>
2041 Node eraseSemantics(InputIt first, InputIt last,
bool propagate =
true)
2043 return eraseSemantics(derived().rootCode(), first, last, propagate);
2046 template <
class InputIt,
2047 typename = std::enable_if_t<std::is_base_of_v<
2048 std::input_iterator_tag,
2049 typename std::iterator_traits<InputIt>::iterator_category>>>
2050 Node eraseSemantics(Index node, InputIt first, InputIt last)
2052 return eraseSemantics(node, SemanticRangeSet(first, last));
2055 template <
class InputIt,
2056 typename = std::enable_if_t<std::is_base_of_v<
2057 std::input_iterator_tag,
2058 typename std::iterator_traits<InputIt>::iterator_category>>>
2059 Node eraseSemantics(Node node, InputIt first, InputIt last,
bool propagate =
true)
2061 return eraseSemantics(node, SemanticRangeSet(first, last));
2064 template <
class InputIt,
2065 typename = std::enable_if_t<std::is_base_of_v<
2066 std::input_iterator_tag,
2067 typename std::iterator_traits<InputIt>::iterator_category>>>
2068 Node eraseSemantics(Code code, InputIt first, InputIt last,
bool propagate =
true)
2070 return eraseSemantics(code, SemanticRangeSet(first, last));
2073 template <
class InputIt,
2074 typename = std::enable_if_t<std::is_base_of_v<
2075 std::input_iterator_tag,
2076 typename std::iterator_traits<InputIt>::iterator_category>>>
2077 Node eraseSemantics(Key key, InputIt first, InputIt last,
bool propagate =
true)
2079 return eraseSemantics(derived().toCode(key), first, last, propagate);
2082 template <
class InputIt,
2083 typename = std::enable_if_t<std::is_base_of_v<
2084 std::input_iterator_tag,
2085 typename std::iterator_traits<InputIt>::iterator_category>>>
2086 Node eraseSemantics(Point coord, InputIt first, InputIt last,
bool propagate =
true,
2089 return eraseSemantics(derived().toCode(coord, depth), first, last, propagate);
2092 Node eraseSemantics(std::initializer_list<label_t> ilist,
bool propagate =
true)
2094 return eraseSemantics(derived().rootCode(), ilist, propagate);
2097 void eraseSemantics(Index node, std::initializer_list<label_t> ilist)
2099 eraseSemantics(node, std::begin(ilist), std::end(ilist));
2102 Node eraseSemantics(Node node, std::initializer_list<label_t> ilist,
2103 bool propagate =
true)
2105 return eraseSemantics(node, std::begin(ilist), std::end(ilist), propagate);
2108 Node eraseSemantics(Code code, std::initializer_list<label_t> ilist,
2109 bool propagate =
true)
2111 return eraseSemantics(code, std::begin(ilist), std::end(ilist), propagate);
2114 Node eraseSemantics(Key key, std::initializer_list<label_t> ilist,
2115 bool propagate =
true)
2117 return eraseSemantics(derived().toCode(key), ilist, propagate);
2120 Node eraseSemantics(Point coord, std::initializer_list<label_t> ilist,
2121 bool propagate =
true, depth_t depth = 0)
2123 return eraseSemantics(derived().toCode(coord, depth), ilist, propagate);
2126 Node eraseSemantics(SemanticRange range,
bool propagate =
true)
2128 return eraseSemantics(derived().rootCode(), range, propagate);
2131 void eraseSemantics(Index node, SemanticRange range)
2133 eraseSemantics(node, SemanticRangeSet(range));
2136 Node eraseSemantics(Node node, SemanticRange range,
bool propagate =
true)
2138 return eraseSemantics(node, SemanticRangeSet(range), propagate);
2141 Node eraseSemantics(Code code, SemanticRange range,
bool propagate =
true)
2143 return eraseSemantics(code, SemanticRangeSet(range), propagate);
2146 Node eraseSemantics(Key key, SemanticRange range,
bool propagate =
true)
2148 return eraseSemantics(derived().toCode(key), range, propagate);
2151 Node eraseSemantics(Point coord, SemanticRange range,
bool propagate =
true,
2154 return eraseSemantics(derived().toCode(coord, depth), range, propagate);
2157 Node eraseSemantics(SemanticRangeSet
const& ranges,
bool propagate =
true)
2159 return eraseSemantics(derived().rootCode(), ranges, propagate);
2162 void eraseSemantics(Index node, SemanticRangeSet
const& ranges)
2164 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
2167 [
this, ranges](Index node) {
2168 semantics_[node.pos].semantic_set.erase(node.offset, ranges);
2170 [
this, ranges](pos_t pos) { semantics_[pos].semantic_set.erase(ranges); });
2172 for (offset_t i{}; i != N; ++i) {
2173 eraseSemantics(derived().child(node, i), ranges);
2178 Node eraseSemantics(Node node, SemanticRangeSet
const& ranges,
bool propagate =
true)
2180 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
2181 return derived().apply(
2183 [
this, ranges](Index node) {
2184 semantics_[node.pos].semantic_set.erase(node.offset, ranges);
2186 [
this, ranges](pos_t pos) { semantics_[pos].semantic_set.erase(ranges); },
2189 for (offset_t i{}; i != N; ++i) {
2190 eraseSemantics(derived().child(node, i), ranges, propagate);
2196 Node eraseSemantics(Code code, SemanticRangeSet
const& ranges,
bool propagate =
true)
2198 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
2199 return derived().apply(
2201 [
this, ranges](Index node) {
2202 semantics_[node.pos].semantic_set.erase(node.offset, ranges);
2204 [
this, ranges](pos_t pos) { semantics_[pos].semantic_set.erase(ranges); },
2207 for (offset_t i{}; i != N; ++i) {
2208 eraseSemantics(code.child(i), ranges, propagate);
2210 return derived()(code);
2214 Node eraseSemantics(Key key, SemanticRangeSet
const& ranges,
bool propagate =
true)
2216 return eraseSemantics(derived().toCode(key), ranges, propagate);
2219 Node eraseSemantics(Point coord, SemanticRangeSet
const& ranges,
bool propagate =
true,
2222 return eraseSemantics(derived().toCode(coord, depth), ranges, propagate);
2225 Node eraseSemantics(std::string
const& tag,
bool propagate =
true)
2227 return eraseSemantics(derived().rootCode(), tag, propagate);
2230 void eraseSemantics(Index node, std::string
const& tag)
2232 eraseSemantics(node, labels(tag));
2235 Node eraseSemantics(Node node, std::string
const& tag,
bool propagate =
true)
2237 return eraseSemantics(node, labels(tag));
2240 Node eraseSemantics(Code code, std::string
const& tag,
bool propagate =
true)
2242 return eraseSemantics(code, labels(tag));
2245 Node eraseSemantics(Key key, std::string
const& tag,
bool propagate =
true)
2247 return eraseSemantics(derived().toCode(key), tag, propagate);
2250 Node eraseSemantics(Point coord, std::string
const& tag,
bool propagate =
true,
2253 return eraseSemantics(derived().toCode(coord, depth), tag, propagate);
2260 template <
class UnaryPredicate,
2261 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2262 Node eraseIfSemantics(UnaryPredicate p,
bool propagate =
true)
2264 return eraseIfSemantics(derived().rootCode(), p, propagate);
2267 template <
class UnaryPredicate,
2268 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2269 void eraseIfSemantics(Index node, UnaryPredicate p)
2271 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
2274 [
this, p](Index node) {
2275 semantics_[node.pos].semantic_set.eraseIf(node.offset, p);
2277 [
this, p](pos_t pos) { semantics_[pos].semantic_set.eraseIf(p); });
2279 for (offset_t i{}; i != N; ++i) {
2280 eraseIfSemantics(derived().child(node, i), p);
2285 template <
class UnaryPredicate,
2286 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2287 Node eraseIfSemantics(Node node, UnaryPredicate p,
bool propagate =
true)
2289 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
2290 return derived().apply(
2292 [
this, p](Index node) {
2293 semantics_[node.pos].semantic_set.eraseIf(node.offset, p);
2295 [
this, p](pos_t pos) { semantics_[pos].semantic_set.eraseIf(p); }, propagate);
2297 for (offset_t i{}; i != N; ++i) {
2298 eraseIfSemantics(derived().child(node, i), p, propagate);
2304 template <
class UnaryPredicate,
2305 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2306 Node eraseIfSemantics(Code code, UnaryPredicate p,
bool propagate =
true)
2308 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
2309 return derived().apply(
2311 [
this, p](Index node) {
2312 semantics_[node.pos].semantic_set.eraseIf(node.offset, p);
2314 [
this, p](pos_t pos) { semantics_[pos].semantic_set.eraseIf(p); }, propagate);
2316 for (offset_t i{}; i != N; ++i) {
2317 eraseIfSemantics(code.child(i), p, propagate);
2319 return derived()(code);
2323 template <
class UnaryPredicate,
2324 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2325 Node eraseIfSemantics(Key key, UnaryPredicate p,
bool propagate =
true)
2327 return eraseIfSemantics(derived().toCode(key), p, propagate);
2330 template <
class UnaryPredicate,
2331 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2332 Node eraseIfSemantics(Point coord, UnaryPredicate p,
bool propagate =
true,
2335 return eraseIfSemantics(derived().toCode(coord, depth), p, propagate);
2338 template <
class UnaryPredicate,
2339 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2340 Node eraseIfSemantics(std::string
const& tag, UnaryPredicate p,
bool propagate =
true)
2342 return eraseIfSemantics(derived().rootCode(), tag, p, propagate);
2345 template <
class UnaryPredicate,
2346 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2347 void eraseIfSemantics(Index node, std::string
const& tag, UnaryPredicate p)
2349 eraseIfSemantics(node, labels(tag), p);
2352 template <
class UnaryPredicate,
2353 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2354 Node eraseIfSemantics(Node node, std::string
const& tag, UnaryPredicate p,
2355 bool propagate =
true)
2357 return eraseIfSemantics(node, labels(tag), p);
2360 template <
class UnaryPredicate,
2361 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2362 Node eraseIfSemantics(Code code, std::string
const& tag, UnaryPredicate p,
2363 bool propagate =
true)
2365 return eraseIfSemantics(code, labels(tag), p);
2368 template <
class UnaryPredicate,
2369 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2370 Node eraseIfSemantics(Key key, std::string
const& tag, UnaryPredicate p,
2371 bool propagate =
true)
2373 return eraseIfSemantics(derived().toCode(key), tag, p, propagate);
2376 template <
class UnaryPredicate,
2377 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2378 Node eraseIfSemantics(Point coord, std::string
const& tag, UnaryPredicate p,
2379 bool propagate =
true, depth_t depth = 0)
2381 return eraseIfSemantics(derived().toCode(coord, depth), tag, p, propagate);
2384 template <
class UnaryPredicate,
2385 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2386 Node eraseIfSemantics(SemanticRange range, UnaryPredicate p,
bool propagate =
true)
2388 return eraseIfSemantics(derived().rootCode(), range, p, propagate);
2391 template <
class UnaryPredicate,
2392 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2393 void eraseIfSemantics(Index node, SemanticRange range, UnaryPredicate p)
2395 eraseIfSemantics(node, SemanticRangeSet(range), p);
2398 template <
class UnaryPredicate,
2399 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2400 Node eraseIfSemantics(Node node, SemanticRange range, UnaryPredicate p,
2401 bool propagate =
true)
2403 return eraseIfSemantics(node, SemanticRangeSet(range), p, propagate);
2406 template <
class UnaryPredicate,
2407 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2408 Node eraseIfSemantics(Code code, SemanticRange range, UnaryPredicate p,
2409 bool propagate =
true)
2411 return eraseIfSemantics(code, SemanticRangeSet(range), p, propagate);
2414 template <
class UnaryPredicate,
2415 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2416 Node eraseIfSemantics(Key key, SemanticRange range, UnaryPredicate p,
2417 bool propagate =
true)
2419 return eraseIfSemantics(derived().toCode(key), range, p, propagate);
2422 template <
class UnaryPredicate,
2423 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2424 Node eraseIfSemantics(Point coord, SemanticRange range, UnaryPredicate p,
2425 bool propagate =
true, depth_t depth = 0)
2427 return eraseIfSemantics(derived().toCode(coord, depth), range, p, propagate);
2430 template <
class UnaryPredicate,
2431 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2432 Node eraseIfSemantics(SemanticRangeSet
const& ranges, UnaryPredicate p,
2433 bool propagate =
true)
2435 return eraseIfSemantics(derived().rootCode(), ranges, p, propagate);
2438 template <
class UnaryPredicate,
2439 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2440 void eraseIfSemantics(Index node, SemanticRangeSet
const& ranges, UnaryPredicate p)
2442 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
2445 [
this, ranges, p](Index node) {
2446 semantics_[node.pos].semantic_set.eraseIf(node.offset, ranges, p);
2448 [
this, ranges, p](pos_t pos) {
2449 semantics_[pos].semantic_set.eraseIf(ranges, p);
2452 for (offset_t i{}; i != N; ++i) {
2453 eraseIfSemantics(derived().child(node, i), ranges, p);
2458 template <
class UnaryPredicate,
2459 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2460 Node eraseIfSemantics(Node node, SemanticRangeSet
const& ranges, UnaryPredicate p,
2461 bool propagate =
true)
2463 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
2464 return derived().apply(
2466 [
this, ranges, p](Index node) {
2467 semantics_[node.pos].semantic_set.eraseIf(node.offset, ranges, p);
2469 [
this, ranges, p](pos_t pos) {
2470 semantics_[pos].semantic_set.eraseIf(ranges, p);
2474 for (offset_t i{}; i != N; ++i) {
2475 eraseIfSemantics(derived().child(node, i), ranges, p, propagate);
2481 template <
class UnaryPredicate,
2482 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2483 Node eraseIfSemantics(Code code, SemanticRangeSet
const& ranges, UnaryPredicate p,
2484 bool propagate =
true)
2486 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
2487 return derived().apply(
2489 [
this, ranges, p](Index node) {
2490 semantics_[node.pos].semantic_set.eraseIf(node.offset, ranges, p);
2492 [
this, ranges, p](pos_t pos) {
2493 semantics_[pos].semantic_set.eraseIf(ranges, p);
2497 for (offset_t i{}; i != N; ++i) {
2498 eraseIfSemantics(code.child(i), ranges, p, propagate);
2500 return derived()(code);
2504 template <
class UnaryPredicate,
2505 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2506 Node eraseIfSemantics(Key key, SemanticRangeSet
const& ranges, UnaryPredicate p,
2507 bool propagate =
true)
2509 return eraseIfSemantics(derived().toCode(key), ranges, p, propagate);
2512 template <
class UnaryPredicate,
2513 class = std::enable_if_t<std::is_invocable<UnaryPredicate, Semantic>::value>>
2514 Node eraseIfSemantics(Point coord, SemanticRangeSet
const& ranges, UnaryPredicate p,
2515 bool propagate =
true, depth_t depth = 0)
2517 return eraseIfSemantics(derived().toCode(coord, depth), ranges, p, propagate);
2526 semantics_.resize(1);
2527 semantics_.assign(1, Data());
2530 void clearImpl(pos_t block)
2532 semantics_[block].semantic_set.clear();
2533 semantics_[block].summary = Semantic();
2536 void clearSemantics(
bool propagate =
true)
2538 clearSemantics(derived().rootCode(), propagate);
2541 void clearSemantics(Index node)
2543 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
2546 [
this](Index node) {
2547 if (derived().isPureLeaf(node)) {
2548 semantics_[node.pos].semantic_set.clear(node.offset);
2551 [
this](pos_t block) { clearImpl(block); });
2553 for (offset_t i{}; i != N; ++i) {
2554 clearSemantics(derived().child(node, i));
2559 void clearSemantics(Node node,
bool propagate =
true)
2561 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
2564 [
this](Index node) {
2565 if (derived().isPureLeaf(node)) {
2566 semantics_[node.pos].semantic_set.clear(node.offset);
2569 [
this](pos_t block) { clearImpl(block); }, propagate);
2571 for (offset_t i{}; i != N; ++i) {
2572 clearSemantics(derived().child(node, i), propagate);
2577 void clearSemantics(Code code,
bool propagate =
true)
2579 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
2582 [
this](Index node) {
2583 if (derived().isPureLeaf(node)) {
2584 semantics_[node.pos].semantic_set.clear(node.offset);
2587 [
this](pos_t block) { clearImpl(block); }, propagate);
2589 for (offset_t i{}; i != N; ++i) {
2590 clearSemantics(code.child(i), propagate);
2595 void clearSemantics(Key key,
bool propagate =
true)
2597 clearSemantics(derived().toCode(key), propagate);
2600 void clearSemantics(Point coord,
bool propagate =
true, depth_t depth = 0)
2602 clearSemantics(derived().toCode(coord, depth), propagate);
2609 void changeSemantics(label_t old_label, label_t new_label,
bool propagate =
true)
2611 changeLabel(derived().rootCode(), old_label, new_label, propagate);
2614 void changeSemantics(Node node, label_t old_label, label_t new_label)
2616 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
2619 [
this, old_label, new_label](Index node) {
2620 semantics_[node.pos].semantic_set.changeLabel(node.offset, old_label,
2623 [
this, old_label, new_label](pos_t pos) {
2624 semantics_[pos].semantic_set.changeLabel(old_label, new_label);
2627 for (offset_t i{}; i != N; ++i) {
2628 changeSemantics(derived().child(node, i), old_label, new_label);
2633 void changeSemantics(Node node, label_t old_label, label_t new_label,
2634 bool propagate =
true)
2636 if (derived().isLeaf(node) || derived().isPureLeaf(node)) {
2639 [
this, old_label, new_label](Index node) {
2640 semantics_[node.pos].semantic_set.changeLabel(node.offset, old_label,
2643 [
this, old_label, new_label](pos_t pos) {
2644 semantics_[pos].semantic_set.changeLabel(old_label, new_label);
2648 for (offset_t i{}; i != N; ++i) {
2649 changeSemantics(derived().child(node, i), old_label, new_label, propagate);
2654 void changeSemantics(Code code, label_t old_label, label_t new_label,
2655 bool propagate =
true)
2657 if (derived().isLeaf(code) || derived().isPureLeaf(code)) {
2660 [
this, old_label, new_label](Index node) {
2661 semantics_[node.pos].semantic_set.changeLabel(node.offset, old_label,
2664 [
this, old_label, new_label](pos_t pos) {
2665 semantics_[pos].semantic_set.changeLabel(old_label, new_label);
2669 for (offset_t i{}; i != N; ++i) {
2670 changeSemantics(code.child(i), old_label, new_label, propagate);
2675 void changeSemantics(Key key, label_t old_label, label_t new_label,
2676 bool propagate =
true)
2678 changeSemantics(derived().toCode(key), old_label, new_label, propagate);
2681 void changeSemantics(Point coord, label_t old_label, label_t new_label,
2682 bool propagate =
true, depth_t depth = 0)
2684 changeSemantics(derived().toCode(coord, depth), old_label, new_label, propagate);
2691 [[nodiscard]]
constexpr PropagationCriteria semanticsPropagationCriteria()
2694 return prop_criteria_;
2697 void setSemanticsPropagationCriteria(PropagationCriteria prop_criteria,
2698 bool propagate =
true)
2700 if (prop_criteria_ == prop_criteria) {
2704 prop_criteria_ = prop_criteria;
2706 derived().setModified();
2709 derived().propagateModified();
2721 semantics_.emplace_back();
2724 SemanticSetMap(SemanticSetMap
const& other) =
default;
2726 SemanticSetMap(SemanticSetMap&& other) =
default;
2737 ~SemanticSetMap() {}
2743 SemanticSetMap& operator=(SemanticSetMap
const& rhs) =
default;
2745 SemanticSetMap& operator=(SemanticSetMap&& rhs) =
default;
2747 template <
class Derived2,
size_t N2>
2748 SemanticSetMap& operator=(SemanticSetMap<Derived22>
const& rhs)
2758 void swap(SemanticSetMap& other)
noexcept
2760 std::swap(semantics_, other.semantics_);
2761 std::swap(mapping_, other.mapping_);
2762 std::swap(prop_criteria_, other.prop_criteria_);
2769 [[nodiscard]]
constexpr Derived& derived() {
return *
static_cast<Derived*
>(
this); }
2771 [[nodiscard]]
constexpr Derived
const& derived()
const
2773 return *
static_cast<Derived const*
>(
this);
2780 void createBlock(Index node)
2783 value_t value_summary{};
2785 for (
auto s : ...) {
2789 semantics_.emplace_back(semantics_[node.pos].semantics.subset(node.offset),
2790 semantics_[node.pos].label_summary[node.offset],
2794 semanticsClear(node);
2801 void fill(Index node, pos_t children)
2805 switch (semanticsPropagationCriteria()) {
2806 case PropagationCriteria::MIN:
2807 case PropagationCriteria::MAX:
2808 semantics_[children].semantic_set.fill(semantics_[node.pos].semantic_set,
2811 case PropagationCriteria::NONE:
2812 case PropagationCriteria::S_MIN:
2813 case PropagationCriteria::S_MAX:
2814 if (derived().allPureLeaf(children) || derived().allLeaf(children)) {
2816 semantics_[children].semantic_set.fill(semantics_[node.pos].semantic_set,
2818 semantics_[children].summary = semantics_[node.pos].summary;
2821 semantics_[node.pos].semantic_set.clear(node.offset);
2830 semanticsClear(node);
2837 void resize(std::size_t count) { semantics_.resize(count); }
2843 void reserveImpl(std::size_t new_cap) { semantics_.reserve(new_cap); }
2861 void updateBlock(pos_t block, std::array<bool, N> modified_parent)
2864 if (derived().noneParent(block)) {
2868 for (offset_t i{}; N != i; ++i) {
2869 Index node{block, i};
2870 if (modified_parent[i]) {
2871 updateNode(node, derived().children(node));
2875 auto children = derived().children(block);
2877 switch (semanticsPropagationCriteria()) {
2878 case PropagationCriteria::NONE: {
2881 case PropagationCriteria::S_MAX: {
2895 label_t summary_label = 0;
2896 value_t summary_value = std::numeric_limits<value_t>::min();
2898 for (offset_t i{}; i != N; ++i) {
2899 pos_t child = children[i];
2900 if (child == NULL_POS) {
2902 std::vector vec(semantics_[block].semantic_set.begin(i),
2903 semantics_[block].semantic_set.end(i));
2906 std::sort(std::begin(vec), std::end(vec),
2907 [](
auto a,
auto b) {
return a.value >
b.value; });
2908 summary_value = std::max(summary_value, vec.front().value);
2911 auto last = std::unique(std::begin(vec), std::end(vec),
2912 [](
auto a,
auto b) {
return a.label ==
b.label; });
2915 for (
auto it = vec.begin(); it != last; ++it) {
2918 summary_label |= label;
2922 summary_label |= semantics_[child].summary.label;
2923 summary_value = std::max(summary_value, semantics_[child].summary.value);
2927 semantics_[block].summary.label = summary_label;
2928 semantics_[block].summary.value = summary_value;
2932 case PropagationCriteria::S_MIN: {
2933 label_t summary_label = 0;
2934 value_t summary_value = std::numeric_limits<value_t>::max();
2936 for (offset_t i{}; i != N; ++i) {
2937 pos_t child = children[i];
2938 if (child == NULL_POS) {
2940 std::vector vec(semantics_[block].semantic_set.begin(i),
2941 semantics_[block].semantic_set.end(i));
2945 std::sort(std::begin(vec), std::end(vec),
2946 [](
auto a,
auto b) {
return a.value <
b.value; });
2947 summary_value = std::min(summary_value, vec.front().value);
2950 auto last = std::unique(std::begin(vec), std::end(vec),
2951 [](
auto a,
auto b) {
return a.label ==
b.label; });
2954 for (
auto it = vec.begin(); it != last; ++it) {
2957 summary_label |= label;
2961 summary_label |= semantics_[child].summary.label;
2962 summary_value = std::min(summary_value, semantics_[child].summary.value);
2966 semantics_[block].summary.label = summary_label;
2967 semantics_[block].summary.value = summary_value;
2971 case PropagationCriteria::MIN: {
2975 for (offset_t i{}; i != N; ++i) {
2976 pos_t child = children[i];
2977 if (child == NULL_POS) {
2981 std::vector vec(semantics_[child].semantic_set.begin(),
2982 semantics_[child].semantic_set.end());
2983 std::sort(std::begin(vec), std::end(vec), [](
auto a,
auto b) {
2984 return a.label <
b.label || (
a.label ==
b.label &&
a.value <
b.value);
2988 auto r_last = std::unique(std::begin(vec), std::end(vec),
2989 [](
auto a,
auto b) {
return a.label ==
b.label; });
2992 semantics_[block].semantic_set.set(i, std::begin(vec), r_last);
3006 case PropagationCriteria::MAX: {
3010 for (offset_t i{}; i != N; ++i) {
3011 pos_t child = children[i];
3012 if (child == NULL_POS) {
3016 std::vector vec(semantics_[child].semantic_set.begin(),
3017 semantics_[child].semantic_set.end());
3018 std::sort(std::begin(vec), std::end(vec), [](
auto a,
auto b) {
3019 return a.label <
b.label || (
a.label ==
b.label &&
a.value >
b.value);
3023 auto r_last = std::unique(std::begin(vec), std::end(vec),
3024 [](
auto a,
auto b) {
return a.label ==
b.label; });
3028 semantics_[block].semantic_set.set(i, std::begin(vec), r_last);
3049 [[nodiscard]]
bool isPrunable(pos_t block)
const
3051 for (offset_t i{1}; N != i; ++i) {
3053 semantics_[block].semantics.begin(0), semantics_[block].semantics.end(0),
3054 semantics_[block].semantics.begin(i), semantics_[block].semantics.end(i))) {
3061 void preparePrune(Index node)
3063 auto children = derived().children(node);
3068 semantics_[node.pos].semantic_set.set(node.offset,
3069 semantics_[children].semantic_set.begin(0),
3070 semantics_[children].semantic_set.end(0));
3077 [[nodiscard]] std::size_t sizeofNodeTimesN(Index node)
const
3082 [[nodiscard]] std::size_t sizeofBlock(pos_t block)
const
3087 [[nodiscard]]
static constexpr std::size_t sizeofBlockLowerBound() noexcept
3089 return sizeof(
typename decltype(semantics_)::value_type);
3092 [[nodiscard]]
static constexpr std::size_t sizeofMap() noexcept
3094 return sizeof(semantics_) +
sizeof(mapping_) +
sizeof(prop_criteria_);
3101 [[nodiscard]]
static constexpr MapType mapType() noexcept
3103 return MapType::SEMANTIC_SET;
3106 template <
class Container>
3107 constexpr std::size_t serializedSize(Container
const& c)
const
3110 for (
auto const [block, inner_offsets, value_offsets] : c) {
3111 if (value_offsets.none()) {
3114 s +=
sizeof(std::uint8_t);
3115 if (derived().allLeaf(block)) {
3116 s += semantics_[block].semantics.serializedSize();
3118 for (offset_t i{}; N != i; ++i) {
3119 if (!value_offsets[i]) {
3124 s += semantics_[block].semantics.serializedSize(i);
3131 template <
class Container>
3132 void readNodes(ReadBuffer& in, Container
const& c)
3134 for (
auto const [block, inner_offsets, value_offsets] : c) {
3135 if (value_offsets.none()) {
3140 in.read(&mode,
sizeof(mode));
3143 semantics_[block].semantics.read(in, value_offsets);
3149 for (offset_t i{}; N != i; ++i) {
3150 if (!value_offsets[i]) {
3155 semantics_[block].semantics.set(i, s);
3161 template <
class BlockRange>
3162 void writeBlocks(WriteBuffer& out, BlockRange
const& blocks)
const
3164 for (
auto block : blocks) {
3165 if (value_offsets.none()) {
3169 if (derived().allLeaf(block)) {
3170 std::uint8_t mode = 0;
3171 out.write(&mode,
sizeof(mode));
3172 semantics_[block].semantics.write(out);
3174 std::uint8_t mode = 1;
3175 out.write(&mode,
sizeof(mode));
3177 for (offset_t i{}; N != i; ++i) {
3178 if (!value_offsets[i]) {
3182 Index node(block, i);
3183 if (derived().isLeaf(node)) {
3184 semantics_[block].semantics.write(out, i);
3186 semantics(node).write(out);
3197 void dotFileInfo(std::ostream& out, Index node)
const
3199 if (derived().isLeaf(node)) {
3200 out <<
"Semantics: " << semantics(node);
3202 out <<
"Semantic Summary: " << semanticsSummary(node);
3207 Container<SemanticSetBlock<N>> semantics_;
3210 PropagationCriteria prop_criteria_ = PropagationCriteria::MAX;
3212 template <
class Derived2, std::
size_t N2>
3213 friend class SemanticSetMap;