Skip to content

Commit 8ff2009

Browse files
wojdyrwjakob
authored andcommitted
generalize type_caster<std::optional<T>>
Add optional_caster<> that works like in pybind11. It can be used for type casting optional types other than std::optional: boost::optional, absl::optional, nonstd::optional, llvm::Optional, etc.
1 parent b11176b commit 8ff2009

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

include/nanobind/stl/optional.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,16 @@ NAMESPACE_BEGIN(detail)
1818
template <typename T> struct remove_opt_mono<std::optional<T>>
1919
: remove_opt_mono<T> { };
2020

21-
template <typename T>
22-
struct type_caster<std::optional<T>> {
21+
template <typename Optional, typename T = typename Optional::value_type>
22+
struct optional_caster {
2323
using Caster = make_caster<T>;
2424

25-
NB_TYPE_CASTER(std::optional<T>, optional_name(Caster::Name))
26-
27-
type_caster() : value(std::nullopt) { }
25+
NB_TYPE_CASTER(Optional, optional_name(Caster::Name))
2826

2927
bool from_python(handle src, uint8_t flags, cleanup_list* cleanup) noexcept {
30-
if (src.is_none()) {
31-
value = std::nullopt;
28+
if (src.is_none())
29+
// default-constructed value is already empty
3230
return true;
33-
}
3431

3532
Caster caster;
3633
if (!caster.from_python(src, flags_for_local_caster<T>(flags), cleanup) ||
@@ -51,6 +48,9 @@ struct type_caster<std::optional<T>> {
5148
}
5249
};
5350

51+
template <typename T>
52+
struct type_caster<std::optional<T>> : optional_caster<std::optional<T>> {};
53+
5454
template <> struct type_caster<std::nullopt_t> {
5555
bool from_python(handle src, uint8_t, cleanup_list *) noexcept {
5656
if (src.is_none())

0 commit comments

Comments
 (0)