wchar_raii now gives us a wstring_view on C++17

This commit is contained in:
Kovid Goyal 2023-01-13 15:40:45 +05:30
parent c7468a5f9a
commit 27f206f116
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 27 additions and 4 deletions

View File

@ -190,7 +190,7 @@
"headers": "calibre/utils/cpp_binding.h calibre/utils/windows/common.h",
"sources": "calibre/utils/windows/winspeech.cpp",
"libraries": "WindowsApp",
"cflags": "/X /std:c++17 /bigobj /await /permissive- /WX /Zc:twoPhase-"
"cflags": "/X /std:c++17 /Zc:__cplusplus /bigobj /await /permissive- /WX /Zc:twoPhase-"
},
{
"name": "wpd",

View File

@ -11,6 +11,9 @@
#define _UNICODE
#include <Python.h>
#include <wchar.h>
#if __cplusplus >= 201703L
#include <string_view>
#endif
#define arraysz(x) (sizeof(x)/sizeof(x[0]))
@ -41,7 +44,23 @@ class generic_raii {
explicit operator bool() const noexcept { return handle != null; }
};
#if __cplusplus >= 201703L
class wchar_raii : public generic_raii<wchar_t*, PyMem_Free> {
private:
Py_ssize_t sz;
public:
int from_unicode(PyObject *obj) {
wchar_t *buf = PyUnicode_AsWideCharString(obj, &sz);
if (!buf) return 0;
attach(buf);
return 1;
}
std::wstring_view as_view() const { return std::wstring_view(handle, sz); }
};
#else
typedef generic_raii<wchar_t*, PyMem_Free> wchar_raii;
#endif
static inline void python_object_destructor(void *p) { PyObject *x = reinterpret_cast<PyObject*>(p); Py_XDECREF(x); }
typedef generic_raii<PyObject*, python_object_destructor> pyobject_raii;
@ -93,8 +112,12 @@ py_to_wchar_no_none(PyObject *obj, wchar_raii *output) {
PyErr_SetString(PyExc_TypeError, "unicode object expected");
return 0;
}
#if __cplusplus >= 201703L
return output->from_unicode(obj);
#else
wchar_t *buf = PyUnicode_AsWideCharString(obj, NULL);
if (!buf) { PyErr_NoMemory(); return 0; }
output->attach(buf);
return 1;
if (!buf) { return 0; }
output->attach(buf);
return 1;
#endif
}