Commit e50999ec by Ralf W. Grosse-Kunstleve Committed by Copybara-Service

Splitting out pybind11_abseil/no_throw_status.h

Factoring out no_throw_status.h is deemed beneficial in its own right, improving readability/clarity, and it makes it obvious that this code depends only on std libraries.

PiperOrigin-RevId: 424156825
parent f6239dcd
......@@ -23,6 +23,11 @@ pybind_library(
)
cc_library(
name = "no_throw_status",
hdrs = ["no_throw_status.h"],
)
cc_library(
name = "status_not_ok_exception",
hdrs = ["status_not_ok_exception.h"],
deps = ["@com_google_absl//absl/status"],
......@@ -34,6 +39,7 @@ pybind_library(
hdrs = ["status_utils.h"],
deps = [
":absl_casters",
":no_throw_status",
":status_not_ok_exception",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
......
#ifndef PYBIND11_ABSEIL_NO_THROW_STATUS_H_
#define PYBIND11_ABSEIL_NO_THROW_STATUS_H_
#include <functional>
#include <utility>
namespace pybind11 {
namespace google {
// Wrapper type to signal to the type_caster that a non-ok status should not
// be converted into an object rather than a thrown exception. StatusType can
// encapsulate references, e.g. `NoThrowStatus<absl::Status&>`.
template <typename StatusType>
struct NoThrowStatus {
NoThrowStatus(StatusType status_in)
: status(std::forward<StatusType>(status_in)) {}
StatusType status;
};
// Convert a absl::Status(Or) into a NoThrowStatus. To use this with references,
// explicitly specify the template parameter rather deducing it, e.g.:
// `return DoNotThrowStatus<const absl::Status&>(my_status);`
// When returning a status by value (by far the most common case), deducing the
// template parameter is fine, e.g.: `return DoNotThrowStatus(my_status);`
template <typename StatusType>
NoThrowStatus<StatusType> DoNotThrowStatus(StatusType status) {
return NoThrowStatus<StatusType>(std::forward<StatusType>(status));
}
// Convert a function returning a absl::Status(Or) into a function
// returning a NoThrowStatus.
template <typename StatusType, typename... Args>
std::function<NoThrowStatus<StatusType>(Args...)> DoNotThrowStatus(
std::function<StatusType(Args...)> f) {
return [f = std::move(f)](Args&&... args) {
return NoThrowStatus<StatusType>(
std::forward<StatusType>(f(std::forward<Args>(args)...)));
};
}
template <typename StatusType, typename... Args>
std::function<NoThrowStatus<StatusType>(Args...)> DoNotThrowStatus(
StatusType (*f)(Args...)) {
return [f](Args&&... args) {
return NoThrowStatus<StatusType>(
std::forward<StatusType>(f(std::forward<Args>(args)...)));
};
}
template <typename StatusType, typename Class, typename... Args>
std::function<NoThrowStatus<StatusType>(Class*, Args...)> DoNotThrowStatus(
StatusType (Class::*f)(Args...)) {
return [f](Class* c, Args&&... args) {
return NoThrowStatus<StatusType>(
std::forward<StatusType>((c->*f)(std::forward<Args>(args)...)));
};
}
template <typename StatusType, typename Class, typename... Args>
std::function<NoThrowStatus<StatusType>(const Class*, Args...)>
DoNotThrowStatus(StatusType (Class::*f)(Args...) const) {
return [f](const Class* c, Args&&... args) {
return NoThrowStatus<StatusType>(
std::forward<StatusType>((c->*f)(std::forward<Args>(args)...)));
};
}
} // namespace google
} // namespace pybind11
#endif // PYBIND11_ABSEIL_NO_THROW_STATUS_H_
......@@ -10,65 +10,12 @@
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "pybind11_abseil/no_throw_status.h"
#include "pybind11_abseil/status_not_ok_exception.h"
namespace pybind11 {
namespace google {
// Wrapper type to signal to the type_caster that a non-ok status should not
// be converted into an object rather than a thrown exception. StatusType can
// encapsulate references, e.g. `NoThrowStatus<absl::Status&>`.
template <typename StatusType>
struct NoThrowStatus {
NoThrowStatus(StatusType status_in)
: status(std::forward<StatusType>(status_in)) {}
StatusType status;
};
// Convert a absl::Status(Or) into a NoThrowStatus. To use this with references,
// explicitly specify the template parameter rather deducing it, e.g.:
// `return DoNotThrowStatus<const absl::Status&>(my_status);`
// When returning a status by value (by far the most common case), deducing the
// template parameter is fine, e.g.: `return DoNotThrowStatus(my_status);`
template <typename StatusType>
NoThrowStatus<StatusType> DoNotThrowStatus(StatusType status) {
return NoThrowStatus<StatusType>(std::forward<StatusType>(status));
}
// Convert a function returning a absl::Status(Or) into a function
// returning a NoThrowStatus.
template <typename StatusType, typename... Args>
std::function<NoThrowStatus<StatusType>(Args...)> DoNotThrowStatus(
std::function<StatusType(Args...)> f) {
return [f = std::move(f)](Args&&... args) {
return NoThrowStatus<StatusType>(
std::forward<StatusType>(f(std::forward<Args>(args)...)));
};
}
template <typename StatusType, typename... Args>
std::function<NoThrowStatus<StatusType>(Args...)> DoNotThrowStatus(
StatusType (*f)(Args...)) {
return [f](Args&&... args) {
return NoThrowStatus<StatusType>(
std::forward<StatusType>(f(std::forward<Args>(args)...)));
};
}
template <typename StatusType, typename Class, typename... Args>
std::function<NoThrowStatus<StatusType>(Class*, Args...)> DoNotThrowStatus(
StatusType (Class::*f)(Args...)) {
return [f](Class* c, Args&&... args) {
return NoThrowStatus<StatusType>(
std::forward<StatusType>((c->*f)(std::forward<Args>(args)...)));
};
}
template <typename StatusType, typename Class, typename... Args>
std::function<NoThrowStatus<StatusType>(const Class*, Args...)>
DoNotThrowStatus(StatusType (Class::*f)(Args...) const) {
return [f](const Class* c, Args&&... args) {
return NoThrowStatus<StatusType>(
std::forward<StatusType>((c->*f)(std::forward<Args>(args)...)));
};
}
// Registers the bindings for the status types in the given module. Can only
// be called once; subsequent calls will fail due to duplicate registrations.
void RegisterStatusBindings(module m);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment