From 27f206f11634fa07109877e574d5c77c043b6a3a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 13 Jan 2023 15:40:45 +0530 Subject: [PATCH] wchar_raii now gives us a wstring_view on C++17 --- setup/extensions.json | 2 +- src/calibre/utils/cpp_binding.h | 29 ++++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/setup/extensions.json b/setup/extensions.json index b27071bf5b..6eae64d0d3 100644 --- a/setup/extensions.json +++ b/setup/extensions.json @@ -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", diff --git a/src/calibre/utils/cpp_binding.h b/src/calibre/utils/cpp_binding.h index 5de1dd81d0..c27332cb81 100644 --- a/src/calibre/utils/cpp_binding.h +++ b/src/calibre/utils/cpp_binding.h @@ -11,6 +11,9 @@ #define _UNICODE #include #include +#if __cplusplus >= 201703L +#include +#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 { + 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_raii; +#endif + static inline void python_object_destructor(void *p) { PyObject *x = reinterpret_cast(p); Py_XDECREF(x); } typedef generic_raii 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 }