Skip to content

Commit 96b484d

Browse files
authored
fix(preproc): Access the hidesets using transparent comparisons
1 parent 654e227 commit 96b484d

File tree

1 file changed

+80
-6
lines changed

1 file changed

+80
-6
lines changed

Diff for: src/cxx/preprocessor.cc

+80-6
Original file line numberDiff line numberDiff line change
@@ -98,20 +98,88 @@ using Include = std::variant<std::monostate, SystemInclude, QuoteInclude>;
9898

9999
} // namespace
100100

101+
template <>
102+
struct std::less<Hideset> {
103+
using is_transparent = void;
104+
105+
bool operator()(const Hideset &hideset, const Hideset &other) const {
106+
return hideset.names() < other.names();
107+
}
108+
109+
bool operator()(const Hideset &hideset,
110+
const std::set<std::string_view> &names) const {
111+
return hideset.names() < names;
112+
}
113+
114+
bool operator()(const std::set<std::string_view> &names,
115+
const Hideset &hideset) const {
116+
return hideset.names() < names;
117+
}
118+
119+
bool operator()(const Hideset &hideset, const std::string_view &name) const {
120+
return std::lexicographical_compare(begin(hideset.names()),
121+
end(hideset.names()), &name, &name + 1);
122+
}
123+
124+
bool operator()(const std::string_view &name, const Hideset &hideset) const {
125+
return std::lexicographical_compare(
126+
&name, &name + 1, begin(hideset.names()), end(hideset.names()));
127+
}
128+
};
129+
101130
template <>
102131
struct std::hash<Hideset> {
132+
using is_transparent = void;
133+
103134
template <typename T>
104135
void hash_combine(std::size_t &seed, const T &val) const {
105136
seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
106137
}
107138

108139
std::size_t operator()(const Hideset &hideset) const {
140+
return operator()(hideset.names());
141+
}
142+
143+
std::size_t operator()(const std::set<std::string_view> &names) const {
109144
std::size_t seed = 0;
110-
for (const auto &name : hideset.names()) hash_combine(seed, name);
145+
for (const auto &name : names) hash_combine(seed, name);
146+
return seed;
147+
}
148+
149+
std::size_t operator()(const std::string_view &name) const {
150+
std::size_t seed = 0;
151+
hash_combine(seed, name);
111152
return seed;
112153
}
113154
};
114155

156+
template <>
157+
struct std::equal_to<Hideset> {
158+
using is_transparent = void;
159+
160+
bool operator()(const Hideset &hideset, const Hideset &other) const {
161+
return hideset.names() == other.names();
162+
}
163+
164+
bool operator()(const Hideset &hideset,
165+
const std::set<std::string_view> &names) const {
166+
return hideset.names() == names;
167+
}
168+
169+
bool operator()(const std::set<std::string_view> &names,
170+
const Hideset &hideset) const {
171+
return hideset.names() == names;
172+
}
173+
174+
bool operator()(const Hideset &hideset, const std::string_view &name) const {
175+
return hideset.names().size() == 1 && *hideset.names().begin() == name;
176+
}
177+
178+
bool operator()(const std::string_view &name, const Hideset &hideset) const {
179+
return hideset.names().size() == 1 && *hideset.names().begin() == name;
180+
}
181+
};
182+
115183
namespace cxx {
116184

117185
namespace {
@@ -268,7 +336,7 @@ struct Preprocessor::Private {
268336
std::vector<fs::path> systemIncludePaths_;
269337
std::vector<fs::path> quoteIncludePaths_;
270338
std::unordered_map<std::string_view, Macro> macros_;
271-
std::unordered_set<Hideset> hidesets;
339+
std::set<Hideset> hidesets;
272340
std::forward_list<std::string> scratchBuffer_;
273341
std::unordered_set<std::string> pragmaOnceProtected_;
274342
std::unordered_map<std::string, std::string> ifndefProtectedFiles_;
@@ -353,7 +421,7 @@ struct Preprocessor::Private {
353421
}
354422

355423
const Hideset *makeUnion(const Hideset *hs, const std::string_view &name) {
356-
if (!hs) return get(std::set<std::string_view>{name});
424+
if (!hs) return get(name);
357425
if (hs->names().contains(name)) return hs;
358426
auto names = hs->names();
359427
names.insert(name);
@@ -373,9 +441,15 @@ struct Preprocessor::Private {
373441
return get(std::move(names));
374442
}
375443

376-
const Hideset *get(std::set<std::string_view> name) {
377-
if (name.empty()) return nullptr;
378-
return &*hidesets.emplace(name).first;
444+
const Hideset *get(std::set<std::string_view> names) {
445+
if (names.empty()) return nullptr;
446+
if (auto it = hidesets.find(names); it != hidesets.end()) return &*it;
447+
return &*hidesets.emplace(std::move(names)).first;
448+
}
449+
450+
const Hideset *get(const std::string_view &name) {
451+
if (auto it = hidesets.find(name); it != hidesets.end()) return &*it;
452+
return &*hidesets.emplace(std::set{name}).first;
379453
}
380454

381455
std::string readFile(const fs::path &file) const {

0 commit comments

Comments
 (0)