28 memset(&pyobj->
fBufInfo, 0,
sizeof(Py_buffer));
29 pyobj->
fBuf =
nullptr;
54 {(
char*)
"format", (getter)
ll_typecode,
nullptr,
nullptr,
nullptr},
55 {(
char*)
"typecode", (getter)
ll_typecode,
nullptr,
nullptr,
nullptr},
56 {(
char*)
nullptr,
nullptr,
nullptr,
nullptr,
nullptr }
64 if (!PyTuple_Check(shape) || PyTuple_GET_SIZE(shape) != 1) {
66 PyObject* pystr = PyObject_Str(shape);
68 PyErr_Format(PyExc_TypeError,
"tuple object of length 1 expected, received %s",
74 PyErr_SetString(PyExc_TypeError,
"tuple object of length 1 expected");
79 if (nlen == -1 && PyErr_Occurred())
86 PyErr_SetString(PyExc_TypeError,
"unsupported buffer dimensions");
95 {(
char*)
"reshape", (PyCFunction)
ll_reshape, METH_O,
nullptr},
96 {(
char*)
nullptr,
nullptr, 0,
nullptr}
107#define HAVE_PTR(suboffsets, dim) (suboffsets && suboffsets[dim] >= 0)
109#define ADJUST_PTR(ptr, suboffsets, dim) \
110 (HAVE_PTR(suboffsets, dim) ? *((char**)ptr) + suboffsets[dim] : ptr)
114#define HAVE_SUBOFFSETS_IN_LAST_DIM(view) \
115 (view->suboffsets && view->suboffsets[dest->ndim-1] >= 0)
120 assert(
dest->ndim > 0 &&
src->ndim > 0);
124 src->strides[
src->ndim-1] ==
src->itemsize);
136 for (
int i = 0; i <
dest->ndim; i++) {
137 if (
dest->shape[i] !=
src->shape[i])
139 if (
dest->shape[i] == 0)
151 if (strcmp(
dest->format,
src->format) != 0 ||
dest->itemsize !=
src->itemsize ||
153 PyErr_SetString(PyExc_ValueError,
154 "low level pointer assignment: lvalue and rvalue have different structures");
172 if (dptr +
size < sptr || sptr +
size < dptr)
173 memcpy(dptr, sptr,
size);
175 memmove(dptr, sptr,
size);
180 for (i=0,
p=mem; i < shape[0];
p+=itemsize, sptr+=sstrides[0], i++) {
181 char *xsptr =
ADJUST_PTR(sptr, ssuboffsets, 0);
182 memcpy(
p, xsptr, itemsize);
184 for (i=0,
p=mem; i < shape[0];
p+=itemsize, dptr+=dstrides[0], i++) {
185 char *xdptr =
ADJUST_PTR(dptr, dsuboffsets, 0);
186 memcpy(xdptr,
p, itemsize);
198 assert(
dest->ndim == 1);
204 mem = (
char*)PyMem_Malloc(
dest->shape[0] *
dest->itemsize);
213 (
char*)
src->buf,
src->strides,
src->suboffsets,
229 assert(view.strides);
235 if (index < 0 || index >=
nitems) {
236 PyErr_Format(PyExc_IndexError,
237 "index out of bounds on dimension %d", dim + 1);
241 ptr += view.strides[dim] *
index;
261 if (nindices > view.ndim) {
262 PyErr_Format(PyExc_TypeError,
263 "cannot index %d-dimension view with %zd-element tuple", view.ndim, nindices);
267 char* ptr = (
char*)llview->
get_buf();
268 for (
Py_ssize_t dim = 0; dim < nindices; dim++) {
272 if (
index == -1 && PyErr_Occurred())
295#if PY_VERSION_HEX < 0x03000000
296 PySliceObject* key = (PySliceObject*)_key;
301 if (PySlice_GetIndicesEx(key, base->shape[dim], &start, &stop, &step, &slicelength) < 0)
304 if (!base->suboffsets || dim == 0) {
306 base->buf = (
char *)base->buf + base->strides[dim] * start;
310 while (
n >= 0 && base->suboffsets[
n] < 0)
314 base->suboffsets[
n] = base->suboffsets[
n] + base->strides[dim] * start;
316 base->shape[dim] = slicelength;
317 base->strides[dim] = base->strides[dim] * step;
325 if (!PyTuple_Check(key))
334 if (!PySlice_Check(
x))
343 if (!PyTuple_Check(key))
365 PyErr_SetString(PyExc_ReferenceError,
"attempt to access a null-pointer");
369 if (view.ndim == 0) {
370 PyErr_SetString(PyExc_TypeError,
"invalid indexing of 0-dim memory");
388 if (nindices < view.ndim) {
390 PyErr_SetString(PyExc_NotImplementedError,
391 "sub-views are not implemented");
413 if (view.ndim == 0) {
414 if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) {
417 else if (key == Py_Ellipsis) {
422 PyErr_SetString(PyExc_TypeError,
423 "invalid indexing of 0-dim memory");
430 if (
index == -1 && PyErr_Occurred())
434 else if (PySlice_Check(key)) {
437 PyErr_SetString(PyExc_NotImplementedError,
438 "multi-dimensional slicing is not implemented");
445 PyErr_SetString(PyExc_NotImplementedError,
446 "multi-dimensional slicing is not implemented");
450 PyErr_SetString(PyExc_TypeError,
"invalid slice key");
461 PyErr_SetString(PyExc_TypeError,
"cannot modify read-only memory");
465 if (
value ==
nullptr) {
466 PyErr_SetString(PyExc_TypeError,
"cannot delete memory");
470 if (view.ndim == 0) {
471 if (key == Py_Ellipsis ||
472 (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0)) {
476 PyErr_SetString(PyExc_TypeError,
477 "invalid indexing of 0-dim memory");
485 PyErr_SetString(PyExc_NotImplementedError,
486 "sub-views are not implemented");
490 if (
index == -1 && PyErr_Occurred())
499 if (PySlice_Check(key) && view.ndim == 1) {
505 if (PyObject_GetBuffer(
value, &
src, PyBUF_FULL_RO) < 0)
509 dest.shape = &arrays[0];
dest.shape[0] = view.shape[0];
510 dest.strides = &arrays[1];
dest.strides[0] = view.strides[0];
511 if (view.suboffsets) {
512 dest.suboffsets = &arrays[2];
dest.suboffsets[0] = view.suboffsets[0];
524 if (PyTuple_GET_SIZE(key) < view.ndim) {
525 PyErr_SetString(PyExc_NotImplementedError,
526 "sub-views are not implemented");
537 PyErr_SetString(PyExc_NotImplementedError,
538 "LowLevelView slice assignments are currently restricted "
543 PyErr_SetString(PyExc_TypeError,
"invalid slice key");
547#if PY_VERSION_HEX < 0x03000000
552 PyErr_SetString(PyExc_TypeError,
"accessing non-existent segment");
576 if (!(flags & PyBUF_FORMAT)) {
585 if ((flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) {
586 PyErr_SetString(PyExc_BufferError,
587 "underlying buffer is not Fortran contiguous");
591 if (!(flags & PyBUF_FORMAT)) {
594 if (view->format != NULL) {
597 PyErr_Format(PyExc_BufferError,
598 "cannot cast to unsigned bytes if the format flag is present");
608 Py_INCREF(view->obj);
637#if PY_VERSION_HEX < 0x03000000
653 (
char*)
"cppyy.LowLevelView",
671 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
673 (
char*)
"memory view on C++ pointer",
698#
if PY_VERSION_HEX >= 0x02030000
701#
if PY_VERSION_HEX >= 0x02060000
704#
if PY_VERSION_HEX >= 0x03040000
713template<
typename T>
struct typecode_traits {};
714template<>
struct typecode_traits<
bool> {
715 static constexpr const char*
format =
"?";
static constexpr const char*
name =
"bool"; };
716template<>
struct typecode_traits<signed char> {
717 static constexpr const char*
format =
"b";
static constexpr const char*
name =
"signed char"; };
718template<>
struct typecode_traits<unsigned char> {
719 static constexpr const char*
format =
"B";
static constexpr const char*
name =
"UCharAsInt"; };
720#if __cplusplus > 201402L
721template<>
struct typecode_traits<std::
byte> {
722 static constexpr const char*
format =
"B";
static constexpr const char*
name =
"UCharAsInt"; };
724template<>
struct typecode_traits<const char*> {
725 static constexpr const char*
format =
"b";
static constexpr const char*
name =
"const char*"; };
726template<>
struct typecode_traits<short> {
727 static constexpr const char*
format =
"h";
static constexpr const char*
name =
"short"; };
728template<>
struct typecode_traits<unsigned short> {
729 static constexpr const char*
format =
"H";
static constexpr const char*
name =
"unsigned short"; };
730template<>
struct typecode_traits<
int> {
731 static constexpr const char*
format =
"i";
static constexpr const char*
name =
"int"; };
732template<>
struct typecode_traits<unsigned
int> {
733 static constexpr const char*
format =
"I";
static constexpr const char*
name =
"unsigned int"; };
734template<>
struct typecode_traits<long> {
735 static constexpr const char*
format =
"l";
static constexpr const char*
736#if PY_VERSION_HEX < 0x03000000
742template<>
struct typecode_traits<unsigned long> {
743 static constexpr const char*
format =
"L";
static constexpr const char*
name =
"unsigned long"; };
744template<>
struct typecode_traits<long long> {
745 static constexpr const char*
format =
"q";
static constexpr const char*
name =
"long long"; };
746template<>
struct typecode_traits<unsigned long long> {
747 static constexpr const char*
format =
"Q";
static constexpr const char*
name =
"unsigned long long"; };
748template<>
struct typecode_traits<float> {
749 static constexpr const char*
format =
"f";
static constexpr const char*
name =
"float"; };
750template<>
struct typecode_traits<
double> {
751 static constexpr const char*
format =
"d";
static constexpr const char*
name =
"double"; };
752template<>
struct typecode_traits<long
double> {
753 static constexpr const char*
format =
"D";
static constexpr const char*
name =
"long double"; };
754template<>
struct typecode_traits<std::complex<float>> {
755 static constexpr const char*
format =
"Zf";
static constexpr const char*
name =
"std::complex<float>"; };
756template<>
struct typecode_traits<std::complex<double>> {
757 static constexpr const char*
format =
"Zd";
static constexpr const char*
name =
"std::complex<double>"; };
758template<>
struct typecode_traits<std::complex<int>> {
759 static constexpr const char*
format =
"Zi";
static constexpr const char*
name =
"std::complex<int>"; };
760template<>
struct typecode_traits<std::complex<long>> {
761 static constexpr const char*
format =
"Zl";
static constexpr const char*
name =
"std::complex<long>"; };
771 Py_ssize_t nx = (shape && 0 <= shape[1]) ? shape[1] : INT_MAX/
sizeof(T);
774 (
LowLevelView*)LowLevelView_Type.tp_new(&LowLevelView_Type, args,
nullptr);
781 view.format = (
char*)typecode_traits<T>::format;
782 view.ndim = shape ? (
int)shape[0] : 1;
786 view.suboffsets =
nullptr;
787 view.internal =
nullptr;
789 if (view.ndim == 1) {
791 view.len = nx *
sizeof(T);
792 view.itemsize =
sizeof(T);
793 llp->
fConverter = CreateConverter(typecode_traits<T>::name);
796 view.len = nx *
sizeof(
void*);
797 view.itemsize =
sizeof(
void*);
801 shape[1] = shape[0] - 1;
802 std::string tname{typecode_traits<T>::name};
805 llp->
fConverter = CreateConverter(tname, &shape[1]);
809 view.strides[0] = view.itemsize;
819 T* buf = address ? *address :
nullptr;
826#define CPPYY_IMPL_VIEW_CREATOR(type) \
827PyObject* CPyCppyy::CreateLowLevelView(type* address, Py_ssize_t* shape) { \
828 return CreateLowLevelViewT<type>(address, shape); \
830PyObject* CPyCppyy::CreateLowLevelView(type** address, Py_ssize_t* shape) { \
831 return CreateLowLevelViewT<type>(address, shape); \
837#if __cplusplus > 201402L
857 return CreateLowLevelViewT<const char*>(address, shape);
Py_ssize_t PyNumber_AsSsize_t(PyObject *obj, PyObject *)
#define CPyCppyy_PyText_AsStringChecked
#define CPyCppyy_PyText_FromString
#define PyVarObject_HEAD_INIT(type, size)
#define PyIndex_Check(obj)
static PyObject * CreateLowLevelViewT(T *address, Py_ssize_t *shape)
#define ADJUST_PTR(ptr, suboffsets, dim)
static PyObject * ll_typecode(CPyCppyy::LowLevelView *self, void *)
static void * ptr_from_index(CPyCppyy::LowLevelView *llview, Py_ssize_t index)
static int ll_ass_sub(CPyCppyy::LowLevelView *self, PyObject *key, PyObject *value)
static PyObject * ll_item_multi(CPyCppyy::LowLevelView *self, PyObject *tup)
static Py_ssize_t is_multiindex(PyObject *key)
static Py_ssize_t ll_oldgetbuf(CPyCppyy::LowLevelView *self, Py_ssize_t seg, void **pptr)
static PySequenceMethods ll_as_sequence
static Py_ssize_t ll_getsegcount(PyObject *, Py_ssize_t *lenp)
static PyObject * ll_reshape(CPyCppyy::LowLevelView *self, PyObject *shape)
static bool equiv_shape(const Py_buffer *dest, const Py_buffer *src)
static int ll_getbuf(CPyCppyy::LowLevelView *self, Py_buffer *view, int flags)
static void * ptr_from_tuple(CPyCppyy::LowLevelView *llview, PyObject *tup)
static int last_dim_is_contiguous(const Py_buffer *dest, const Py_buffer *src)
static PyBufferProcs ll_as_buffer
static PyMethodDef ll_methods[]
static bool equiv_structure(const Py_buffer *dest, const Py_buffer *src)
static void copy_base(const Py_ssize_t *shape, Py_ssize_t itemsize, char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets, char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets, char *mem)
static void ll_dealloc(CPyCppyy::LowLevelView *pyobj)
static PyMappingMethods ll_as_mapping
#define CPPYY_IMPL_VIEW_CREATOR(type)
static PyGetSetDef ll_getset[]
static CPyCppyy::LowLevelView * ll_new(PyTypeObject *subtype, PyObject *, PyObject *)
static PyObject * ll_item(CPyCppyy::LowLevelView *self, Py_ssize_t index)
static int copy_single(Py_buffer *dest, Py_buffer *src)
static int init_slice(Py_buffer *base, PyObject *_key, int dim)
static Py_ssize_t ll_length(CPyCppyy::LowLevelView *self)
static bool is_multislice(PyObject *key)
static PyObject * ll_subscript(CPyCppyy::LowLevelView *self, PyObject *key)
static char * lookup_dimension(Py_buffer &view, char *ptr, int dim, Py_ssize_t index)
#define HAVE_SUBOFFSETS_IN_LAST_DIM(view)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t nitems
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t format
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
virtual bool ToMemory(PyObject *value, void *address, PyObject *ctxt=nullptr)
virtual PyObject * FromMemory(void *address)
PyObject_HEAD Py_buffer fBufInfo
Set of helper functions that are invoked from the pythonizors, on the Python side.
PyObject * CreateLowLevelView(bool *, Py_ssize_t *shape=nullptr)
PyTypeObject LowLevelView_Type
#define dest(otri, vertexptr)