xnd 0.2.0dev3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +42 -0
- data/Gemfile +3 -0
- data/History.md +0 -0
- data/README.md +7 -0
- data/Rakefile +135 -0
- data/ext/ruby_xnd/extconf.rb +70 -0
- data/ext/ruby_xnd/float_pack_unpack.c +277 -0
- data/ext/ruby_xnd/float_pack_unpack.h +39 -0
- data/ext/ruby_xnd/gc_guard.c +36 -0
- data/ext/ruby_xnd/gc_guard.h +12 -0
- data/ext/ruby_xnd/include/xnd.h +449 -0
- data/ext/ruby_xnd/lib/libxnd.a +0 -0
- data/ext/ruby_xnd/lib/libxnd.so +1 -0
- data/ext/ruby_xnd/lib/libxnd.so.0 +1 -0
- data/ext/ruby_xnd/lib/libxnd.so.0.2.0dev3 +0 -0
- data/ext/ruby_xnd/memory_block_object.c +32 -0
- data/ext/ruby_xnd/memory_block_object.h +33 -0
- data/ext/ruby_xnd/ruby_xnd.c +1953 -0
- data/ext/ruby_xnd/ruby_xnd.h +61 -0
- data/ext/ruby_xnd/ruby_xnd_internal.h +85 -0
- data/ext/ruby_xnd/util.h +170 -0
- data/ext/ruby_xnd/xnd/AUTHORS.txt +5 -0
- data/ext/ruby_xnd/xnd/INSTALL.txt +134 -0
- data/ext/ruby_xnd/xnd/LICENSE.txt +29 -0
- data/ext/ruby_xnd/xnd/MANIFEST.in +3 -0
- data/ext/ruby_xnd/xnd/Makefile.in +80 -0
- data/ext/ruby_xnd/xnd/README.rst +44 -0
- data/ext/ruby_xnd/xnd/config.guess +1530 -0
- data/ext/ruby_xnd/xnd/config.h.in +22 -0
- data/ext/ruby_xnd/xnd/config.sub +1782 -0
- data/ext/ruby_xnd/xnd/configure +4867 -0
- data/ext/ruby_xnd/xnd/configure.ac +164 -0
- data/ext/ruby_xnd/xnd/doc/Makefile +14 -0
- data/ext/ruby_xnd/xnd/doc/_static/copybutton.js +66 -0
- data/ext/ruby_xnd/xnd/doc/conf.py +26 -0
- data/ext/ruby_xnd/xnd/doc/index.rst +44 -0
- data/ext/ruby_xnd/xnd/doc/libxnd/data-structures.rst +186 -0
- data/ext/ruby_xnd/xnd/doc/libxnd/functions.rst +148 -0
- data/ext/ruby_xnd/xnd/doc/libxnd/index.rst +25 -0
- data/ext/ruby_xnd/xnd/doc/releases/index.rst +34 -0
- data/ext/ruby_xnd/xnd/doc/xnd/align-pack.rst +96 -0
- data/ext/ruby_xnd/xnd/doc/xnd/buffer-protocol.rst +42 -0
- data/ext/ruby_xnd/xnd/doc/xnd/index.rst +30 -0
- data/ext/ruby_xnd/xnd/doc/xnd/quickstart.rst +62 -0
- data/ext/ruby_xnd/xnd/doc/xnd/types.rst +674 -0
- data/ext/ruby_xnd/xnd/install-sh +527 -0
- data/ext/ruby_xnd/xnd/libxnd/Makefile.in +102 -0
- data/ext/ruby_xnd/xnd/libxnd/Makefile.vc +112 -0
- data/ext/ruby_xnd/xnd/libxnd/bitmaps.c +345 -0
- data/ext/ruby_xnd/xnd/libxnd/contrib.h +313 -0
- data/ext/ruby_xnd/xnd/libxnd/copy.c +944 -0
- data/ext/ruby_xnd/xnd/libxnd/equal.c +1216 -0
- data/ext/ruby_xnd/xnd/libxnd/inline.h +154 -0
- data/ext/ruby_xnd/xnd/libxnd/overflow.h +147 -0
- data/ext/ruby_xnd/xnd/libxnd/split.c +286 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.in +39 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.vc +44 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/README.txt +2 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/runtest.c +101 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/test.h +48 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/test_fixed.c +108 -0
- data/ext/ruby_xnd/xnd/libxnd/xnd.c +1304 -0
- data/ext/ruby_xnd/xnd/libxnd/xnd.h +449 -0
- data/ext/ruby_xnd/xnd/python/test_xnd.py +3144 -0
- data/ext/ruby_xnd/xnd/python/xnd/__init__.py +290 -0
- data/ext/ruby_xnd/xnd/python/xnd/_xnd.c +2822 -0
- data/ext/ruby_xnd/xnd/python/xnd/contrib/pretty.py +850 -0
- data/ext/ruby_xnd/xnd/python/xnd/docstrings.h +129 -0
- data/ext/ruby_xnd/xnd/python/xnd/pyxnd.h +200 -0
- data/ext/ruby_xnd/xnd/python/xnd/util.h +182 -0
- data/ext/ruby_xnd/xnd/python/xnd_randvalue.py +1121 -0
- data/ext/ruby_xnd/xnd/python/xnd_support.py +106 -0
- data/ext/ruby_xnd/xnd/setup.py +303 -0
- data/ext/ruby_xnd/xnd/vcbuild/INSTALL.txt +42 -0
- data/ext/ruby_xnd/xnd/vcbuild/runtest32.bat +16 -0
- data/ext/ruby_xnd/xnd/vcbuild/runtest64.bat +14 -0
- data/ext/ruby_xnd/xnd/vcbuild/vcbuild32.bat +29 -0
- data/ext/ruby_xnd/xnd/vcbuild/vcbuild64.bat +29 -0
- data/ext/ruby_xnd/xnd/vcbuild/vcclean.bat +13 -0
- data/ext/ruby_xnd/xnd/vcbuild/vcdistclean.bat +14 -0
- data/lib/ruby_xnd.so +0 -0
- data/lib/xnd.rb +306 -0
- data/lib/xnd/monkeys.rb +29 -0
- data/lib/xnd/version.rb +6 -0
- data/spec/debug_spec.rb +9 -0
- data/spec/gc_guard_spec.rb +10 -0
- data/spec/leakcheck.rb +9 -0
- data/spec/spec_helper.rb +877 -0
- data/spec/type_inference_spec.rb +81 -0
- data/spec/xnd_spec.rb +2921 -0
- data/xnd.gemspec +47 -0
- metadata +215 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* BSD 3-Clause License
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2017-2018, plures
|
|
5
|
+
* All rights reserved.
|
|
6
|
+
*
|
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
|
8
|
+
* modification, are permitted provided that the following conditions are met:
|
|
9
|
+
*
|
|
10
|
+
* 1. Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
* this list of conditions and the following disclaimer.
|
|
12
|
+
*
|
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
14
|
+
* this list of conditions and the following disclaimer in the documentation
|
|
15
|
+
* and/or other materials provided with the distribution.
|
|
16
|
+
*
|
|
17
|
+
* 3. Neither the name of the copyright holder nor the names of its
|
|
18
|
+
* contributors may be used to endorse or promote products derived from
|
|
19
|
+
* this software without specific prior written permission.
|
|
20
|
+
*
|
|
21
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
22
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
23
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
24
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
25
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
26
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
27
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
28
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
29
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
#include "pymacro.h"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
/******************************************************************************/
|
|
38
|
+
/* Module */
|
|
39
|
+
/******************************************************************************/
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
PyDoc_STRVAR(doc_module, "xnd module");
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
/******************************************************************************/
|
|
47
|
+
/* xnd properties */
|
|
48
|
+
/******************************************************************************/
|
|
49
|
+
|
|
50
|
+
PyDoc_STRVAR(doc_value,
|
|
51
|
+
"\n\
|
|
52
|
+
Convert the in-memory value to a Python value.\n\
|
|
53
|
+
\n\
|
|
54
|
+
>>> x = xnd([1, 2, 3, 4, 5])\n\
|
|
55
|
+
>>> x.value\n\
|
|
56
|
+
[1, 2, 3, 4, 5]\n\
|
|
57
|
+
\n");
|
|
58
|
+
|
|
59
|
+
PyDoc_STRVAR(doc_type,
|
|
60
|
+
"\n\
|
|
61
|
+
Return the type of the in-memory value.\n\
|
|
62
|
+
\n\
|
|
63
|
+
>>> x = xnd([[1, 2, 3], [4, 5]])\n\
|
|
64
|
+
>>> x.type\n\
|
|
65
|
+
ndt(\"var * var * int64\")\n\
|
|
66
|
+
\n");
|
|
67
|
+
|
|
68
|
+
PyDoc_STRVAR(doc_ndim,
|
|
69
|
+
"\n\
|
|
70
|
+
Return the number of dimensions of the in-memory value.\n\
|
|
71
|
+
\n\
|
|
72
|
+
>>> x = xnd([[(1, \"a\"), (2, \"b\")], [(3, \"x\"), (4, \"y\")]])\n\
|
|
73
|
+
>>> x.ndim\n\
|
|
74
|
+
2\n\
|
|
75
|
+
\n");
|
|
76
|
+
|
|
77
|
+
PyDoc_STRVAR(doc_align,
|
|
78
|
+
"\n\
|
|
79
|
+
Return the alignment of the memory block.\n\
|
|
80
|
+
\n\
|
|
81
|
+
>>> t = \"2 * {a: uint8, b: float64, align=512}\"\n\
|
|
82
|
+
>>> x = xnd([{'a': 1, 'b': 2.0}, {'a': 2, 'b': 3.0}], type=t)\n\
|
|
83
|
+
>>> x.align\n\
|
|
84
|
+
512\n\
|
|
85
|
+
\n");
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
/******************************************************************************/
|
|
89
|
+
/* xnd methods */
|
|
90
|
+
/******************************************************************************/
|
|
91
|
+
|
|
92
|
+
PyDoc_STRVAR(doc_short_value,
|
|
93
|
+
"short_value($self, /, maxshape=None)\n--\n\n\
|
|
94
|
+
Convert the in-memory value to an abbreviated Python value. Container types\n\
|
|
95
|
+
are converted to maxshape-1 actual values followed by an Ellipsis. If maxshape\n\
|
|
96
|
+
is None, the representation is not abbreviated.\n\
|
|
97
|
+
\n\
|
|
98
|
+
>>> x = xnd([1, 2, 3, 4, 5])\n\
|
|
99
|
+
>>> x.short_value(maxshape=3)\n\
|
|
100
|
+
[1, 2, ...]\n\
|
|
101
|
+
\n");
|
|
102
|
+
|
|
103
|
+
PyDoc_STRVAR(doc_empty,
|
|
104
|
+
"empty($type, type, /)\n--\n\n\
|
|
105
|
+
Class method that constructs a new xnd container according to the type\n\
|
|
106
|
+
argument. All values are initialized to zero.\n\
|
|
107
|
+
\n\
|
|
108
|
+
>>> xnd.empty(\"10 * 2 * (int64, string, complex128)\")\n\
|
|
109
|
+
xnd([[(0, '', 0j), (0, '', 0j)], [(0, '', 0j), (0, '', 0j)],\n\
|
|
110
|
+
[(0, '', 0j), (0, '', 0j)], [(0, '', 0j), (0, '', 0j)],\n\
|
|
111
|
+
[(0, '', 0j), (0, '', 0j)], [(0, '', 0j), (0, '', 0j)],\n\
|
|
112
|
+
[(0, '', 0j), (0, '', 0j)], [(0, '', 0j), (0, '', 0j)],\n\
|
|
113
|
+
[(0, '', 0j), (0, '', 0j)], ...], type=\"10 * 2 * (int64, string, complex128)\")\n\
|
|
114
|
+
\n");
|
|
115
|
+
|
|
116
|
+
PyDoc_STRVAR(doc_from_buffer,
|
|
117
|
+
"from_buffer($type, obj, /)\n--\n\n\
|
|
118
|
+
Class method that constructs a new xnd container from an object that supports\n\
|
|
119
|
+
the buffer protocol.\n\
|
|
120
|
+
\n\
|
|
121
|
+
>>> xnd.from_buffer(b\"123\")\n\
|
|
122
|
+
xnd([49, 50, 51], type=\"3 * uint8\")\n\
|
|
123
|
+
\n\
|
|
124
|
+
>>> import numpy as np\n\
|
|
125
|
+
>>> a = np.array([[1, 2, 3], [4, 5, 6]])\n\
|
|
126
|
+
>>> xnd.from_buffer(a)\n\
|
|
127
|
+
xnd([[1, 2, 3], [4, 5, 6]], type=\"2 * 3 * int64\")\n\
|
|
128
|
+
\n\
|
|
129
|
+
\n");
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* BSD 3-Clause License
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2017-2018, plures
|
|
5
|
+
* All rights reserved.
|
|
6
|
+
*
|
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
|
8
|
+
* modification, are permitted provided that the following conditions are met:
|
|
9
|
+
*
|
|
10
|
+
* 1. Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
* this list of conditions and the following disclaimer.
|
|
12
|
+
*
|
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
14
|
+
* this list of conditions and the following disclaimer in the documentation
|
|
15
|
+
* and/or other materials provided with the distribution.
|
|
16
|
+
*
|
|
17
|
+
* 3. Neither the name of the copyright holder nor the names of its
|
|
18
|
+
* contributors may be used to endorse or promote products derived from
|
|
19
|
+
* this software without specific prior written permission.
|
|
20
|
+
*
|
|
21
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
22
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
23
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
24
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
25
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
26
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
27
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
28
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
29
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
#ifndef PYXND_H
|
|
35
|
+
#define PYXND_H
|
|
36
|
+
#ifdef __cplusplus
|
|
37
|
+
extern "C" {
|
|
38
|
+
#endif
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
#include <Python.h>
|
|
42
|
+
#include "ndtypes.h"
|
|
43
|
+
#include "xnd.h"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
/****************************************************************************/
|
|
47
|
+
/* MemoryBlock Object */
|
|
48
|
+
/****************************************************************************/
|
|
49
|
+
|
|
50
|
+
/* This object owns the memory that is shared by several xnd objects. It is
|
|
51
|
+
never exposed to the Python level.
|
|
52
|
+
|
|
53
|
+
The memory block is created by the primary xnd object on initialization.
|
|
54
|
+
Sub-views, slices etc. share the memory block.
|
|
55
|
+
|
|
56
|
+
PEP-3118 imports are supported. At a later stage the mblock object will
|
|
57
|
+
potentially need to communicate with Arrow or other formats in order
|
|
58
|
+
to acquire and manage external memory blocks.
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
/* Exposed here for the benefit of Numba. The API should not be regarded
|
|
62
|
+
stable across versions. */
|
|
63
|
+
|
|
64
|
+
typedef struct {
|
|
65
|
+
PyObject_HEAD
|
|
66
|
+
PyObject *type; /* type owner */
|
|
67
|
+
xnd_master_t *xnd; /* memblock owner */
|
|
68
|
+
Py_buffer *view; /* PEP-3118 imports */
|
|
69
|
+
} MemoryBlockObject;
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
/****************************************************************************/
|
|
73
|
+
/* xnd object */
|
|
74
|
+
/****************************************************************************/
|
|
75
|
+
|
|
76
|
+
/* Exposed here for the benefit of Numba. The API should not be regarded
|
|
77
|
+
stable across versions. */
|
|
78
|
+
|
|
79
|
+
typedef struct {
|
|
80
|
+
PyObject_HEAD
|
|
81
|
+
MemoryBlockObject *mblock; /* owner of the primary type and memory block */
|
|
82
|
+
PyObject *type; /* owner of the current type */
|
|
83
|
+
xnd_t xnd; /* typed view, does not own anything */
|
|
84
|
+
} XndObject;
|
|
85
|
+
|
|
86
|
+
#define TYPE_OWNER(v) (((XndObject *)v)->type)
|
|
87
|
+
#define XND(v) (&(((XndObject *)v)->xnd))
|
|
88
|
+
#define XND_INDEX(v) (((XndObject *)v)->xnd.index)
|
|
89
|
+
#define XND_TYPE(v) (((XndObject *)v)->xnd.type)
|
|
90
|
+
#define XND_PTR(v) (((XndObject *)v)->xnd.ptr)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
/****************************************************************************/
|
|
94
|
+
/* Capsule API */
|
|
95
|
+
/****************************************************************************/
|
|
96
|
+
|
|
97
|
+
#define Xnd_CheckExact_INDEX 0
|
|
98
|
+
#define Xnd_CheckExact_RETURN int
|
|
99
|
+
#define Xnd_CheckExact_ARGS (const PyObject *)
|
|
100
|
+
|
|
101
|
+
#define Xnd_Check_INDEX 1
|
|
102
|
+
#define Xnd_Check_RETURN int
|
|
103
|
+
#define Xnd_Check_ARGS (const PyObject *)
|
|
104
|
+
|
|
105
|
+
#define CONST_XND_INDEX 2
|
|
106
|
+
#define CONST_XND_RETURN const xnd_t *
|
|
107
|
+
#define CONST_XND_ARGS (const PyObject *)
|
|
108
|
+
|
|
109
|
+
#define Xnd_EmptyFromType_INDEX 3
|
|
110
|
+
#define Xnd_EmptyFromType_RETURN PyObject *
|
|
111
|
+
#define Xnd_EmptyFromType_ARGS (PyTypeObject *, ndt_t *t)
|
|
112
|
+
|
|
113
|
+
#define Xnd_ViewMoveNdt_INDEX 4
|
|
114
|
+
#define Xnd_ViewMoveNdt_RETURN PyObject *
|
|
115
|
+
#define Xnd_ViewMoveNdt_ARGS (const PyObject *, ndt_t *t)
|
|
116
|
+
|
|
117
|
+
#define Xnd_FromXnd_INDEX 5
|
|
118
|
+
#define Xnd_FromXnd_RETURN PyObject *
|
|
119
|
+
#define Xnd_FromXnd_ARGS (PyTypeObject *, xnd_t *x)
|
|
120
|
+
|
|
121
|
+
#define Xnd_Subscript_INDEX 6
|
|
122
|
+
#define Xnd_Subscript_RETURN PyObject *
|
|
123
|
+
#define Xnd_Subscript_ARGS (const PyObject *self, const PyObject *key)
|
|
124
|
+
|
|
125
|
+
#define Xnd_FromXndMoveType_INDEX 7
|
|
126
|
+
#define Xnd_FromXndMoveType_RETURN PyObject *
|
|
127
|
+
#define Xnd_FromXndMoveType_ARGS (const PyObject *xnd, xnd_t *x)
|
|
128
|
+
|
|
129
|
+
#define Xnd_FromXndView_INDEX 8
|
|
130
|
+
#define Xnd_FromXndView_RETURN PyObject *
|
|
131
|
+
#define Xnd_FromXndView_ARGS (xnd_view_t *x)
|
|
132
|
+
|
|
133
|
+
#define Xnd_GetType_INDEX 9
|
|
134
|
+
#define Xnd_GetType_RETURN PyTypeObject *
|
|
135
|
+
#define Xnd_GetType_ARGS (void)
|
|
136
|
+
|
|
137
|
+
#define XND_MAX_API 10
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
#ifdef XND_MODULE
|
|
141
|
+
static Xnd_CheckExact_RETURN Xnd_CheckExact Xnd_CheckExact_ARGS;
|
|
142
|
+
static Xnd_Check_RETURN Xnd_Check Xnd_Check_ARGS;
|
|
143
|
+
static CONST_XND_RETURN CONST_XND CONST_XND_ARGS;
|
|
144
|
+
static Xnd_EmptyFromType_RETURN Xnd_EmptyFromType Xnd_EmptyFromType_ARGS;
|
|
145
|
+
static Xnd_ViewMoveNdt_RETURN Xnd_ViewMoveNdt Xnd_ViewMoveNdt_ARGS;
|
|
146
|
+
static Xnd_FromXnd_RETURN Xnd_FromXnd Xnd_FromXnd_ARGS;
|
|
147
|
+
static Xnd_Subscript_RETURN Xnd_Subscript Xnd_Subscript_ARGS;
|
|
148
|
+
static Xnd_FromXndMoveType_RETURN Xnd_FromXndMoveType Xnd_FromXndMoveType_ARGS;
|
|
149
|
+
static Xnd_FromXndView_RETURN Xnd_FromXndView Xnd_FromXndView_ARGS;
|
|
150
|
+
static Xnd_GetType_RETURN Xnd_GetType Xnd_GetType_ARGS;
|
|
151
|
+
#else
|
|
152
|
+
static void **_xnd_api;
|
|
153
|
+
|
|
154
|
+
#define Xnd_CheckExact \
|
|
155
|
+
(*(Xnd_CheckExact_RETURN (*)Xnd_CheckExact_ARGS) _xnd_api[Xnd_CheckExact_INDEX])
|
|
156
|
+
|
|
157
|
+
#define Xnd_Check \
|
|
158
|
+
(*(Xnd_Check_RETURN (*)Xnd_Check_ARGS) _xnd_api[Xnd_Check_INDEX])
|
|
159
|
+
|
|
160
|
+
#define CONST_XND \
|
|
161
|
+
(*(CONST_XND_RETURN (*)CONST_XND_ARGS) _xnd_api[CONST_XND_INDEX])
|
|
162
|
+
|
|
163
|
+
#define Xnd_EmptyFromType \
|
|
164
|
+
(*(Xnd_EmptyFromType_RETURN (*)Xnd_EmptyFromType_ARGS) _xnd_api[Xnd_EmptyFromType_INDEX])
|
|
165
|
+
|
|
166
|
+
#define Xnd_ViewMoveNdt \
|
|
167
|
+
(*(Xnd_ViewMoveNdt_RETURN (*)Xnd_ViewMoveNdt_ARGS) _xnd_api[Xnd_ViewMoveNdt_INDEX])
|
|
168
|
+
|
|
169
|
+
#define Xnd_FromXnd \
|
|
170
|
+
(*(Xnd_FromXnd_RETURN (*)Xnd_FromXnd_ARGS) _xnd_api[Xnd_FromXnd_INDEX])
|
|
171
|
+
|
|
172
|
+
#define Xnd_Subscript \
|
|
173
|
+
(*(Xnd_Subscript_RETURN (*)Xnd_Subscript_ARGS) _xnd_api[Xnd_Subscript_INDEX])
|
|
174
|
+
|
|
175
|
+
#define Xnd_FromXndMoveType \
|
|
176
|
+
(*(Xnd_FromXndMoveType_RETURN (*)Xnd_FromXndMoveType_ARGS) _xnd_api[Xnd_FromXndMoveType_INDEX])
|
|
177
|
+
|
|
178
|
+
#define Xnd_FromXndView \
|
|
179
|
+
(*(Xnd_FromXndView_RETURN (*)Xnd_FromXndView_ARGS) _xnd_api[Xnd_FromXndView_INDEX])
|
|
180
|
+
|
|
181
|
+
#define Xnd_GetType \
|
|
182
|
+
(*(Xnd_GetType_RETURN (*)Xnd_GetType_ARGS) _xnd_api[Xnd_GetType_INDEX])
|
|
183
|
+
|
|
184
|
+
static int
|
|
185
|
+
import_xnd(void)
|
|
186
|
+
{
|
|
187
|
+
_xnd_api = (void **)PyCapsule_Import("xnd._xnd._API", 0);
|
|
188
|
+
if (_xnd_api == NULL) {
|
|
189
|
+
return -1;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return 0;
|
|
193
|
+
}
|
|
194
|
+
#endif
|
|
195
|
+
|
|
196
|
+
#ifdef __cplusplus
|
|
197
|
+
}
|
|
198
|
+
#endif
|
|
199
|
+
|
|
200
|
+
#endif /* PYXND_H */
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* BSD 3-Clause License
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2017-2018, plures
|
|
5
|
+
* All rights reserved.
|
|
6
|
+
*
|
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
|
8
|
+
* modification, are permitted provided that the following conditions are met:
|
|
9
|
+
*
|
|
10
|
+
* 1. Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
* this list of conditions and the following disclaimer.
|
|
12
|
+
*
|
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
14
|
+
* this list of conditions and the following disclaimer in the documentation
|
|
15
|
+
* and/or other materials provided with the distribution.
|
|
16
|
+
*
|
|
17
|
+
* 3. Neither the name of the copyright holder nor the names of its
|
|
18
|
+
* contributors may be used to endorse or promote products derived from
|
|
19
|
+
* this software without specific prior written permission.
|
|
20
|
+
*
|
|
21
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
22
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
23
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
24
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
25
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
26
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
27
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
28
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
29
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
#ifndef UTIL_H
|
|
35
|
+
#define UTIL_H
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
#include <Python.h>
|
|
39
|
+
#include <stdlib.h>
|
|
40
|
+
#include <stdint.h>
|
|
41
|
+
#include <inttypes.h>
|
|
42
|
+
#include "ndtypes.h"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
static inline Py_ssize_t
|
|
46
|
+
safe_downcast(int64_t size)
|
|
47
|
+
{
|
|
48
|
+
#if SIZE_MAX < INT64_MAX
|
|
49
|
+
if (size > INT32_MAX) {
|
|
50
|
+
PyErr_SetString(PyExc_ValueError,
|
|
51
|
+
"sizes should never exceed INT32_MAX on 32-bit platforms");
|
|
52
|
+
return -1;
|
|
53
|
+
}
|
|
54
|
+
#endif
|
|
55
|
+
return (Py_ssize_t)size;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static inline bool
|
|
59
|
+
check_invariants(const ndt_t *t)
|
|
60
|
+
{
|
|
61
|
+
#if SIZE_MAX < INT64_MAX
|
|
62
|
+
return safe_downcast(t->datasize) >= 0;
|
|
63
|
+
#else
|
|
64
|
+
(void)t;
|
|
65
|
+
return 1;
|
|
66
|
+
#endif
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static inline PyObject *
|
|
70
|
+
list_new(int64_t size)
|
|
71
|
+
{
|
|
72
|
+
#if SIZE_MAX < INT64_MAX
|
|
73
|
+
Py_ssize_t n = safe_downcast(size);
|
|
74
|
+
return n < 0 ? NULL : PyList_New(n);
|
|
75
|
+
#else
|
|
76
|
+
return PyList_New(size);
|
|
77
|
+
#endif
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static PyObject *
|
|
81
|
+
tuple_new(int64_t size)
|
|
82
|
+
{
|
|
83
|
+
#if SIZE_MAX < INT64_MAX
|
|
84
|
+
Py_ssize_t n = safe_downcast(size);
|
|
85
|
+
return n < 0 ? NULL : PyTuple_New(n);
|
|
86
|
+
#else
|
|
87
|
+
return PyTuple_New(size);
|
|
88
|
+
#endif
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static inline PyObject *
|
|
92
|
+
unicode_from_kind_and_data(int kind, const void *buffer, int64_t size)
|
|
93
|
+
{
|
|
94
|
+
#if SIZE_MAX < INT64_MAX
|
|
95
|
+
Py_ssize_t n = safe_downcast(size);
|
|
96
|
+
return n < 0 ? NULL : PyUnicode_FromKindAndData(kind, buffer, n);
|
|
97
|
+
#else
|
|
98
|
+
return PyUnicode_FromKindAndData(kind, buffer, size);
|
|
99
|
+
#endif
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static inline PyObject *
|
|
103
|
+
bytes_from_string_and_size(const char *str, int64_t size)
|
|
104
|
+
{
|
|
105
|
+
#if SIZE_MAX < INT64_MAX
|
|
106
|
+
Py_ssize_t n = safe_downcast(size);
|
|
107
|
+
return n < 0 ? NULL : PyBytes_FromStringAndSize(str, n);
|
|
108
|
+
#else
|
|
109
|
+
return PyBytes_FromStringAndSize(str, size);
|
|
110
|
+
#endif
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
static inline int
|
|
114
|
+
py_slice_get_indices_ex(PyObject *key, int64_t length,
|
|
115
|
+
int64_t *start, int64_t *stop, int64_t *step,
|
|
116
|
+
int64_t *slicelength)
|
|
117
|
+
{
|
|
118
|
+
Py_ssize_t n, _start, _stop, _step, _slicelength;
|
|
119
|
+
int ret;
|
|
120
|
+
|
|
121
|
+
n = safe_downcast(length);
|
|
122
|
+
if (n < 0) {
|
|
123
|
+
return -1;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
ret = PySlice_GetIndicesEx(key, n, &_start, &_stop, &_step, &_slicelength);
|
|
127
|
+
*start = _start;
|
|
128
|
+
*stop = _stop;
|
|
129
|
+
*step = _step;
|
|
130
|
+
*slicelength = _slicelength;
|
|
131
|
+
|
|
132
|
+
return ret;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* PSF copyright: Written by Jim Hugunin and Chris Chase. */
|
|
136
|
+
int
|
|
137
|
+
pyslice_unpack(PyObject *_r,
|
|
138
|
+
Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)
|
|
139
|
+
{
|
|
140
|
+
PySliceObject *r = (PySliceObject*)_r;
|
|
141
|
+
/* this is harder to get right than you might think */
|
|
142
|
+
|
|
143
|
+
assert(PY_SSIZE_T_MIN + 1 <= -PY_SSIZE_T_MAX);
|
|
144
|
+
|
|
145
|
+
if (r->step == Py_None) {
|
|
146
|
+
*step = 1;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
if (!_PyEval_SliceIndex(r->step, step)) return -1;
|
|
150
|
+
if (*step == 0) {
|
|
151
|
+
PyErr_SetString(PyExc_ValueError,
|
|
152
|
+
"slice step cannot be zero");
|
|
153
|
+
return -1;
|
|
154
|
+
}
|
|
155
|
+
/* Here *step might be -PY_SSIZE_T_MAX-1; in this case we replace it
|
|
156
|
+
* with -PY_SSIZE_T_MAX. This doesn't affect the semantics, and it
|
|
157
|
+
* guards against later undefined behaviour resulting from code that
|
|
158
|
+
* does "step = -step" as part of a slice reversal.
|
|
159
|
+
*/
|
|
160
|
+
if (*step < -PY_SSIZE_T_MAX)
|
|
161
|
+
*step = -PY_SSIZE_T_MAX;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (r->start == Py_None) {
|
|
165
|
+
*start = *step < 0 ? PY_SSIZE_T_MAX : 0;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
if (!_PyEval_SliceIndex(r->start, start)) return -1;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (r->stop == Py_None) {
|
|
172
|
+
*stop = *step < 0 ? PY_SSIZE_T_MIN : PY_SSIZE_T_MAX;
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
if (!_PyEval_SliceIndex(r->stop, stop)) return -1;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return 0;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
#endif /* UTIL_H */
|