Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
a743ead4
Commit
a743ead4
authored
Nov 03, 2016
by
Wenzel Jakob
Committed by
GitHub
Nov 03, 2016
Browse files
Merge pull request #474 from aldanor/feature/numpy-dtype-ex
Overriding field names when binding structured dtypes
parents
03f627eb
abd3429c
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
41 additions
and
8 deletions
+41
-8
include/pybind11/numpy.h
include/pybind11/numpy.h
+30
-6
tests/test_numpy_dtypes.cpp
tests/test_numpy_dtypes.cpp
+9
-1
tests/test_numpy_dtypes.py
tests/test_numpy_dtypes.py
+2
-1
No files found.
include/pybind11/numpy.h
View file @
a743ead4
...
...
@@ -20,6 +20,7 @@
#include <string>
#include <initializer_list>
#include <functional>
#include <utility>
#if defined(_MSC_VER)
# pragma warning(push)
...
...
@@ -748,14 +749,16 @@ std::string npy_format_descriptor<T, enable_if_t<is_pod_struct<T>::value>>::form
template
<
typename
T
>
PyObject
*
npy_format_descriptor
<
T
,
enable_if_t
<
is_pod_struct
<
T
>::
value
>>::
dtype_ptr
=
nullptr
;
// Extract name, offset and format descriptor for a struct field
#define PYBIND11_FIELD_DESCRIPTOR(Type, Field) \
::pybind11::detail::field_descriptor { \
#Field, offsetof(Type, Field), sizeof(decltype(static_cast<Type*>(0)->Field)), \
::pybind11::format_descriptor<decltype(static_cast<Type*>(0)->Field)>::format(), \
::pybind11::detail::npy_format_descriptor<decltype(static_cast<Type*>(0)->Field)>::dtype() \
#define PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, Name) \
::pybind11::detail::field_descriptor { \
Name, offsetof(T, Field), sizeof(decltype(std::declval<T>().Field)), \
::pybind11::format_descriptor<decltype(std::declval<T>().Field)>::format(), \
::pybind11::detail::npy_format_descriptor<decltype(std::declval<T>().Field)>::dtype() \
}
// Extract name, offset and format descriptor for a struct field
#define PYBIND11_FIELD_DESCRIPTOR(T, Field) PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, #Field)
// The main idea of this macro is borrowed from https://github.com/swansontec/map-macro
// (C) William Swanson, Paul Fultz
#define PYBIND11_EVAL0(...) __VA_ARGS__
...
...
@@ -792,6 +795,27 @@ PyObject* npy_format_descriptor<T, enable_if_t<is_pod_struct<T>::value>>::dtype_
::pybind11::detail::npy_format_descriptor<Type>::register_dtype \
({PYBIND11_MAP_LIST (PYBIND11_FIELD_DESCRIPTOR, Type, __VA_ARGS__)})
#ifdef _MSC_VER
#define PYBIND11_MAP2_LIST_NEXT1(test, next) \
PYBIND11_EVAL0 (PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0))
#else
#define PYBIND11_MAP2_LIST_NEXT1(test, next) \
PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0)
#endif
#define PYBIND11_MAP2_LIST_NEXT(test, next) \
PYBIND11_MAP2_LIST_NEXT1 (PYBIND11_MAP_GET_END test, next)
#define PYBIND11_MAP2_LIST0(f, t, x1, x2, peek, ...) \
f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT (peek, PYBIND11_MAP2_LIST1) (f, t, peek, __VA_ARGS__)
#define PYBIND11_MAP2_LIST1(f, t, x1, x2, peek, ...) \
f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT (peek, PYBIND11_MAP2_LIST0) (f, t, peek, __VA_ARGS__)
// PYBIND11_MAP2_LIST(f, t, a1, a2, ...) expands to f(t, a1, a2), f(t, a3, a4), ...
#define PYBIND11_MAP2_LIST(f, t, ...) \
PYBIND11_EVAL (PYBIND11_MAP2_LIST1 (f, t, __VA_ARGS__, (), 0))
#define PYBIND11_NUMPY_DTYPE_EX(Type, ...) \
::pybind11::detail::npy_format_descriptor<Type>::register_dtype \
({PYBIND11_MAP2_LIST (PYBIND11_FIELD_DESCRIPTOR_EX, Type, __VA_ARGS__)})
template
<
class
T
>
using
array_iterator
=
typename
std
::
add_pointer
<
T
>::
type
;
...
...
tests/test_numpy_dtypes.cpp
View file @
a743ead4
...
...
@@ -67,6 +67,11 @@ struct StringStruct {
std
::
array
<
char
,
3
>
b
;
};
PYBIND11_PACKED
(
struct
StructWithUglyNames
{
int8_t
__x__
;
uint64_t
__y__
;
});
enum
class
E1
:
int64_t
{
A
=
-
1
,
B
=
1
};
enum
E2
:
uint8_t
{
X
=
1
,
Y
=
2
};
...
...
@@ -197,7 +202,8 @@ py::list print_dtypes() {
py
::
dtype
::
of
<
PartialStruct
>
().
str
(),
py
::
dtype
::
of
<
PartialNestedStruct
>
().
str
(),
py
::
dtype
::
of
<
StringStruct
>
().
str
(),
py
::
dtype
::
of
<
EnumStruct
>
().
str
()
py
::
dtype
::
of
<
EnumStruct
>
().
str
(),
py
::
dtype
::
of
<
StructWithUglyNames
>
().
str
()
};
auto
l
=
py
::
list
();
for
(
const
auto
&
s
:
dtypes
)
{
...
...
@@ -312,6 +318,8 @@ test_initializer numpy_dtypes([](py::module &m) {
// ... or after
py
::
class_
<
PackedStruct
>
(
m
,
"PackedStruct"
);
PYBIND11_NUMPY_DTYPE_EX
(
StructWithUglyNames
,
__x__
,
"x"
,
__y__
,
"y"
);
m
.
def
(
"create_rec_simple"
,
&
create_recarray
<
SimpleStruct
>
);
m
.
def
(
"create_rec_packed"
,
&
create_recarray
<
PackedStruct
>
);
m
.
def
(
"create_rec_nested"
,
&
create_nested
);
...
...
tests/test_numpy_dtypes.py
View file @
a743ead4
...
...
@@ -42,7 +42,8 @@ def test_dtype():
"{'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}"
,
"[('a', 'S3'), ('b', 'S3')]"
,
"[('e1', '<i8'), ('e2', 'u1')]"
"[('e1', '<i8'), ('e2', 'u1')]"
,
"[('x', 'i1'), ('y', '<u8')]"
]
d1
=
np
.
dtype
({
'names'
:
[
'a'
,
'b'
],
'formats'
:
[
'int32'
,
'float64'
],
...
...
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