Skip to content

Commit 884282e

Browse files
sbenzaquencopybara-github
authored andcommitted
Refactor error factories to propagate static knowledge to the compiler, where supported.
This allows the compiler to optimize conversions to StatusOr since it can assume the Status is !ok instead of having to check again. PiperOrigin-RevId: 896110150 Change-Id: I0dc167906b761339aaac5934764fe2bd6deb1624
1 parent eb76981 commit 884282e

2 files changed

Lines changed: 134 additions & 69 deletions

File tree

absl/status/status.cc

Lines changed: 29 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -158,75 +158,35 @@ std::ostream& operator<<(std::ostream& os, const Status& x) {
158158
return os;
159159
}
160160

161-
Status AbortedError(absl::string_view message, absl::SourceLocation loc) {
162-
return Status(absl::StatusCode::kAborted, message, loc);
163-
}
164-
165-
Status AlreadyExistsError(absl::string_view message, absl::SourceLocation loc) {
166-
return Status(absl::StatusCode::kAlreadyExists, message, loc);
167-
}
168-
169-
Status CancelledError(absl::string_view message, absl::SourceLocation loc) {
170-
return Status(absl::StatusCode::kCancelled, message, loc);
171-
}
172-
173-
Status DataLossError(absl::string_view message, absl::SourceLocation loc) {
174-
return Status(absl::StatusCode::kDataLoss, message, loc);
175-
}
176-
177-
Status DeadlineExceededError(absl::string_view message,
178-
absl::SourceLocation loc) {
179-
return Status(absl::StatusCode::kDeadlineExceeded, message, loc);
180-
}
181-
182-
Status FailedPreconditionError(absl::string_view message,
183-
absl::SourceLocation loc) {
184-
return Status(absl::StatusCode::kFailedPrecondition, message, loc);
185-
}
186-
187-
Status InternalError(absl::string_view message, absl::SourceLocation loc) {
188-
return Status(absl::StatusCode::kInternal, message, loc);
189-
}
190-
191-
Status InvalidArgumentError(absl::string_view message,
192-
absl::SourceLocation loc) {
193-
return Status(absl::StatusCode::kInvalidArgument, message, loc);
194-
}
195-
196-
Status NotFoundError(absl::string_view message, absl::SourceLocation loc) {
197-
return Status(absl::StatusCode::kNotFound, message, loc);
198-
}
199-
200-
Status OutOfRangeError(absl::string_view message, absl::SourceLocation loc) {
201-
return Status(absl::StatusCode::kOutOfRange, message, loc);
202-
}
203-
204-
Status PermissionDeniedError(absl::string_view message,
205-
absl::SourceLocation loc) {
206-
return Status(absl::StatusCode::kPermissionDenied, message, loc);
207-
}
208-
209-
Status ResourceExhaustedError(absl::string_view message,
210-
absl::SourceLocation loc) {
211-
return Status(absl::StatusCode::kResourceExhausted, message, loc);
212-
}
213-
214-
Status UnauthenticatedError(absl::string_view message,
215-
absl::SourceLocation loc) {
216-
return Status(absl::StatusCode::kUnauthenticated, message, loc);
217-
}
218-
219-
Status UnavailableError(absl::string_view message, absl::SourceLocation loc) {
220-
return Status(absl::StatusCode::kUnavailable, message, loc);
221-
}
222-
223-
Status UnimplementedError(absl::string_view message, absl::SourceLocation loc) {
224-
return Status(absl::StatusCode::kUnimplemented, message, loc);
225-
}
226-
227-
Status UnknownError(absl::string_view message, absl::SourceLocation loc) {
228-
return Status(absl::StatusCode::kUnknown, message, loc);
229-
}
161+
namespace status_internal {
162+
// We use an int in the template parameter to shorten mangled names.
163+
template <int error_code>
164+
Status MakeErrorImpl(string_view message, SourceLocation loc) {
165+
return Status(static_cast<StatusCode>(error_code), message, loc);
166+
}
167+
168+
// Explicit instantiation for all the error codes.
169+
// If we add more error code, we need to add their values on this list.
170+
// Using ints here instead of static_cast<int>(StatusCode::kFoo) makes it easier
171+
// to see that the list is complete.
172+
template Status MakeErrorImpl<0>(string_view, SourceLocation);
173+
template Status MakeErrorImpl<1>(string_view, SourceLocation);
174+
template Status MakeErrorImpl<2>(string_view, SourceLocation);
175+
template Status MakeErrorImpl<3>(string_view, SourceLocation);
176+
template Status MakeErrorImpl<4>(string_view, SourceLocation);
177+
template Status MakeErrorImpl<5>(string_view, SourceLocation);
178+
template Status MakeErrorImpl<6>(string_view, SourceLocation);
179+
template Status MakeErrorImpl<7>(string_view, SourceLocation);
180+
template Status MakeErrorImpl<8>(string_view, SourceLocation);
181+
template Status MakeErrorImpl<9>(string_view, SourceLocation);
182+
template Status MakeErrorImpl<10>(string_view, SourceLocation);
183+
template Status MakeErrorImpl<11>(string_view, SourceLocation);
184+
template Status MakeErrorImpl<12>(string_view, SourceLocation);
185+
template Status MakeErrorImpl<13>(string_view, SourceLocation);
186+
template Status MakeErrorImpl<14>(string_view, SourceLocation);
187+
template Status MakeErrorImpl<15>(string_view, SourceLocation);
188+
template Status MakeErrorImpl<16>(string_view, SourceLocation);
189+
} // namespace status_internal
230190

231191
bool IsAborted(const Status& status) {
232192
return status.code() == absl::StatusCode::kAborted;

absl/status/status.h

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,111 @@ inline Status CancelledError() { return Status(absl::StatusCode::kCancelled); }
10621062
const char* absl_nonnull StatusMessageAsCStr(
10631063
const Status& status ABSL_ATTRIBUTE_LIFETIME_BOUND);
10641064

1065+
namespace status_internal {
1066+
// We use an int in the template parameter to shorten mangled names.
1067+
template <int error_code>
1068+
Status MakeErrorImpl(string_view message, SourceLocation loc);
1069+
// Make the instantiations extern to reduce bloat on callers.
1070+
extern template Status MakeErrorImpl<0>(string_view, SourceLocation);
1071+
extern template Status MakeErrorImpl<1>(string_view, SourceLocation);
1072+
extern template Status MakeErrorImpl<2>(string_view, SourceLocation);
1073+
extern template Status MakeErrorImpl<3>(string_view, SourceLocation);
1074+
extern template Status MakeErrorImpl<4>(string_view, SourceLocation);
1075+
extern template Status MakeErrorImpl<5>(string_view, SourceLocation);
1076+
extern template Status MakeErrorImpl<6>(string_view, SourceLocation);
1077+
extern template Status MakeErrorImpl<7>(string_view, SourceLocation);
1078+
extern template Status MakeErrorImpl<8>(string_view, SourceLocation);
1079+
extern template Status MakeErrorImpl<9>(string_view, SourceLocation);
1080+
extern template Status MakeErrorImpl<10>(string_view, SourceLocation);
1081+
extern template Status MakeErrorImpl<11>(string_view, SourceLocation);
1082+
extern template Status MakeErrorImpl<12>(string_view, SourceLocation);
1083+
extern template Status MakeErrorImpl<13>(string_view, SourceLocation);
1084+
extern template Status MakeErrorImpl<14>(string_view, SourceLocation);
1085+
extern template Status MakeErrorImpl<15>(string_view, SourceLocation);
1086+
extern template Status MakeErrorImpl<16>(string_view, SourceLocation);
1087+
1088+
template <StatusCode error_code>
1089+
Status MakeError(string_view message, SourceLocation loc) {
1090+
Status out = MakeErrorImpl<static_cast<int>(error_code)>(message, loc);
1091+
// -Wassume warning complains about potential side effects of `ok()`, so use a
1092+
// local to avoid that.
1093+
ABSL_ATTRIBUTE_UNUSED bool ok = out.ok();
1094+
ABSL_ASSUME(!ok);
1095+
return out;
1096+
}
1097+
} // namespace status_internal
1098+
1099+
// Inline implementations to give the compiler static knowledge about the
1100+
// objects.
1101+
inline Status AbortedError(absl::string_view message,
1102+
absl::SourceLocation loc) {
1103+
return status_internal::MakeError<StatusCode::kAborted>(message, loc);
1104+
}
1105+
inline Status AlreadyExistsError(absl::string_view message,
1106+
absl::SourceLocation loc) {
1107+
return status_internal::MakeError<StatusCode::kAlreadyExists>(message, loc);
1108+
}
1109+
inline Status CancelledError(absl::string_view message,
1110+
absl::SourceLocation loc) {
1111+
return status_internal::MakeError<StatusCode::kCancelled>(message, loc);
1112+
}
1113+
inline Status DataLossError(absl::string_view message,
1114+
absl::SourceLocation loc) {
1115+
return status_internal::MakeError<StatusCode::kDataLoss>(message, loc);
1116+
}
1117+
inline Status DeadlineExceededError(absl::string_view message,
1118+
absl::SourceLocation loc) {
1119+
return status_internal::MakeError<StatusCode::kDeadlineExceeded>(message,
1120+
loc);
1121+
}
1122+
inline Status FailedPreconditionError(absl::string_view message,
1123+
absl::SourceLocation loc) {
1124+
return status_internal::MakeError<StatusCode::kFailedPrecondition>(message,
1125+
loc);
1126+
}
1127+
inline Status InternalError(absl::string_view message,
1128+
absl::SourceLocation loc) {
1129+
return status_internal::MakeError<StatusCode::kInternal>(message, loc);
1130+
}
1131+
inline Status InvalidArgumentError(absl::string_view message,
1132+
absl::SourceLocation loc) {
1133+
return status_internal::MakeError<StatusCode::kInvalidArgument>(message, loc);
1134+
}
1135+
inline Status NotFoundError(absl::string_view message,
1136+
absl::SourceLocation loc) {
1137+
return status_internal::MakeError<StatusCode::kNotFound>(message, loc);
1138+
}
1139+
inline Status OutOfRangeError(absl::string_view message,
1140+
absl::SourceLocation loc) {
1141+
return status_internal::MakeError<StatusCode::kOutOfRange>(message, loc);
1142+
}
1143+
inline Status PermissionDeniedError(absl::string_view message,
1144+
absl::SourceLocation loc) {
1145+
return status_internal::MakeError<StatusCode::kPermissionDenied>(message,
1146+
loc);
1147+
}
1148+
inline Status ResourceExhaustedError(absl::string_view message,
1149+
absl::SourceLocation loc) {
1150+
return status_internal::MakeError<StatusCode::kResourceExhausted>(message,
1151+
loc);
1152+
}
1153+
inline Status UnauthenticatedError(absl::string_view message,
1154+
absl::SourceLocation loc) {
1155+
return status_internal::MakeError<StatusCode::kUnauthenticated>(message, loc);
1156+
}
1157+
inline Status UnavailableError(absl::string_view message,
1158+
absl::SourceLocation loc) {
1159+
return status_internal::MakeError<StatusCode::kUnavailable>(message, loc);
1160+
}
1161+
inline Status UnimplementedError(absl::string_view message,
1162+
absl::SourceLocation loc) {
1163+
return status_internal::MakeError<StatusCode::kUnimplemented>(message, loc);
1164+
}
1165+
inline Status UnknownError(absl::string_view message,
1166+
absl::SourceLocation loc) {
1167+
return status_internal::MakeError<StatusCode::kUnknown>(message, loc);
1168+
}
1169+
10651170
ABSL_NAMESPACE_END
10661171
} // namespace absl
10671172

0 commit comments

Comments
 (0)