mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-26 07:02:11 +00:00
Working type casters for wide strings and wide characters
This commit is contained in:
commit
81dfd2c51f
@ -92,6 +92,7 @@ Significant features and/or improvements to the code were contributed by
|
|||||||
Jonas Adler,
|
Jonas Adler,
|
||||||
Sylvain Corlay,
|
Sylvain Corlay,
|
||||||
Axel Huebl,
|
Axel Huebl,
|
||||||
|
@hulucc,
|
||||||
Johan Mabille,
|
Johan Mabille,
|
||||||
Tomasz Miąsko, and
|
Tomasz Miąsko, and
|
||||||
Ben Pritchard.
|
Ben Pritchard.
|
||||||
|
@ -241,10 +241,14 @@ as arguments and return values, refer to the section on binding :ref:`classes`.
|
|||||||
+----------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| char | Character literal | pybind11/pybind11.h |
|
| char | Character literal | pybind11/pybind11.h |
|
||||||
+----------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
|
| wchar_t | Wide character literal | pybind11/pybind11.h |
|
||||||
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| const char * | UTF-8 string literal | pybind11/pybind11.h |
|
| const char * | UTF-8 string literal | pybind11/pybind11.h |
|
||||||
+----------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| std::string | STL dynamic UTF-8 string | pybind11/pybind11.h |
|
| std::string | STL dynamic UTF-8 string | pybind11/pybind11.h |
|
||||||
+----------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
|
| std::wstring | STL dynamic wide string | pybind11/pybind11.h |
|
||||||
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| std::pair<T1, T2> | Pair of two custom types | pybind11/pybind11.h |
|
| std::pair<T1, T2> | Pair of two custom types | pybind11/pybind11.h |
|
||||||
+----------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| std::tuple<....> | Arbitrary tuple of types | pybind11/pybind11.h |
|
| std::tuple<....> | Arbitrary tuple of types | pybind11/pybind11.h |
|
||||||
|
@ -5,8 +5,7 @@ Changelog
|
|||||||
|
|
||||||
1.4 (not yet released)
|
1.4 (not yet released)
|
||||||
--------------------------
|
--------------------------
|
||||||
TBD
|
* Transparent type conversion for ``std::wstring`` and ``wchar_t``
|
||||||
|
|
||||||
|
|
||||||
1.3 (March 8, 2016)
|
1.3 (March 8, 2016)
|
||||||
--------------------------
|
--------------------------
|
||||||
|
@ -60,9 +60,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* C++ STL data types are automatically casted */
|
/* C++ STL data types are automatically casted */
|
||||||
std::vector<std::string> get_list_2() {
|
std::vector<std::wstring> get_list_2() {
|
||||||
std::vector<std::string> list;
|
std::vector<std::wstring> list;
|
||||||
list.push_back("value");
|
list.push_back(L"value");
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,10 +103,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* STL data types (such as vectors) are automatically casted from Python */
|
/* STL data types (such as vectors) are automatically casted from Python */
|
||||||
void print_list_2(std::vector<std::string> &list) {
|
void print_list_2(std::vector<std::wstring> &list) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (auto item : list)
|
for (auto item : list)
|
||||||
std::cout << "list item " << index++ << ": " << item << std::endl;
|
std::wcout << L"list item " << index++ << L": " << item << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pybind automatically translates between C++11 and Python tuples */
|
/* pybind automatically translates between C++11 and Python tuples */
|
||||||
|
@ -349,22 +349,45 @@ public:
|
|||||||
PYBIND11_TYPE_CASTER(std::string, _(PYBIND11_STRING_NAME));
|
PYBIND11_TYPE_CASTER(std::string, _(PYBIND11_STRING_NAME));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> class type_caster<char> {
|
template <> class type_caster<std::wstring> {
|
||||||
public:
|
public:
|
||||||
bool load(handle src, bool) {
|
bool load(handle src, bool) {
|
||||||
object temp;
|
object temp;
|
||||||
handle load_src = src;
|
handle load_src = src;
|
||||||
if (PyUnicode_Check(load_src.ptr())) {
|
if (!PyUnicode_Check(load_src.ptr())) {
|
||||||
temp = object(PyUnicode_AsUTF8String(load_src.ptr()), false);
|
temp = object(PyUnicode_FromObject(load_src.ptr()), false);
|
||||||
if (!temp) { PyErr_Clear(); return false; } // UnicodeEncodeError
|
if (!temp) { PyErr_Clear(); return false; }
|
||||||
load_src = temp;
|
load_src = temp;
|
||||||
}
|
}
|
||||||
const char *ptr = PYBIND11_BYTES_AS_STRING(load_src.ptr());
|
wchar_t *buffer = nullptr;
|
||||||
if (!ptr) { PyErr_Clear(); return false; } // TypeError
|
ssize_t length = -1;
|
||||||
value = std::string(ptr);
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
buffer = PyUnicode_AsWideCharString(load_src.ptr(), &length);
|
||||||
|
#else
|
||||||
|
temp = object(
|
||||||
|
sizeof(wchar_t) == sizeof(short)
|
||||||
|
? PyUnicode_AsUTF16String(load_src.ptr())
|
||||||
|
: PyUnicode_AsUTF32String(load_src.ptr()), false);
|
||||||
|
if (temp) {
|
||||||
|
int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), (char **) &buffer, &length);
|
||||||
|
if (err == -1) { buffer = nullptr; } // TypeError
|
||||||
|
length = length / sizeof(wchar_t) - 1; ++buffer; // Skip BOM
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!buffer) { PyErr_Clear(); return false; }
|
||||||
|
value = std::wstring(buffer, length);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static handle cast(const std::wstring &src, return_value_policy /* policy */, handle /* parent */) {
|
||||||
|
return PyUnicode_FromWideChar(src.c_str(), src.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
PYBIND11_TYPE_CASTER(std::wstring, _(PYBIND11_STRING_NAME));
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> class type_caster<char> : public type_caster<std::string> {
|
||||||
|
public:
|
||||||
static handle cast(const char *src, return_value_policy /* policy */, handle /* parent */) {
|
static handle cast(const char *src, return_value_policy /* policy */, handle /* parent */) {
|
||||||
return PyUnicode_FromString(src);
|
return PyUnicode_FromString(src);
|
||||||
}
|
}
|
||||||
@ -382,6 +405,25 @@ protected:
|
|||||||
std::string value;
|
std::string value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <> class type_caster<wchar_t> : public type_caster<std::wstring> {
|
||||||
|
public:
|
||||||
|
static handle cast(const wchar_t *src, return_value_policy /* policy */, handle /* parent */) {
|
||||||
|
return PyUnicode_FromWideChar(src, wcslen(src));
|
||||||
|
}
|
||||||
|
|
||||||
|
static handle cast(wchar_t src, return_value_policy /* policy */, handle /* parent */) {
|
||||||
|
wchar_t wstr[2] = { src, L'\0' };
|
||||||
|
return PyUnicode_FromWideChar(wstr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator wchar_t*() { return (wchar_t *)value.c_str(); }
|
||||||
|
operator wchar_t() { if (value.length() > 0) return value[0]; else return L'\0'; }
|
||||||
|
|
||||||
|
static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); }
|
||||||
|
protected:
|
||||||
|
std::wstring value;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T1, typename T2> class type_caster<std::pair<T1, T2>> {
|
template <typename T1, typename T2> class type_caster<std::pair<T1, T2>> {
|
||||||
typedef std::pair<T1, T2> type;
|
typedef std::pair<T1, T2> type;
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user