|
18 | 18 | # include <optional> |
19 | 19 | #endif |
20 | 20 |
|
| 21 | +#ifdef PYBIND11_HAS_STRING_VIEW |
| 22 | +# include <string_view> |
| 23 | +#endif |
| 24 | + |
21 | 25 | PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) |
22 | 26 |
|
23 | 27 | /* A few forward declarations */ |
@@ -1085,6 +1089,20 @@ class str : public object { |
1085 | 1089 | // NOLINTNEXTLINE(google-explicit-constructor) |
1086 | 1090 | str(const std::string &s) : str(s.data(), s.size()) { } |
1087 | 1091 |
|
| 1092 | +#ifdef PYBIND11_HAS_STRING_VIEW |
| 1093 | + // enable_if is needed to avoid "ambiguous conversion" errors (see PR #3521). |
| 1094 | + template <typename T, detail::enable_if_t<std::is_same<T, std::string_view>::value, int> = 0> |
| 1095 | + // NOLINTNEXTLINE(google-explicit-constructor) |
| 1096 | + str(T s) : str(s.data(), s.size()) { } |
| 1097 | + |
| 1098 | +# ifdef PYBIND11_HAS_U8STRING |
| 1099 | + // reinterpret_cast here is safe (C++20 guarantees char8_t has the same size/alignment as char) |
| 1100 | + // NOLINTNEXTLINE(google-explicit-constructor) |
| 1101 | + str(std::u8string_view s) : str(reinterpret_cast<const char*>(s.data()), s.size()) { } |
| 1102 | +# endif |
| 1103 | + |
| 1104 | +#endif |
| 1105 | + |
1088 | 1106 | explicit str(const bytes &b); |
1089 | 1107 |
|
1090 | 1108 | /** \rst |
@@ -1167,6 +1185,26 @@ class bytes : public object { |
1167 | 1185 | pybind11_fail("Unable to extract bytes contents!"); |
1168 | 1186 | return std::string(buffer, (size_t) length); |
1169 | 1187 | } |
| 1188 | + |
| 1189 | +#ifdef PYBIND11_HAS_STRING_VIEW |
| 1190 | + // enable_if is needed to avoid "ambiguous conversion" errors (see PR #3521). |
| 1191 | + template <typename T, detail::enable_if_t<std::is_same<T, std::string_view>::value, int> = 0> |
| 1192 | + // NOLINTNEXTLINE(google-explicit-constructor) |
| 1193 | + bytes(T s) : bytes(s.data(), s.size()) { } |
| 1194 | + |
| 1195 | + // Obtain a string view that views the current `bytes` buffer value. Note that this is only |
| 1196 | + // valid so long as the `bytes` instance remains alive and so generally should not outlive the |
| 1197 | + // lifetime of the `bytes` instance. |
| 1198 | + // NOLINTNEXTLINE(google-explicit-constructor) |
| 1199 | + operator std::string_view() const { |
| 1200 | + char *buffer = nullptr; |
| 1201 | + ssize_t length = 0; |
| 1202 | + if (PYBIND11_BYTES_AS_STRING_AND_SIZE(m_ptr, &buffer, &length)) |
| 1203 | + pybind11_fail("Unable to extract bytes contents!"); |
| 1204 | + return {buffer, static_cast<size_t>(length)}; |
| 1205 | + } |
| 1206 | +#endif |
| 1207 | + |
1170 | 1208 | }; |
1171 | 1209 | // Note: breathe >= 4.17.0 will fail to build docs if the below two constructors |
1172 | 1210 | // are included in the doxygen group; close here and reopen after as a workaround |
@@ -1714,6 +1752,13 @@ class memoryview : public object { |
1714 | 1752 | static memoryview from_memory(const void *mem, ssize_t size) { |
1715 | 1753 | return memoryview::from_memory(const_cast<void*>(mem), size, true); |
1716 | 1754 | } |
| 1755 | + |
| 1756 | +#ifdef PYBIND11_HAS_STRING_VIEW |
| 1757 | + static memoryview from_memory(std::string_view mem) { |
| 1758 | + return from_memory(const_cast<char*>(mem.data()), static_cast<ssize_t>(mem.size()), true); |
| 1759 | + } |
| 1760 | +#endif |
| 1761 | + |
1717 | 1762 | #endif |
1718 | 1763 | }; |
1719 | 1764 |
|
|
0 commit comments