Skip to content

Commit b59daf1

Browse files
committed
pattern: Properly implement sorting of sub-patterns
1 parent a555801 commit b59daf1

8 files changed

Lines changed: 93 additions & 41 deletions

lib/include/pl/patterns/pattern.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,26 @@ namespace pl::ptrn {
3030
public:
3131
virtual ~IIterable() = default;
3232
[[nodiscard]] virtual std::vector<std::shared_ptr<Pattern>> getEntries() = 0;
33+
[[nodiscard]] virtual std::vector<std::shared_ptr<Pattern>> getSortedEntries() = 0;
3334
virtual void setEntries(const std::vector<std::shared_ptr<Pattern>> &entries) = 0;
3435

3536
[[nodiscard]] virtual std::shared_ptr<Pattern> getEntry(size_t index) const = 0;
36-
virtual void forEachEntry(u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)> &callback) = 0;
37+
void forEachEntry(u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)> &callback) {
38+
forEachEntryImpl(this->getEntries(), start, end, callback);
39+
}
40+
41+
void forEachEntrySorted(u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)> &callback) {
42+
forEachEntryImpl(this->getSortedEntries(), start, end, callback);
43+
}
3744

3845
[[nodiscard]] virtual size_t getEntryCount() const = 0;
3946

4047
virtual void addEntry(const std::shared_ptr<Pattern> &) {
4148
core::err::E0012.throwError("Cannot add entry to this pattern");
4249
}
50+
51+
protected:
52+
virtual void forEachEntryImpl(const std::vector<std::shared_ptr<Pattern>> &patterns, u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)> &callback) = 0;
4353
};
4454

4555
enum class Visibility : u8 {

lib/include/pl/patterns/pattern_array_dynamic.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,11 @@ namespace pl::ptrn {
108108
return this->m_entries;
109109
}
110110

111-
void forEachEntry(u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)>& fn) override {
111+
[[nodiscard]] std::vector<std::shared_ptr<Pattern>> getSortedEntries() override {
112+
return this->m_entries;
113+
}
114+
115+
void forEachEntryImpl(const std::vector<std::shared_ptr<Pattern>> &patterns, u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)>& fn) override {
112116
auto evaluator = this->getEvaluator();
113117
auto startArrayIndex = evaluator->getCurrentArrayIndex();
114118

@@ -119,10 +123,10 @@ namespace pl::ptrn {
119123
evaluator->clearCurrentArrayIndex();
120124
};
121125

122-
for (u64 i = start; i < std::min<u64>(end, this->m_entries.size()); i++) {
126+
for (u64 i = start; i < std::min<u64>(end, patterns.size()); i++) {
123127
evaluator->setCurrentArrayIndex(i);
124128

125-
auto &entry = this->m_entries[i];
129+
auto &entry = patterns[i];
126130
if (!entry->isPatternLocal() || entry->hasAttribute("export"))
127131
fn(i, entry);
128132
}

lib/include/pl/patterns/pattern_array_static.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@ namespace pl::ptrn {
3232
return { this->getTemplate()->clone() };
3333
}
3434

35-
void forEachEntry(u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)>& fn) override {
35+
[[nodiscard]] std::vector<std::shared_ptr<Pattern>> getSortedEntries() override {
36+
return { this->getTemplate()->clone() };
37+
}
38+
39+
void forEachEntryImpl(const std::vector<std::shared_ptr<Pattern>> &patterns, u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)>& fn) override {
40+
std::ignore = patterns;
41+
3642
auto evaluator = this->getEvaluator();
3743
auto startArrayIndex = evaluator->getCurrentArrayIndex();
3844
ON_SCOPE_EXIT {

lib/include/pl/patterns/pattern_bitfield.hpp

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,10 @@ namespace pl::ptrn {
382382
return this->m_entries;
383383
}
384384

385+
[[nodiscard]] std::vector<std::shared_ptr<Pattern>> getSortedEntries() override {
386+
return this->m_sortedEntries;
387+
}
388+
385389
void setOffset(u64 offset) override {
386390
for (auto &entry : this->m_entries) {
387391
if (entry->getSection() == this->getSection() && entry->getSection() != ptrn::Pattern::PatternLocalSectionId)
@@ -391,7 +395,7 @@ namespace pl::ptrn {
391395
PatternBitfieldMember::setOffset(offset);
392396
}
393397

394-
void forEachEntry(u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)>& fn) override {
398+
void forEachEntryImpl(const std::vector<std::shared_ptr<Pattern>> &patterns, u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)>& fn) override {
395399
auto evaluator = this->getEvaluator();
396400
auto startArrayIndex = evaluator->getCurrentArrayIndex();
397401

@@ -402,10 +406,10 @@ namespace pl::ptrn {
402406
evaluator->clearCurrentArrayIndex();
403407
};
404408

405-
for (u64 i = start; i < std::min<u64>(end, this->m_entries.size()); i++) {
409+
for (u64 i = start; i < std::min<u64>(end, patterns.size()); i++) {
406410
evaluator->setCurrentArrayIndex(i);
407411

408-
auto &entry = this->m_entries[i];
412+
auto &entry = patterns[i];
409413
if (!entry->isPatternLocal() || entry->hasAttribute("export"))
410414
fn(i, entry);
411415
}
@@ -417,8 +421,6 @@ namespace pl::ptrn {
417421
for (auto &entry : this->m_entries) {
418422
if (!entry->hasOverriddenColor())
419423
entry->setBaseColor(this->getColor());
420-
421-
this->m_sortedEntries.push_back(entry.get());
422424
}
423425

424426
if (!this->m_entries.empty())
@@ -495,11 +497,14 @@ namespace pl::ptrn {
495497
void sort(const std::function<bool (const Pattern *, const Pattern *)> &comparator) override {
496498
this->m_sortedEntries.clear();
497499
for (auto &member : this->m_entries)
498-
this->m_sortedEntries.push_back(member.get());
500+
this->m_sortedEntries.push_back(member);
501+
502+
std::ranges::sort(this->m_sortedEntries, [&](const auto & a, const auto & b) {
503+
return comparator(a.get(), b.get());
504+
});
499505

500-
std::sort(this->m_sortedEntries.begin(), this->m_sortedEntries.end(), comparator);
501506
if (this->isReversed())
502-
std::reverse(this->m_sortedEntries.begin(), this->m_sortedEntries.end());
507+
std::ranges::reverse(this->m_sortedEntries);
503508

504509
for (auto &member : this->m_entries)
505510
member->sort(comparator);
@@ -511,7 +516,7 @@ namespace pl::ptrn {
511516

512517
this->getEvaluator()->readData(this->getOffset(), result.data(), result.size(), this->getSection());
513518
if (this->getEndian() != std::endian::native)
514-
std::reverse(result.begin(), result.end());
519+
std::ranges::reverse(result);
515520

516521
return result;
517522
}
@@ -526,7 +531,7 @@ namespace pl::ptrn {
526531

527532
private:
528533
std::vector<std::shared_ptr<Pattern>> m_entries;
529-
std::vector<Pattern *> m_sortedEntries;
534+
std::vector<std::shared_ptr<Pattern>> m_sortedEntries;
530535
u8 m_firstBitOffset = 0;
531536
u128 m_totalBitSize = 0;
532537
bool m_reversed = false;
@@ -638,7 +643,7 @@ namespace pl::ptrn {
638643

639644
for (const auto &field : this->m_fields) {
640645
field->setParent(this->reference());
641-
this->m_sortedFields.push_back(field.get());
646+
this->m_sortedFields.push_back(field);
642647
}
643648
}
644649

@@ -745,6 +750,10 @@ namespace pl::ptrn {
745750
return this->m_fields;
746751
}
747752

753+
[[nodiscard]] std::vector<std::shared_ptr<Pattern>> getSortedEntries() override {
754+
return this->m_sortedFields;
755+
}
756+
748757
void setEntries(const std::vector<std::shared_ptr<Pattern>> &entries) override {
749758
this->m_fields = entries;
750759
}
@@ -758,12 +767,12 @@ namespace pl::ptrn {
758767
PatternBitfieldMember::setOffset(offset);
759768
}
760769

761-
void forEachEntry(u64 start, u64 end, const std::function<void (u64, const std::shared_ptr<Pattern>&)> &fn) override {
770+
void forEachEntryImpl(const std::vector<std::shared_ptr<Pattern>> &patterns, u64 start, u64 end, const std::function<void (u64, const std::shared_ptr<Pattern>&)> &fn) override {
762771
if (this->isSealed())
763772
return;
764773

765774
for (auto i = start; i < end; i++) {
766-
auto &pattern = this->m_fields[i];
775+
auto &pattern = patterns[i];
767776
if (!pattern->isPatternLocal() || pattern->hasAttribute("export"))
768777
fn(i, pattern);
769778
}
@@ -772,11 +781,13 @@ namespace pl::ptrn {
772781
void sort(const std::function<bool (const Pattern *, const Pattern *)> &comparator) override {
773782
this->m_sortedFields.clear();
774783
for (auto &member : this->m_fields)
775-
this->m_sortedFields.push_back(member.get());
784+
this->m_sortedFields.push_back(member);
776785

777-
std::sort(this->m_sortedFields.begin(), this->m_sortedFields.end(), comparator);
786+
std::ranges::sort(this->m_sortedFields, [&](const auto & a, const auto & b) {
787+
return comparator(a.get(), b.get());
788+
});
778789
if (this->isReversed())
779-
std::reverse(this->m_sortedFields.begin(), this->m_sortedFields.end());
790+
std::ranges::reverse(this->m_sortedFields);
780791

781792
for (auto &member : this->m_fields)
782793
member->sort(comparator);
@@ -788,7 +799,7 @@ namespace pl::ptrn {
788799

789800
this->getEvaluator()->readData(this->getOffset(), result.data(), result.size(), this->getSection());
790801
if (this->getEndian() != std::endian::native)
791-
std::reverse(result.begin(), result.end());
802+
std::ranges::reverse(result);
792803

793804
return result;
794805
}
@@ -803,7 +814,7 @@ namespace pl::ptrn {
803814

804815
private:
805816
std::vector<std::shared_ptr<Pattern>> m_fields;
806-
std::vector<Pattern *> m_sortedFields;
817+
std::vector<std::shared_ptr<Pattern>> m_sortedFields;
807818

808819
u8 m_firstBitOffset = 0;
809820
u64 m_totalBitSize = 0;

lib/include/pl/patterns/pattern_string.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ namespace pl::ptrn {
2424
return { };
2525
}
2626

27+
[[nodiscard]] std::vector<std::shared_ptr<Pattern>> getSortedEntries() override {
28+
return { };
29+
}
30+
2731
void setEntries(const std::vector<std::shared_ptr<Pattern>> &) override {
2832

2933
}
@@ -87,7 +91,9 @@ namespace pl::ptrn {
8791
return this->getSize();
8892
}
8993

90-
void forEachEntry(u64 start, u64 end, const std::function<void (u64, const std::shared_ptr<Pattern>&)> &callback) override {
94+
void forEachEntryImpl(const std::vector<std::shared_ptr<Pattern>> &patterns, u64 start, u64 end, const std::function<void (u64, const std::shared_ptr<Pattern>&)> &callback) override {
95+
std::ignore = patterns;
96+
9197
for (auto i = start; i < end; i++)
9298
callback(i, this->getEntry(i));
9399
}

lib/include/pl/patterns/pattern_struct.hpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace pl::ptrn {
1515
for (const auto &member : other.m_members) {
1616
auto copy = member->clone();
1717

18-
this->m_sortedMembers.push_back(copy.get());
18+
this->m_sortedMembers.push_back(copy);
1919
this->m_members.push_back(std::move(copy));
2020
}
2121
}
@@ -36,11 +36,14 @@ namespace pl::ptrn {
3636
return this->m_members;
3737
}
3838

39+
[[nodiscard]] std::vector<std::shared_ptr<Pattern>> getSortedEntries() override {
40+
return this->m_sortedMembers;
41+
}
42+
3943
void addEntry(const std::shared_ptr<Pattern> &entry) override {
4044
if (entry == nullptr) return;
4145

4246
entry->setParent(this->reference());
43-
this->m_sortedMembers.push_back(entry.get());
4447
this->m_members.push_back(entry);
4548
}
4649

@@ -55,12 +58,12 @@ namespace pl::ptrn {
5558
this->setBaseColor(this->m_members.front()->getColor());
5659
}
5760

58-
void forEachEntry(u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)>& fn) override {
61+
void forEachEntryImpl(const std::vector<std::shared_ptr<Pattern>> &patterns, u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)>& fn) override {
5962
if (this->isSealed())
6063
return;
6164

62-
for (u64 i = start; i < this->m_members.size() && i < end; i++) {
63-
auto &pattern = this->m_members[i];
65+
for (u64 i = start; i < patterns.size() && i < end; i++) {
66+
auto &pattern = patterns[i];
6467
if (!pattern->isPatternLocal() || pattern->hasAttribute("export"))
6568
fn(i, pattern);
6669
}
@@ -159,9 +162,11 @@ namespace pl::ptrn {
159162
void sort(const std::function<bool (const Pattern *, const Pattern *)> &comparator) override {
160163
this->m_sortedMembers.clear();
161164
for (auto &member : this->m_members)
162-
this->m_sortedMembers.push_back(member.get());
165+
this->m_sortedMembers.push_back(member);
163166

164-
std::sort(this->m_sortedMembers.begin(), this->m_sortedMembers.end(), comparator);
167+
std::ranges::sort(this->m_sortedMembers, [&](const auto & a, const auto & b) {
168+
return comparator(a.get(), b.get());
169+
});
165170

166171
for (auto &member : this->m_sortedMembers)
167172
member->sort(comparator);
@@ -228,7 +233,7 @@ namespace pl::ptrn {
228233

229234
private:
230235
std::vector<std::shared_ptr<Pattern>> m_members;
231-
std::vector<Pattern *> m_sortedMembers;
236+
std::vector<std::shared_ptr<Pattern>> m_sortedMembers;
232237
};
233238

234239
}

lib/include/pl/patterns/pattern_union.hpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ namespace pl::ptrn {
1515
for (const auto &member : other.m_members) {
1616
auto copy = member->clone();
1717

18-
this->m_sortedMembers.push_back(copy.get());
1918
this->m_members.push_back(std::move(copy));
2019
}
2120
}
@@ -36,10 +35,13 @@ namespace pl::ptrn {
3635
return this->m_members;
3736
}
3837

38+
[[nodiscard]] std::vector<std::shared_ptr<Pattern>> getSortedEntries() override {
39+
return this->m_sortedMembers;
40+
}
41+
3942
void addEntry(const std::shared_ptr<Pattern> &entry) override {
4043
if (entry == nullptr) return;
4144

42-
this->m_sortedMembers.push_back(entry.get());
4345
this->m_members.push_back(entry);
4446
}
4547

@@ -54,12 +56,12 @@ namespace pl::ptrn {
5456
this->setBaseColor(this->m_members.front()->getColor());
5557
}
5658

57-
void forEachEntry(u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)>& fn) override {
59+
void forEachEntryImpl(const std::vector<std::shared_ptr<Pattern>> &patterns, u64 start, u64 end, const std::function<void(u64, const std::shared_ptr<Pattern>&)>& fn) override {
5860
if (this->isSealed())
5961
return;
6062

61-
for (u64 i = start; i < this->m_members.size() && i < end; i++) {
62-
auto &pattern = this->m_members[i];
63+
for (u64 i = start; i < patterns.size() && i < end; i++) {
64+
auto &pattern = patterns[i];
6365
if (!pattern->isPatternLocal() || pattern->hasAttribute("export"))
6466
fn(i, pattern);
6567
}
@@ -158,9 +160,11 @@ namespace pl::ptrn {
158160
void sort(const std::function<bool (const Pattern *, const Pattern *)> &comparator) override {
159161
this->m_sortedMembers.clear();
160162
for (auto &member : this->m_members)
161-
this->m_sortedMembers.push_back(member.get());
163+
this->m_sortedMembers.push_back(member);
162164

163-
std::sort(this->m_sortedMembers.begin(), this->m_sortedMembers.end(), comparator);
165+
std::ranges::sort(this->m_sortedMembers, [&](const auto & a, const auto & b) {
166+
return comparator(a.get(), b.get());
167+
});
164168

165169
for (auto &member : this->m_members)
166170
member->sort(comparator);
@@ -220,7 +224,7 @@ namespace pl::ptrn {
220224

221225
private:
222226
std::vector<std::shared_ptr<Pattern>> m_members;
223-
std::vector<Pattern *> m_sortedMembers;
227+
std::vector<std::shared_ptr<Pattern>> m_sortedMembers;
224228
};
225229

226230
}

lib/include/pl/patterns/pattern_wide_string.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ namespace pl::ptrn {
7575
return { };
7676
}
7777

78+
[[nodiscard]] std::vector<std::shared_ptr<Pattern>> getSortedEntries() override {
79+
return { };
80+
}
81+
7882
void setEntries(const std::vector<std::shared_ptr<Pattern>> &) override {
7983

8084
}
@@ -90,7 +94,9 @@ namespace pl::ptrn {
9094
return this->getSize() / sizeof(char16_t);
9195
}
9296

93-
void forEachEntry(u64 start, u64 end, const std::function<void (u64, const std::shared_ptr<Pattern>&)> &callback) override {
97+
void forEachEntryImpl(const std::vector<std::shared_ptr<Pattern>> &patterns, u64 start, u64 end, const std::function<void (u64, const std::shared_ptr<Pattern>&)> &callback) override {
98+
std::ignore = patterns;
99+
94100
for (auto i = start; i < end; i++)
95101
callback(i, this->getEntry(i));
96102
}

0 commit comments

Comments
 (0)