|
20 | 20 | #include <utility> |
21 | 21 | #include <vector> |
22 | 22 |
|
| 23 | +#include "absl/container/flat_hash_map.h" |
23 | 24 | #include "absl/container/flat_hash_set.h" |
24 | | -#include "absl/log/absl_check.h" |
25 | 25 | #include "absl/status/status.h" |
26 | 26 | #include "absl/status/statusor.h" |
27 | 27 | #include "absl/strings/str_cat.h" |
@@ -109,43 +109,47 @@ bool SignaturesOverlap(const OverloadDecl& lhs, const OverloadDecl& rhs) { |
109 | 109 | template <typename Overload> |
110 | 110 | void AddOverloadInternal(std::string_view function_name, |
111 | 111 | std::vector<OverloadDecl>& insertion_order, |
112 | | - OverloadDeclHashSet& overloads, Overload&& overload, |
113 | | - absl::Status& status) { |
| 112 | + absl::flat_hash_map<std::string, size_t>& by_id, |
| 113 | + absl::flat_hash_map<std::string, size_t>& by_signature, |
| 114 | + Overload&& overload, absl::Status& status) { |
114 | 115 | if (!status.ok()) { |
115 | 116 | return; |
116 | 117 | } |
117 | 118 |
|
118 | | - if (overload.id().empty()) { |
119 | | - OverloadDecl overload_decl = overload; |
120 | | - absl::StatusOr<std::string> overload_id = |
121 | | - common_internal::MakeOverloadSignature( |
122 | | - function_name, overload_decl.args(), overload_decl.member()); |
123 | | - if (!overload_id.ok()) { |
124 | | - status = overload_id.status(); |
125 | | - return; |
126 | | - } |
127 | | - overload_decl.set_id(*overload_id); |
128 | | - AddOverloadInternal(function_name, insertion_order, overloads, |
129 | | - std::move(overload_decl), status); |
| 119 | + absl::StatusOr<std::string> signature = |
| 120 | + common_internal::MakeOverloadSignature(function_name, overload.args(), |
| 121 | + overload.member()); |
| 122 | + if (!signature.ok()) { |
| 123 | + status = signature.status(); |
130 | 124 | return; |
131 | 125 | } |
132 | 126 |
|
133 | | - if (auto it = overloads.find(overload.id()); it != overloads.end()) { |
| 127 | + OverloadDecl mutable_overload = std::forward<Overload>(overload); |
| 128 | + mutable_overload.set_signature(*signature); |
| 129 | + |
| 130 | + if (mutable_overload.id().empty()) { |
| 131 | + mutable_overload.set_id(mutable_overload.signature()); |
| 132 | + } |
| 133 | + |
| 134 | + if (auto it = by_id.find(mutable_overload.id()); it != by_id.end()) { |
134 | 135 | status = absl::AlreadyExistsError( |
135 | | - absl::StrCat("overload already exists: ", overload.id())); |
| 136 | + absl::StrCat("overload exists: ", mutable_overload.id())); |
136 | 137 | return; |
137 | 138 | } |
138 | | - for (const auto& existing : overloads) { |
139 | | - if (SignaturesOverlap(overload, existing)) { |
| 139 | + |
| 140 | + for (const auto& existing : insertion_order) { |
| 141 | + if (SignaturesOverlap(mutable_overload, existing)) { |
140 | 142 | status = absl::InvalidArgumentError( |
141 | 143 | absl::StrCat("overload signature collision: ", existing.id(), |
142 | | - " collides with ", overload.id())); |
| 144 | + " collides with ", mutable_overload.id())); |
143 | 145 | return; |
144 | 146 | } |
145 | 147 | } |
146 | | - const auto inserted = overloads.insert(std::forward<Overload>(overload)); |
147 | | - ABSL_DCHECK(inserted.second); |
148 | | - insertion_order.push_back(*inserted.first); |
| 148 | + |
| 149 | + size_t index = insertion_order.size(); |
| 150 | + by_id[mutable_overload.id()] = index; |
| 151 | + by_signature[mutable_overload.signature()] = index; |
| 152 | + insertion_order.push_back(std::move(mutable_overload)); |
149 | 153 | } |
150 | 154 |
|
151 | 155 | void CollectTypeParams(absl::flat_hash_set<std::string>& type_params, |
@@ -195,14 +199,25 @@ absl::flat_hash_set<std::string> OverloadDecl::GetTypeParams() const { |
195 | 199 |
|
196 | 200 | void FunctionDecl::AddOverloadImpl(const OverloadDecl& overload, |
197 | 201 | absl::Status& status) { |
198 | | - AddOverloadInternal(name_, overloads_.insertion_order, overloads_.set, |
199 | | - overload, status); |
| 202 | + AddOverloadInternal(name_, overloads_.insertion_order, overloads_.by_id, |
| 203 | + overloads_.by_signature, overload, status); |
200 | 204 | } |
201 | 205 |
|
202 | 206 | void FunctionDecl::AddOverloadImpl(OverloadDecl&& overload, |
203 | 207 | absl::Status& status) { |
204 | | - AddOverloadInternal(name_, overloads_.insertion_order, overloads_.set, |
205 | | - std::move(overload), status); |
| 208 | + AddOverloadInternal(name_, overloads_.insertion_order, overloads_.by_id, |
| 209 | + overloads_.by_signature, std::move(overload), status); |
| 210 | +} |
| 211 | + |
| 212 | +const OverloadDecl* FunctionDecl::FindOverloadById(absl::string_view id) const { |
| 213 | + if (auto it = overloads_.by_id.find(id); it != overloads_.by_id.end()) { |
| 214 | + return &overloads_.insertion_order[it->second]; |
| 215 | + } |
| 216 | + if (auto it = overloads_.by_signature.find(id); |
| 217 | + it != overloads_.by_signature.end()) { |
| 218 | + return &overloads_.insertion_order[it->second]; |
| 219 | + } |
| 220 | + return nullptr; |
206 | 221 | } |
207 | 222 |
|
208 | 223 | } // namespace cel |
0 commit comments