diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 0c862e4be..211fd92a8 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -114,6 +114,10 @@ public: template using is_std_char_type = any_of, /* std::string */ +#if defined(PYBIND11_CPP17) + std::is_same, /* std::byte */ +#endif + std::is_same, /* uint8_t */ #if defined(PYBIND11_HAS_U8STRING) std::is_same, /* std::u8string */ #endif @@ -450,11 +454,21 @@ struct string_caster { cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) { const char *buffer = reinterpret_cast(src.data()); auto nbytes = ssize_t(src.size() * sizeof(CharT)); - handle s = decode_utfN(buffer, nbytes); - if (!s) { - throw error_already_set(); +#if defined(PYBIND11_CPP17) + if constexpr (std::is_same::value || + std::is_same::value) +#else + if (std::is_same::value) +#endif + { + return PyBytes_FromStringAndSize(buffer, nbytes); + } else { + handle s = decode_utfN(buffer, nbytes); + if (!s) { + throw error_already_set(); + } + return s; } - return s; } PYBIND11_TYPE_CASTER(StringType, const_name(PYBIND11_STRING_NAME)); @@ -477,12 +491,18 @@ private: nullptr); #endif } + template + using accept_bytes_as_is = any_of, +#if defined(PYBIND11_CPP17) + std::is_same, +#endif + std::is_same>; // When loading into a std::string or char*, accept a bytes/bytearray object as-is (i.e. // without any encoding/decoding attempt). For other C++ char sizes this is a no-op. // which supports loading a unicode from a str, doesn't take this path. template - bool load_raw(enable_if_t::value, handle> src) { + bool load_raw(enable_if_t::value, handle> src) { if (PYBIND11_BYTES_CHECK(src.ptr())) { // We were passed raw bytes; accept it into a std::string or char* // without any encoding attempt. @@ -490,7 +510,7 @@ private: if (!bytes) { pybind11_fail("Unexpected PYBIND11_BYTES_AS_STRING() failure."); } - value = StringType(bytes, (size_t) PYBIND11_BYTES_SIZE(src.ptr())); + value = StringType((const C *) bytes, (size_t) PYBIND11_BYTES_SIZE(src.ptr())); return true; } if (PyByteArray_Check(src.ptr())) { @@ -500,7 +520,7 @@ private: if (!bytearray) { pybind11_fail("Unexpected PyByteArray_AsString() failure."); } - value = StringType(bytearray, (size_t) PyByteArray_Size(src.ptr())); + value = StringType((const C *) bytearray, (size_t) PyByteArray_Size(src.ptr())); return true; } @@ -508,7 +528,7 @@ private: } template - bool load_raw(enable_if_t::value, handle>) { + bool load_raw(enable_if_t::value, handle>) { return false; } };