|
41 | 41 | # include <variant>
|
42 | 42 | # define PYBIND11_HAS_VARIANT 1
|
43 | 43 | # endif
|
| 44 | +// std::variant |
| 45 | +# if defined(PYBIND11_CPP17) && __has_include(<filesystem>) |
| 46 | +# include <filesystem> |
| 47 | +# define PYBIND11_HAS_FILESYSTEM 1 |
| 48 | +# endif |
44 | 49 | #elif defined(_MSC_VER) && defined(PYBIND11_CPP17)
|
45 | 50 | # include <optional>
|
46 | 51 | # include <variant>
|
@@ -372,6 +377,43 @@ template <typename... Ts>
|
372 | 377 | struct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> { };
|
373 | 378 | #endif
|
374 | 379 |
|
| 380 | +#if PYBIND11_HAS_FILESYSTEM && ((PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 6) || PY_MAJOR_VERSION >= 4) |
| 381 | +template <> struct type_caster<std::filesystem::path> |
| 382 | +{ |
| 383 | +public: |
| 384 | + PYBIND11_TYPE_CASTER(std::filesystem::path, _("path_like")); |
| 385 | + |
| 386 | + bool load(handle src, bool) |
| 387 | + { |
| 388 | + auto fs_encoded = reinterpret_steal<object>(PyOS_FSPath(src.ptr())); |
| 389 | + if (!fs_encoded) |
| 390 | + { |
| 391 | + PyErr_Clear(); |
| 392 | + return false; |
| 393 | + } |
| 394 | + if (PyBytes_Check(fs_encoded.ptr())) // fs_encoded may be bytes or unicode |
| 395 | + fs_encoded = reinterpret_steal<object>(PyUnicode_DecodeFSDefault(PyBytes_AS_STRING(fs_encoded.ptr()))); |
| 396 | + |
| 397 | + auto size = Py_ssize_t{}; |
| 398 | + auto buffer = PyUnicode_AsUTF8AndSize(fs_encoded.ptr(), &size); |
| 399 | + if (! buffer) |
| 400 | + { |
| 401 | + PyErr_Clear(); |
| 402 | + return false; |
| 403 | + } |
| 404 | + |
| 405 | + value = std::filesystem::u8path(buffer, buffer + size); |
| 406 | + return true; |
| 407 | + } |
| 408 | + |
| 409 | + static handle cast(std::filesystem::path src, return_value_policy /* policy */, handle /* parent */) |
| 410 | + { |
| 411 | + auto data = src.u8string(); |
| 412 | + return PyUnicode_DecodeUTF8(data.data(), data.size(), nullptr /* usually means strict */); |
| 413 | + } |
| 414 | +}; |
| 415 | +#endif |
| 416 | + |
375 | 417 | NAMESPACE_END(detail)
|
376 | 418 |
|
377 | 419 | inline std::ostream &operator<<(std::ostream &os, const handle &obj) {
|
|
0 commit comments