50template <
typename string_type>
51int getStringImpl(PyObject* obj, string_type& v)
53 typedef typename string_type::value_type value_type;
54 static_assert(
sizeof(value_type) == 1,
"string_type should be narrow string");
55 if (!PyUnicode_Check(obj))
57 PyErr_SetString(PyExc_TypeError,
"not a string");
61 const char* data = PyUnicode_AsUTF8AndSize(obj, &size);
66 v = string_type(
reinterpret_cast<const value_type*
>(data),
static_cast<size_t>(size));
70template <
typename string_type>
71int getWideStringImpl(PyObject * obj, string_type& v)
73 typedef typename string_type::value_type value_type;
74 static_assert(
sizeof(value_type) ==
sizeof(wchar_t),
"string_type should be wide string");
75 if (!PyUnicode_Check(obj))
77 PyErr_SetString(PyExc_TypeError,
"not a string");
80 Py_ssize_t n = PyUnicode_AsWideChar(obj, 0, 0);
85 const Py_ssize_t size = n - 1;
91 string_type tmp(
static_cast<size_t>(size),
'\0');
92 if (PyUnicode_AsWideChar(obj,
reinterpret_cast<wchar_t*
>(&tmp[0]), size) == -1)
110PyObject* buildStringImpl(
const char* v,
size_t size)
116 if (size > PY_SSIZE_T_MAX)
118 PyErr_SetString(PyExc_OverflowError,
"input too long");
121 return PyUnicode_DecodeUTF8(v,
static_cast<Py_ssize_t
>(size), 0);
125PyObject* buildStringImpl(
const wchar_t* v,
size_t size)
131 if (size > PY_SSIZE_T_MAX)
133 PyErr_SetString(PyExc_OverflowError,
"input too long");
136 return PyUnicode_FromWideChar(v,
static_cast<Py_ssize_t
>(size));
140#if LASS_HAVE_STD_U8STRING
142PyObject* buildStringImpl(
const char8_t* v,
size_t size)
144 return buildStringImpl(
reinterpret_cast<const char*
>(v), size);
150PyObject* buildStringImpl(
const char16_t* v,
size_t size)
156 if (size > (PY_SSIZE_T_MAX / 2))
158 PyErr_SetString(PyExc_OverflowError,
"input too long");
161 return PyUnicode_DecodeUTF16(
reinterpret_cast<const char*
>(v),
static_cast<Py_ssize_t
>(size * 2),
nullptr,
nullptr);
165PyObject* buildStringImpl(
const char32_t* v,
size_t size)
171 if (size > (PY_SSIZE_T_MAX / 4))
173 PyErr_SetString(PyExc_OverflowError,
"input too long");
176 return PyUnicode_DecodeUTF32(
reinterpret_cast<const char*
>(v),
static_cast<Py_ssize_t
>(size * 4),
nullptr,
nullptr);
183PyObject* PyExportTraits<void*>::build(
void* value)
189 return PyCapsule_New(value, 0, 0);
193int PyExportTraits<void*>::get(PyObject* obj,
void*& value)
200 if (!PyCapsule_CheckExact(obj))
202 PyErr_SetString(PyExc_TypeError,
"does not evaluate to a void*");
205 void* v = PyCapsule_GetPointer(obj, 0);
216PyObject* PyExportTraits<std::nullptr_t>::build(std::nullptr_t )
222int PyExportTraits<std::nullptr_t>::get(PyObject* obj, std::nullptr_t& value)
226 PyErr_SetString(PyExc_TypeError,
"must be None");
235PyObject* PyExportTraits<bool>::build(
bool v)
248int PyExportTraits<bool>::get(PyObject* obj,
bool& v)
250 int result = PyObject_IsTrue(obj);
253 PyErr_SetString(PyExc_TypeError,
"does not evaluate to a boolean");
263PyObject* PyExportTraits<signed PY_LONG_LONG>::build(
signed PY_LONG_LONG v)
265 return PyLong_FromLongLong(v);
269int PyExportTraits<signed PY_LONG_LONG>::get(PyObject* obj,
signed PY_LONG_LONG& v)
271#if LASS_USE_OLD_EXPORTRAITS_INT
272 if (PyLong_Check(obj))
274 v = PyLong_AsLongLong(obj);
277 PyErr_SetString(PyExc_TypeError,
"not an integer");
280# if PY_VERSION_HEX < 0x030a0000
284 if (!PyLong_Check(obj))
292 return PyExportTraits<signed PY_LONG_LONG>::get(o.get(), v);
295 v = PyLong_AsLongLong(obj);
296 if (v == -1 && PyErr_Occurred())
305PyObject* PyExportTraits<unsigned PY_LONG_LONG>::build(
unsigned PY_LONG_LONG v)
307 return PyLong_FromUnsignedLongLong(v);
311int PyExportTraits<unsigned PY_LONG_LONG>::get(PyObject* obj,
unsigned PY_LONG_LONG& v)
313#if LASS_USE_OLD_EXPORTRAITS_INT
314 if (PyLong_Check(obj))
316 v = PyLong_AsUnsignedLongLong(obj);
319 PyErr_SetString(PyExc_TypeError,
"not an integer");
322 if (!PyLong_Check(obj))
332 return PyExportTraits<unsigned PY_LONG_LONG>::get(o.get(), v);
334 v = PyLong_AsUnsignedLongLong(obj);
335 if (v == ((
unsigned PY_LONG_LONG)-1) && PyErr_Occurred())
346PyObject* PyExportTraits<const char*>::build(
const char* v)
352 return PyExportTraits<std::string_view>::build(v);
356PyObject* PyExportTraits<std::string>::build(
const std::string& v)
358 return impl::buildStringImpl(v.data(), v.length());
362int PyExportTraits<std::string>::get(PyObject* obj, std::string& v)
364 return getStringImpl(obj, v);
368PyObject* PyExportTraits<const wchar_t*>::build(
const wchar_t* v)
374 return PyExportTraits<std::wstring_view>::build(v);
378PyObject* PyExportTraits<std::wstring>::build(
const std::wstring& v)
380 return impl::buildStringImpl(v.data(), v.length());
384int PyExportTraits<std::wstring>::get(PyObject* obj, std::wstring& v)
386 return getWideStringImpl(obj, v);
390#if LASS_HAVE_STD_U8STRING
392PyObject* PyExportTraits<const char8_t*>::build(
const char8_t* v)
398 return PyExportTraits<std::u8string_view>::build(v);
402PyObject* PyExportTraits<std::u8string>::build(
const std::u8string& v)
404 return impl::buildStringImpl(
reinterpret_cast<const char*
>(v.data()), v.length());
408int PyExportTraits<std::u8string>::get(PyObject* obj, std::u8string& v)
410 return getStringImpl(obj, v);
416PyObject* PyExportTraits<const char16_t*>::build(
const char16_t* v)
422 return PyExportTraits<std::u16string_view>::build(v);
426PyObject* PyExportTraits<std::u16string>::build(
const std::u16string& v)
428 return impl::buildStringImpl(v.data(), v.length());
432int PyExportTraits<std::u16string>::get(PyObject* obj, std::u16string& v)
434#if LASS_HAVE_WCHAR_T == 2
435 return getWideStringImpl(obj, v);
437 if (!PyUnicode_Check(obj))
439 PyErr_SetString(PyExc_TypeError,
"not a string");
442 if (PyUnicode_READY(obj) != 0)
446 if (PyUnicode_KIND(obj) == PyUnicode_2BYTE_KIND)
449 v = std::u16string(
reinterpret_cast<char16_t*
>(PyUnicode_2BYTE_DATA(obj)),
static_cast<size_t>(PyUnicode_GET_LENGTH(obj)));
452 TPyObjPtr bytes(PyUnicode_AsUTF16String(obj));
457 LASS_ASSERT(PyBytes_Check(bytes.get()));
458 const Py_ssize_t n = PyBytes_Size(bytes.get());
459 const char16_t* data =
reinterpret_cast<char16_t*
>(PyBytes_AsString(bytes.get()));
461 LASS_ASSERT(data[0] == 0xfeff);
462 v = std::u16string(data + 1,
static_cast<size_t>((n / 2) - 1));
468PyObject* PyExportTraits<const char32_t*>::build(
const char32_t* v)
474 return PyExportTraits<std::u32string_view>::build(v);
478PyObject* PyExportTraits<std::u32string>::build(
const std::u32string& v)
480 return impl::buildStringImpl(v.data(), v.length());
484int PyExportTraits<std::u32string>::get(PyObject* obj, std::u32string& v)
486#if LASS_HAVE_WCHAR_T == 4
487 return getWideStringImpl(obj, v);
489 if (!PyUnicode_Check(obj))
491 PyErr_SetString(PyExc_TypeError,
"not a string");
494 Py_ssize_t size = PyUnicode_GetLength(obj);
497 v = std::u32string();
500 std::u32string tmp(
static_cast<size_t>(size),
'\0');
501 if (PyUnicode_AsUCS4(obj,
reinterpret_cast<Py_UCS4*
>(&tmp[0]), size, 0) ==
nullptr)
PyObjectPtr< PyObject >::Type TPyObjPtr
PyObjectPtr to a PyObject.
Comprehensive C++ to Python binding library.
Library for Assembled Shared Sources.