Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
f9c0defe
Commit
f9c0defe
authored
Jul 20, 2016
by
Ivan Smirnov
Browse files
Add numpy wrappers for char[] and std::array<char>
parent
103d5ead
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
84 additions
and
5 deletions
+84
-5
example/example20.cpp
example/example20.cpp
+37
-0
example/example20.py
example/example20.py
+10
-1
example/example20.ref
example/example20.ref
+8
-1
include/pybind11/numpy.h
include/pybind11/numpy.h
+29
-3
No files found.
example/example20.cpp
View file @
f9c0defe
...
@@ -65,6 +65,19 @@ struct PartialNestedStruct {
...
@@ -65,6 +65,19 @@ struct PartialNestedStruct {
struct
UnboundStruct
{
};
struct
UnboundStruct
{
};
struct
StringStruct
{
char
a
[
3
];
std
::
array
<
char
,
3
>
b
;
};
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
StringStruct
&
v
)
{
os
<<
"a='"
;
for
(
size_t
i
=
0
;
i
<
3
&&
v
.
a
[
i
];
i
++
)
os
<<
v
.
a
[
i
];
os
<<
"',b='"
;
for
(
size_t
i
=
0
;
i
<
3
&&
v
.
b
[
i
];
i
++
)
os
<<
v
.
b
[
i
];
return
os
<<
"'"
;
}
template
<
typename
T
>
template
<
typename
T
>
py
::
array
mkarray_via_buffer
(
size_t
n
)
{
py
::
array
mkarray_via_buffer
(
size_t
n
)
{
return
py
::
array
(
py
::
buffer_info
(
nullptr
,
sizeof
(
T
),
return
py
::
array
(
py
::
buffer_info
(
nullptr
,
sizeof
(
T
),
...
@@ -108,6 +121,25 @@ py::array_t<PartialNestedStruct, 0> create_partial_nested(size_t n) {
...
@@ -108,6 +121,25 @@ py::array_t<PartialNestedStruct, 0> create_partial_nested(size_t n) {
return
arr
;
return
arr
;
}
}
py
::
array_t
<
StringStruct
,
0
>
create_string_array
(
bool
non_empty
)
{
auto
arr
=
mkarray_via_buffer
<
StringStruct
>
(
non_empty
?
4
:
0
);
if
(
non_empty
)
{
auto
req
=
arr
.
request
();
auto
ptr
=
static_cast
<
StringStruct
*>
(
req
.
ptr
);
for
(
size_t
i
=
0
;
i
<
req
.
size
*
req
.
itemsize
;
i
++
)
static_cast
<
char
*>
(
req
.
ptr
)[
i
]
=
0
;
ptr
[
1
].
a
[
0
]
=
'a'
;
ptr
[
1
].
b
[
0
]
=
'a'
;
ptr
[
2
].
a
[
0
]
=
'a'
;
ptr
[
2
].
b
[
0
]
=
'a'
;
ptr
[
3
].
a
[
0
]
=
'a'
;
ptr
[
3
].
b
[
0
]
=
'a'
;
ptr
[
2
].
a
[
1
]
=
'b'
;
ptr
[
2
].
b
[
1
]
=
'b'
;
ptr
[
3
].
a
[
1
]
=
'b'
;
ptr
[
3
].
b
[
1
]
=
'b'
;
ptr
[
3
].
a
[
2
]
=
'c'
;
ptr
[
3
].
b
[
2
]
=
'c'
;
}
return
arr
;
}
template
<
typename
S
>
template
<
typename
S
>
void
print_recarray
(
py
::
array_t
<
S
,
0
>
arr
)
{
void
print_recarray
(
py
::
array_t
<
S
,
0
>
arr
)
{
auto
req
=
arr
.
request
();
auto
req
=
arr
.
request
();
...
@@ -122,6 +154,7 @@ void print_format_descriptors() {
...
@@ -122,6 +154,7 @@ void print_format_descriptors() {
std
::
cout
<<
py
::
format_descriptor
<
NestedStruct
>::
format
()
<<
std
::
endl
;
std
::
cout
<<
py
::
format_descriptor
<
NestedStruct
>::
format
()
<<
std
::
endl
;
std
::
cout
<<
py
::
format_descriptor
<
PartialStruct
>::
format
()
<<
std
::
endl
;
std
::
cout
<<
py
::
format_descriptor
<
PartialStruct
>::
format
()
<<
std
::
endl
;
std
::
cout
<<
py
::
format_descriptor
<
PartialNestedStruct
>::
format
()
<<
std
::
endl
;
std
::
cout
<<
py
::
format_descriptor
<
PartialNestedStruct
>::
format
()
<<
std
::
endl
;
std
::
cout
<<
py
::
format_descriptor
<
StringStruct
>::
format
()
<<
std
::
endl
;
}
}
void
print_dtypes
()
{
void
print_dtypes
()
{
...
@@ -133,6 +166,7 @@ void print_dtypes() {
...
@@ -133,6 +166,7 @@ void print_dtypes() {
std
::
cout
<<
to_str
(
py
::
dtype_of
<
NestedStruct
>
())
<<
std
::
endl
;
std
::
cout
<<
to_str
(
py
::
dtype_of
<
NestedStruct
>
())
<<
std
::
endl
;
std
::
cout
<<
to_str
(
py
::
dtype_of
<
PartialStruct
>
())
<<
std
::
endl
;
std
::
cout
<<
to_str
(
py
::
dtype_of
<
PartialStruct
>
())
<<
std
::
endl
;
std
::
cout
<<
to_str
(
py
::
dtype_of
<
PartialNestedStruct
>
())
<<
std
::
endl
;
std
::
cout
<<
to_str
(
py
::
dtype_of
<
PartialNestedStruct
>
())
<<
std
::
endl
;
std
::
cout
<<
to_str
(
py
::
dtype_of
<
StringStruct
>
())
<<
std
::
endl
;
}
}
void
init_ex20
(
py
::
module
&
m
)
{
void
init_ex20
(
py
::
module
&
m
)
{
...
@@ -141,6 +175,7 @@ void init_ex20(py::module &m) {
...
@@ -141,6 +175,7 @@ void init_ex20(py::module &m) {
PYBIND11_NUMPY_DTYPE
(
NestedStruct
,
a
,
b
);
PYBIND11_NUMPY_DTYPE
(
NestedStruct
,
a
,
b
);
PYBIND11_NUMPY_DTYPE
(
PartialStruct
,
x
,
y
,
z
);
PYBIND11_NUMPY_DTYPE
(
PartialStruct
,
x
,
y
,
z
);
PYBIND11_NUMPY_DTYPE
(
PartialNestedStruct
,
a
);
PYBIND11_NUMPY_DTYPE
(
PartialNestedStruct
,
a
);
PYBIND11_NUMPY_DTYPE
(
StringStruct
,
a
,
b
);
m
.
def
(
"create_rec_simple"
,
&
create_recarray
<
SimpleStruct
>
);
m
.
def
(
"create_rec_simple"
,
&
create_recarray
<
SimpleStruct
>
);
m
.
def
(
"create_rec_packed"
,
&
create_recarray
<
PackedStruct
>
);
m
.
def
(
"create_rec_packed"
,
&
create_recarray
<
PackedStruct
>
);
...
@@ -153,6 +188,8 @@ void init_ex20(py::module &m) {
...
@@ -153,6 +188,8 @@ void init_ex20(py::module &m) {
m
.
def
(
"print_rec_nested"
,
&
print_recarray
<
NestedStruct
>
);
m
.
def
(
"print_rec_nested"
,
&
print_recarray
<
NestedStruct
>
);
m
.
def
(
"print_dtypes"
,
&
print_dtypes
);
m
.
def
(
"print_dtypes"
,
&
print_dtypes
);
m
.
def
(
"get_format_unbound"
,
&
get_format_unbound
);
m
.
def
(
"get_format_unbound"
,
&
get_format_unbound
);
m
.
def
(
"create_string_array"
,
&
create_string_array
);
m
.
def
(
"print_string_array"
,
&
print_recarray
<
StringStruct
>
);
}
}
#undef PYBIND11_PACKED
#undef PYBIND11_PACKED
example/example20.py
View file @
f9c0defe
...
@@ -6,7 +6,7 @@ import numpy as np
...
@@ -6,7 +6,7 @@ import numpy as np
from
example
import
(
from
example
import
(
create_rec_simple
,
create_rec_packed
,
create_rec_nested
,
print_format_descriptors
,
create_rec_simple
,
create_rec_packed
,
create_rec_nested
,
print_format_descriptors
,
print_rec_simple
,
print_rec_packed
,
print_rec_nested
,
print_dtypes
,
get_format_unbound
,
print_rec_simple
,
print_rec_packed
,
print_rec_nested
,
print_dtypes
,
get_format_unbound
,
create_rec_partial
,
create_rec_partial_nested
create_rec_partial
,
create_rec_partial_nested
,
create_string_array
,
print_string_array
)
)
...
@@ -72,3 +72,12 @@ check_eq(arr, [((False, 0, 0.0), (True, 1, 1.5)),
...
@@ -72,3 +72,12 @@ check_eq(arr, [((False, 0, 0.0), (True, 1, 1.5)),
print_rec_nested
(
arr
)
print_rec_nested
(
arr
)
assert
create_rec_nested
.
__doc__
.
strip
().
endswith
(
'numpy.ndarray[dtype=NestedStruct]'
)
assert
create_rec_nested
.
__doc__
.
strip
().
endswith
(
'numpy.ndarray[dtype=NestedStruct]'
)
arr
=
create_string_array
(
True
)
print
(
arr
.
dtype
)
print_string_array
(
arr
)
dtype
=
arr
.
dtype
assert
arr
[
'a'
].
tolist
()
==
[
b
''
,
b
'a'
,
b
'ab'
,
b
'abc'
]
assert
arr
[
'b'
].
tolist
()
==
[
b
''
,
b
'a'
,
b
'ab'
,
b
'abc'
]
arr
=
create_string_array
(
False
)
assert
dtype
==
arr
.
dtype
example/example20.ref
View file @
f9c0defe
...
@@ -3,11 +3,13 @@ T{=?:x:=I:y:=f:z:}
...
@@ -3,11 +3,13 @@ T{=?:x:=I:y:=f:z:}
T{=T{=?:x:3x=I:y:=f:z:}:a:=T{=?:x:=I:y:=f:z:}:b:}
T{=T{=?:x:3x=I:y:=f:z:}:a:=T{=?:x:=I:y:=f:z:}:b:}
T{=?:x:3x=I:y:=f:z:12x}
T{=?:x:3x=I:y:=f:z:12x}
T{8x=T{=?:x:3x=I:y:=f:z:12x}:a:8x}
T{8x=T{=?:x:3x=I:y:=f:z:12x}:a:8x}
T{=3s:a:=3s:b:}
{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':12}
{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':12}
[('x', '?'), ('y', '<u4'), ('z', '<f4')]
[('x', '?'), ('y', '<u4'), ('z', '<f4')]
[('a', {'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':12}), ('b', [('x', '?'), ('y', '<u4'), ('z', '<f4')])]
[('a', {'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':12}), ('b', [('x', '?'), ('y', '<u4'), ('z', '<f4')])]
{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}
{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}
{'names':['a'], 'formats':[{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}], 'offsets':[8], 'itemsize':40}
{'names':['a'], 'formats':[{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}], 'offsets':[8], 'itemsize':40}
[('a', 'S3'), ('b', 'S3')]
s:0,0,0
s:0,0,0
s:1,1,1.5
s:1,1,1.5
s:0,2,3
s:0,2,3
...
@@ -18,4 +20,9 @@ p:0,2,3
...
@@ -18,4 +20,9 @@ p:0,2,3
{'names':['a'], 'formats':[{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}], 'offsets':[8], 'itemsize':40}
{'names':['a'], 'formats':[{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}], 'offsets':[8], 'itemsize':40}
n:a=s:0,0,0;b=p:1,1,1.5
n:a=s:0,0,0;b=p:1,1,1.5
n:a=s:1,1,1.5;b=p:0,2,3
n:a=s:1,1,1.5;b=p:0,2,3
n:a=s:0,2,3;b=p:1,3,4.5
n:a=s:0,2,3;b=p:1,3,4.5
\ No newline at end of file
[('a', 'S3'), ('b', 'S3')]
a='',b=''
a='a',b='a'
a='ab',b='ab'
a='abc',b='abc'
include/pybind11/numpy.h
View file @
f9c0defe
...
@@ -13,6 +13,7 @@
...
@@ -13,6 +13,7 @@
#include "complex.h"
#include "complex.h"
#include <numeric>
#include <numeric>
#include <algorithm>
#include <algorithm>
#include <array>
#include <cstdlib>
#include <cstdlib>
#include <cstring>
#include <cstring>
#include <sstream>
#include <sstream>
...
@@ -27,10 +28,14 @@ NAMESPACE_BEGIN(pybind11)
...
@@ -27,10 +28,14 @@ NAMESPACE_BEGIN(pybind11)
namespace
detail
{
namespace
detail
{
template
<
typename
type
,
typename
SFINAE
=
void
>
struct
npy_format_descriptor
{
};
template
<
typename
type
,
typename
SFINAE
=
void
>
struct
npy_format_descriptor
{
};
template
<
typename
T
>
struct
is_std_array
:
std
::
false_type
{
};
template
<
typename
T
,
size_t
N
>
struct
is_std_array
<
std
::
array
<
T
,
N
>>
:
std
::
true_type
{
};
template
<
typename
T
>
template
<
typename
T
>
struct
is_pod_struct
{
struct
is_pod_struct
{
enum
{
value
=
std
::
is_pod
<
T
>::
value
&&
// offsetof only works correctly for POD types
enum
{
value
=
std
::
is_pod
<
T
>::
value
&&
// offsetof only works correctly for POD types
!
std
::
is_array
<
T
>::
value
&&
!
is_std_array
<
T
>::
value
&&
!
std
::
is_integral
<
T
>::
value
&&
!
std
::
is_integral
<
T
>::
value
&&
!
std
::
is_same
<
T
,
float
>::
value
&&
!
std
::
is_same
<
T
,
float
>::
value
&&
!
std
::
is_same
<
T
,
double
>::
value
&&
!
std
::
is_same
<
T
,
double
>::
value
&&
...
@@ -221,9 +226,14 @@ public:
...
@@ -221,9 +226,14 @@ public:
template
<
typename
T
>
template
<
typename
T
>
struct
format_descriptor
<
T
,
typename
std
::
enable_if
<
detail
::
is_pod_struct
<
T
>::
value
>::
type
>
{
struct
format_descriptor
<
T
,
typename
std
::
enable_if
<
detail
::
is_pod_struct
<
T
>::
value
>::
type
>
{
static
const
char
*
format
()
{
static
const
char
*
format
()
{
return
detail
::
npy_format_descriptor
<
T
>::
format
();
}
return
detail
::
npy_format_descriptor
<
T
>::
format
();
};
}
template
<
size_t
N
>
struct
format_descriptor
<
char
[
N
]
>
{
static
const
char
*
format
()
{
PYBIND11_DESCR
s
=
detail
::
_
<
N
>
()
+
detail
::
_
(
"s"
);
return
s
.
text
();
}
};
template
<
size_t
N
>
struct
format_descriptor
<
std
::
array
<
char
,
N
>>
{
static
const
char
*
format
()
{
PYBIND11_DESCR
s
=
detail
::
_
<
N
>
()
+
detail
::
_
(
"s"
);
return
s
.
text
();
}
};
};
template
<
typename
T
>
template
<
typename
T
>
...
@@ -268,6 +278,22 @@ DECL_FMT(std::complex<float>, NPY_CFLOAT_, "complex64");
...
@@ -268,6 +278,22 @@ DECL_FMT(std::complex<float>, NPY_CFLOAT_, "complex64");
DECL_FMT
(
std
::
complex
<
double
>
,
NPY_CDOUBLE_
,
"complex128"
);
DECL_FMT
(
std
::
complex
<
double
>
,
NPY_CDOUBLE_
,
"complex128"
);
#undef DECL_FMT
#undef DECL_FMT
#define DECL_CHAR_FMT \
static PYBIND11_DESCR name() { return _("S") + _<N>(); } \
static object dtype() { \
auto& api = array::lookup_api(); \
PyObject *descr = nullptr; \
PYBIND11_DESCR fmt = _("S") + _<N>(); \
pybind11::str py_fmt(fmt.text()); \
if (!api.PyArray_DescrConverter_(py_fmt.release().ptr(), &descr) || !descr) \
pybind11_fail("NumPy: failed to create string dtype"); \
return object(descr, false); \
} \
static const char *format() { PYBIND11_DESCR s = _<N>() + _("s"); return s.text(); }
template
<
size_t
N
>
struct
npy_format_descriptor
<
char
[
N
]
>
{
DECL_CHAR_FMT
};
template
<
size_t
N
>
struct
npy_format_descriptor
<
std
::
array
<
char
,
N
>>
{
DECL_CHAR_FMT
};
#undef DECL_CHAR_FMT
struct
field_descriptor
{
struct
field_descriptor
{
const
char
*
name
;
const
char
*
name
;
size_t
offset
;
size_t
offset
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment