43#ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_PY_TUPLE_H
44#define LASS_GUARDIAN_OF_INCLUSION_UTIL_PY_TUPLE_H
51#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
53# pragma warning(disable: 4267)
66 inline bool tupleSetItems(PyObject* tuple, Py_ssize_t index,
const P& p)
68 PyObject* value = pyBuildSimpleObject(p);
69 return value && (PyTuple_SetItem(tuple, index, value) == 0);
75 template <
typename P,
typename... Ptail>
76 inline bool tupleSetItems(PyObject* tuple, Py_ssize_t index,
const P& p, Ptail&... tail)
78 PyObject* value = pyBuildSimpleObject(p);
79 return value && (PyTuple_SetItem(tuple, index, value) == 0)
80 && tupleSetItems(tuple, index + 1, tail...);
87 inline bool decodeObject(PyObject* in, Py_ssize_t index, P& out)
89 if (lass::python::pyGetSimpleObject(in, out) != 0)
91 std::ostringstream buffer;
92 buffer <<
"Bad Argument on " << (index + 1) <<
"th position";
102 template <
typename P>
103 inline bool decodeObjects(PyObject** objects, Py_ssize_t index, P& p)
105 return impl::decodeObject(objects[index], index, p);
111 template <
typename P,
typename... Ptail>
112 inline bool decodeObjects(PyObject** objects, Py_ssize_t index, P& p, Ptail&... tail)
114 return impl::decodeObject(objects[index], index, p)
115 && decodeObjects(objects, index + 1, tail...);
121 template <
typename P>
122 inline bool decodeObjectsMinimum(PyObject** objects, Py_ssize_t index, Py_ssize_t size, P& p)
125 || impl::decodeObject(objects[index], index, p);
131 template <
typename P,
typename... Ptail>
132 inline bool decodeObjectsMinimum(PyObject** objects, Py_ssize_t index, Py_ssize_t size, P& p, Ptail&... tail)
135 || (impl::decodeObject(objects[index], index, p)
136 && decodeObjectsMinimum(objects, index + 1, size, tail...));
152template <
typename... P>
156 TPyObjPtr tuple(PyTuple_New(
sizeof...(P)));
157 return tuple && impl::tupleSetItems(tuple.get(), 0, p...)
166inline int decodeTuple(PyObject* obj)
169 return impl::checkSequenceSize(obj, 0) ? 0 : 1;
174template <
typename... P>
175int decodeTuple(PyObject* obj, P&... p)
178 const TPyObjPtr tuple = impl::checkedFastSequence(obj,
sizeof...(P));
183 PyObject** objects = PySequence_Fast_ITEMS(tuple.get());
184 return impl::decodeObjects(objects, 0, p...)
193inline int decodeTuple(
const TPyObjPtr& obj)
195 return decodeTuple(obj.get());
200template <
typename... P>
201inline int decodeTuple(
const TPyObjPtr& obj, P&... p)
203 return decodeTuple(obj.get(), p...);
210template <
typename... P>
211int decodeTupleMinimum(PyObject* obj, Py_ssize_t minumumLength, P&... p)
214 const TPyObjPtr tuple = impl::checkedFastSequence(obj, minumumLength,
sizeof...(P));
219 const Py_ssize_t size = PySequence_Fast_GET_SIZE(tuple.get());
220 PyObject** objects = PySequence_Fast_ITEMS(tuple.get());
221 return impl::decodeObjectsMinimum(objects, 0, size, p...)
230template <
typename... P>
231int decodeTupleMinimum(
const TPyObjPtr& obj, Py_ssize_t minumumLength, P&... p)
233 return decodeTupleMinimum(obj.get(), minumumLength, p...);
243template <
typename T1,
typename T2>
246 constexpr static const char* py_typing =
"tuple[T1, T2]";
248 static PyObject* build(
const std::pair<T1, T2>& v)
253 static int get(PyObject* obj, std::pair<T1, T2>& v)
255 if (decodeTuple(obj, v.first, v.second) != 0)
268template <
typename... T>
271 constexpr static const char* py_typing =
"tuple[T...]";
273 static PyObject* build(
const std::tuple<T...>& v)
275 return doBuild(v, std::index_sequence_for<T...>());
277 static int get(PyObject* obj, std::tuple<T...>& v)
279 return doGet(obj, v, std::index_sequence_for<T...>());
283 template <std::size_t... I>
284 static PyObject* doBuild(
const std::tuple<T...>& v, std::index_sequence<I...>)
288 template <std::size_t... I>
289 static int doGet(PyObject* obj, std::tuple<T...>& v, std::index_sequence<I...>)
291 if (decodeTuple(obj, std::get<I>(v)...) != 0)
304#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
acquire the GIL for the current scope.
void addMessageHeader(const char *header)
Prepend a message to the current Python exception value.
PyObjectPtr< PyObject >::Type TPyObjPtr
PyObjectPtr to a PyObject.
PyObject * fromSharedPtrToNakedCast(const util::SharedPtr< T, PyObjectStorage, PyObjectCounter > &object)
fromSharedPtrToNakedCast.
Comprehensive C++ to Python binding library.
Library for Assembled Shared Sources.
by copy, general case assumes shadow type or PyObjectPlus based type.