43#ifndef LASS_GUARDIAN_OF_INCLUSION_PYTHON_EXPORT_TRAITS_H
44#define LASS_GUARDIAN_OF_INCLUSION_PYTHON_EXPORT_TRAITS_H
291 template <
typename T>
struct ShadowTraits;
293 template <
typename In,
typename Out>
294 [[deprecated]]
int pyNumCast(In in, Out& out)
298 out = num::numCast<Out>(in);
300 catch (
const std::exception& error)
302 PyErr_SetString(PyExc_TypeError, error.what());
308 template <
typename T>
309 using NoNone [[deprecated(
"lass::python::NoNone<T> instead.")]] = lass::python::NoNone<T>;
311 LASS_PYTHON_DLL PyObject* buildStringImpl(
const char* s,
size_t n);
312 LASS_PYTHON_DLL PyObject* buildStringImpl(
const wchar_t* s,
size_t n);
313#if LASS_HAVE_STD_U8STRING
315 LASS_PYTHON_DLL PyObject* buildStringImpl(
const char8_t* s,
size_t n);
318 LASS_PYTHON_DLL PyObject* buildStringImpl(
const char16_t* s,
size_t n);
319 LASS_PYTHON_DLL PyObject* buildStringImpl(
const char32_t* s,
size_t n);
328 typedef impl::ShadowTraits<typename ShadoweeTraits<T>::TShadow> TShadowTraits;
329 static PyObject* build(
const T& v)
333 static int get(PyObject* obj, T& v)
335 return TShadowTraits::getObject(obj, v);
345 static PyObject* build(
const T& v)
347 return PyExportTraits<T>::build(v);
359 typedef impl::ShadowTraits<typename ShadoweeTraits<T>::TShadow> TShadowTraits;
360 static PyObject* build(T* value)
368 static int get(PyObject* obj, T*& value)
375 return TShadowTraits::getObject(obj, value);
389template <
typename T,
template <
typename,
typename>
class S,
typename C>
392 constexpr static const char* py_typing =
"T | None";
394 typedef impl::ShadowTraits<typename ShadoweeTraits<T>::TShadow> TShadowTraits;
395 typedef util::SharedPtr<T, S, C> TPtr;
396 static PyObject* build(
const TPtr& value)
404 static int get(PyObject* obj, TPtr& value)
411 return TShadowTraits::getObject(obj, value);
429 constexpr static const char* py_typing =
"Any";
431 static PyObject* build(
const TPyObjPtr& v)
439 static int get(PyObject* obj,
TPyObjPtr& v)
490template <
typename T,
typename Deleter>
493 constexpr static const char* py_typing =
"T | None";
495 typedef impl::ShadowTraits<typename ShadoweeTraits<T>::TShadow> TShadowTraits;
496 static PyObject* build(std::unique_ptr<T, Deleter>&& value)
513 constexpr static const char* py_typing =
"T | None";
515 typedef impl::ShadowTraits<typename ShadoweeTraits<T>::TShadow> TShadowTraits;
516 typedef std::shared_ptr<T> TPtr;
517 static PyObject* build(
const TPtr& value)
525 static int get(PyObject* obj, TPtr& value)
532 return TShadowTraits::getObject(obj, value);
543 constexpr static const char* py_typing =
"Any";
545 LASS_PYTHON_DLL
static PyObject* build(
void* value);
546 LASS_PYTHON_DLL
static int get(PyObject* obj,
void*& value);
554struct PyExportTraits<std::nullptr_t>
556 constexpr static const char* py_typing =
"None";
558 LASS_PYTHON_DLL
static PyObject* build(std::nullptr_t value);
559 LASS_PYTHON_DLL
static int get(PyObject* obj, std::nullptr_t& value);
597 constexpr static const char* py_typing =
"T";
602 const T& v =
static_cast<const T&
>(value);
605 PyErr_SetString(PyExc_TypeError,
"value must be not be None");
608 return PyExportTraits<T>::build(value);
615 PyErr_SetString(PyExc_TypeError,
"argument must be not be None");
618 return PyExportTraits<T>::get(obj, value);
640template <
typename T,
template <
typename,
typename>
class S,
typename C>
697 constexpr static const char* py_typing =
"T | MaybeNone";
698 constexpr static const char* py_typing_preamble =
"from _typeshed import MaybeNone";
702 return PyExportTraits<T>::build(value);
724template <
typename T,
template <
typename,
typename>
class S,
typename C>
752 constexpr static const char* py_typing =
"Self";
753#if PY_VERSION_HEX < 0x030b0000
754 constexpr static const char* py_typing_preamble =
"from typing_extensions import Self";
756 constexpr static const char* py_typing_preamble =
"from typing import Self";
769 constexpr static const char* py_typing =
"bool";
771 LASS_PYTHON_DLL
static PyObject* build(
bool v);
772 LASS_PYTHON_DLL
static int get(PyObject* obj,
bool& v);
784template <
typename Integer>
787 constexpr static const char* py_typing =
"int";
789 LASS_META_ASSERT(
sizeof(Integer) <=
sizeof(
long), integer_should_fit_in_long);
790 static PyObject* build(Integer v)
792 return PyLong_FromLong(v);
794 static int get(PyObject* obj, Integer& v)
796#if LASS_USE_OLD_EXPORTRAITS_INT
797 if (PyLong_Check(obj))
800 const PY_LONG_LONG x = PyLong_AsLongLong(obj);
802 const long x = PyLong_AsLong(obj);
804 if (PyErr_Occurred())
806 PyErr_Format(PyExc_TypeError,
"not a %s: overflow", num::NumTraits<Integer>::name().c_str());
809 return impl::pyNumCast(x, v);
811 PyErr_SetString(PyExc_TypeError,
"not an integer");
814# if PY_VERSION_HEX < 0x030a0000
818 if (!PyLong_Check(obj))
826 return PyExportTraits<Integer>::get(o.get(), v);
830 const PY_LONG_LONG x = PyLong_AsLongLong(obj);
832 const long x = PyLong_AsLong(obj);
834 if (x == -1 && PyErr_Occurred())
840 v = num::numCast<Integer>(x);
842 catch (
const num::BadNumCast& err)
844 PyErr_SetString(PyExc_OverflowError, err.what());
906template <
typename Integer>
909 constexpr static const char* py_typing =
"int";
911 LASS_META_ASSERT(
sizeof(Integer) <=
sizeof(
unsigned long), integer_should_fit_in_unsigned_long);
912 static PyObject* build(Integer v)
914 return PyLong_FromUnsignedLong(v);
916 static int get(PyObject* obj, Integer& v)
918#if LASS_USE_OLD_EXPORTRAITS_INT
919 if (PyLong_Check(obj))
922 const unsigned PY_LONG_LONG x = PyLong_AsUnsignedLongLong(obj);
924 const unsigned long x = PyLong_AsUnsignedLong(obj);
926 if (PyErr_Occurred())
928 PyErr_Format(PyExc_TypeError,
"not a %s: overflow", num::NumTraits<Integer>::name().c_str());
931 return impl::pyNumCast(x, v);
933 PyErr_SetString(PyExc_TypeError,
"not an integer");
936 if (!PyLong_Check(obj))
946 return PyExportTraits<Integer>::get(o.get(), v);
949 const unsigned PY_LONG_LONG x = PyLong_AsUnsignedLongLong(obj);
950 if (x == ((
unsigned PY_LONG_LONG) - 1) && PyErr_Occurred())
955 const unsigned long x = PyLong_AsUnsignedLong(obj);
956 if (x == ((
unsigned long) - 1) && PyErr_Occurred())
963 v = num::numCast<Integer>(x);
965 catch (
const num::BadNumCast& err)
967 PyErr_SetString(PyExc_OverflowError, err.what());
1021#ifdef HAVE_LONG_LONG
1032 constexpr static const char* py_typing =
"int";
1034 LASS_PYTHON_DLL
static PyObject* build(
signed PY_LONG_LONG v);
1035 LASS_PYTHON_DLL
static int get(PyObject* obj,
signed PY_LONG_LONG& v);
1045struct PyExportTraits<unsigned PY_LONG_LONG>
1047 constexpr static const char* py_typing =
"int";
1049 LASS_PYTHON_DLL
static PyObject* build(
unsigned PY_LONG_LONG v);
1050 LASS_PYTHON_DLL
static int get(PyObject* obj,
unsigned PY_LONG_LONG& v);
1062template <
typename Float>
1065 constexpr static const char* py_typing =
"float";
1066 constexpr static const char* py_typing_param =
"_Float";
1067 constexpr static const char* py_typing_preamble =
1068 "from typing import SupportsFloat, SupportsIndex\n"
1069 "type _Float = float | SupportsFloat | SupportsIndex\n";
1071 static PyObject* build(Float v)
1073 return PyFloat_FromDouble(v);
1075 static int get(PyObject* obj, Float& v)
1077#if LASS_USE_OLD_EXPORTRAITS_FLOAT
1078 if (PyFloat_Check(obj))
1080 return impl::pyNumCast(PyFloat_AS_DOUBLE(obj), v);
1082 if (PyLong_Check(obj))
1084 const double x = PyLong_AsDouble(obj);
1085 if (PyErr_Occurred())
1087 PyErr_Format(PyExc_TypeError,
"not a %s: overflow", num::NumTraits<Float>::name().c_str());
1090 return impl::pyNumCast(x, v);
1092 PyErr_SetString(PyExc_TypeError,
"not a float or integer");
1096 if (PyFloat_CheckExact(obj))
1098 x = PyFloat_AS_DOUBLE(obj);
1100 else if (PyLong_Check(obj))
1102 x = PyLong_AsDouble(obj);
1103 if (x == -1.0 && PyErr_Occurred())
1110 x = PyFloat_AsDouble(obj);
1111 if (x == -1.0 && PyErr_Occurred())
1116 v =
static_cast<Float
>(x);
1189template <
typename T>
1192 constexpr static const char* py_typing =
"complex";
1193 constexpr static const char* py_typing_param =
"_Complex";
1194 constexpr static const char* py_typing_preamble =
1195 "from typing import SupportsComplex, SupportsFloat, SupportsIndex\n"
1196 "type _Complex = complex | SupportsComplex | SupportsFloat | SupportsIndex\n";
1198 static PyObject* build(
const std::complex<T>& v)
1200 return PyComplex_FromDoubles(
1201 static_cast<double>(v.real()),
1202 static_cast<double>(v.imag()));
1204 static int get(PyObject* obj, std::complex<T>& v)
1206#if LASS_USE_OLD_EXPORTRAITS_COMPLEX
1208 if (PyExportTraits<T>::get(obj, re) == 0)
1210 v = std::complex<T>(re, 0);
1214 if (!PyComplex_Check(obj))
1216 PyErr_SetString(PyExc_TypeError,
"not a complex number");
1219 if (impl::pyNumCast(PyComplex_RealAsDouble(obj), re) != 0)
1223 if (impl::pyNumCast(PyComplex_ImagAsDouble(obj), im) != 0)
1227 v = std::complex<T>(re, im);
1230 Py_complex c = PyComplex_AsCComplex(obj);
1231 if (c.real == -1.0 && PyErr_Occurred())
1235 v = std::complex<T>(
static_cast<T
>(c.real),
static_cast<T
>(c.imag));
1252template <
typename T>
1255 constexpr static const char* py_typing =
"str";
1257 static PyObject* build(std::basic_string_view<T> v)
1259 return impl::buildStringImpl(v.data(), v.size());
1269 constexpr static const char* py_typing =
"str | None";
1271 LASS_PYTHON_DLL
static PyObject* build(
const char* v);
1278struct PyExportTraits<const char [N]>
1280 static PyObject* build(
const char* v)
1282 static_assert(N > 1,
"N should include the null-terminator");
1283 return impl::buildStringImpl(v, N - 1);
1301 constexpr static const char* py_typing =
"str";
1303 LASS_PYTHON_DLL
static PyObject* build(
const std::string& v);
1304 LASS_PYTHON_DLL
static int get(PyObject* obj, std::string& v);
1313 constexpr static const char* py_typing =
"str | None";
1315 LASS_PYTHON_DLL
static PyObject* build(
const wchar_t* v);
1324 static PyObject* build(
const wchar_t* v)
1326 return impl::buildStringImpl(v, N);
1344 constexpr static const char* py_typing =
"str";
1346 LASS_PYTHON_DLL
static PyObject* build(
const std::wstring& v);
1347 LASS_PYTHON_DLL
static int get(PyObject* obj, std::wstring& v);
1351#if LASS_HAVE_STD_U8STRING
1352#if __cpp_lib_char8_t
1366 constexpr static const char* py_typing =
"str | None";
1368 LASS_PYTHON_DLL
static PyObject* build(
const char8_t* v);
1377 static PyObject* build(
const char8_t* v)
1379 return impl::buildStringImpl(v, N);
1399 constexpr static const char* py_typing =
"str";
1401 LASS_PYTHON_DLL
static PyObject* build(
const std::u8string& v);
1402 LASS_PYTHON_DLL
static int get(PyObject* obj, std::u8string& v);
1421 constexpr static const char* py_typing =
"str | None";
1423 LASS_PYTHON_DLL
static PyObject* build(
const char16_t* v);
1432 static PyObject* build(
const char16_t* v)
1434 return impl::buildStringImpl(v, N);
1442struct PyExportTraits<char16_t[N]> : PyExportTraits<const char16_t[N]>
1454 constexpr static const char* py_typing =
"str";
1456 LASS_PYTHON_DLL
static PyObject* build(
const std::u16string& v);
1457 LASS_PYTHON_DLL
static int get(PyObject* obj, std::u16string& v);
1473 constexpr static const char* py_typing =
"str | None";
1475 LASS_PYTHON_DLL
static PyObject* build(
const char32_t* v);
1484 static PyObject* build(
const char32_t* v)
1486 return impl::buildStringImpl(v, N);
1494struct PyExportTraits<char32_t[N]> : PyExportTraits<const char32_t[N]>
1506 constexpr static const char* py_typing =
"str";
1508 LASS_PYTHON_DLL
static PyObject* build(
const std::u32string& v);
1509 LASS_PYTHON_DLL
static int get(PyObject* obj, std::u32string& v);
Wrapper to type-hint return values in Python that maybe None but not likely.
Wrapper to prevent None values being passed to and from Python.
Wrapper to type-hint a return value as Self.
PyObjectPtr< PyObject >::Type TPyObjPtr
PyObjectPtr to a PyObject.
PyObject * fromSharedPtrToNakedCast(const util::SharedPtr< T, PyObjectStorage, PyObjectCounter > &object)
fromSharedPtrToNakedCast.
lass::util::SharedPtr< T, PyObjectStorage, PyObjectCounter > fromNakedToSharedPtrCast(PyObject *object)
fromNakedToSharedPtrCast.
ColorRGBA out(const ColorRGBA &a, const ColorRGBA &b)
a held out by b, part of a outside b.
Comprehensive C++ to Python binding library.
general utility, debug facilities, ...
Library for Assembled Shared Sources.
Helper class to create PyExportTraits for floating point numbers.
Helper class to create PyExportTraits for MaybeNone wrapped types.
Helper class to create PyExportTraits for NoNone wrapped types.
static PyObject * build(const NoNone< T > &value)
Raise a Python TypeError if value is equal to nullptr
static int get(PyObject *obj, NoNone< T > &value)
Raise a Python TypeError if obj is equal to None
Helper class to create PyExportTraits for signed integers.
Helper class to create PyExportTraits for unsigned integers.
by copy, general case assumes shadow type or PyObjectPlus based type.