Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pybind11
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
pybind11
Commits
cc8ff165
Commit
cc8ff165
authored
Oct 31, 2016
by
Ivan Smirnov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move register_dtype() outside of the template
(avoid code bloat if possible)
parent
f95fda0e
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
37 additions
and
24 deletions
+37
-24
include/pybind11/numpy.h
+37
-24
No files found.
include/pybind11/numpy.h
View file @
cc8ff165
...
...
@@ -81,14 +81,18 @@ struct numpy_type_info {
struct
numpy_internals
{
std
::
unordered_map
<
std
::
type_index
,
numpy_type_info
>
registered_dtypes
;
template
<
typename
T
>
numpy_type_info
*
get_type_info
(
bool
throw_if_missing
=
true
)
{
auto
it
=
registered_dtypes
.
find
(
std
::
type_index
(
t
ypeid
(
T
)
));
numpy_type_info
*
get_type_info
(
const
std
::
type_info
&
tinfo
,
bool
throw_if_missing
=
true
)
{
auto
it
=
registered_dtypes
.
find
(
std
::
type_index
(
t
info
));
if
(
it
!=
registered_dtypes
.
end
())
return
&
(
it
->
second
);
if
(
throw_if_missing
)
pybind11_fail
(
std
::
string
(
"NumPy type info missing for "
)
+
t
ypeid
(
T
)
.
name
());
pybind11_fail
(
std
::
string
(
"NumPy type info missing for "
)
+
t
info
.
name
());
return
nullptr
;
}
template
<
typename
T
>
numpy_type_info
*
get_type_info
(
bool
throw_if_missing
=
true
)
{
return
get_type_info
(
typeid
(
typename
std
::
remove_cv
<
T
>::
type
),
throw_if_missing
);
}
};
inline
PYBIND11_NOINLINE
void
load_numpy_internals
(
numpy_internals
*
&
ptr
)
{
...
...
@@ -686,34 +690,25 @@ struct field_descriptor {
dtype
descr
;
};
template
<
typename
T
>
struct
npy_format_descriptor
<
T
,
enable_if_t
<
is_pod_struct
<
T
>::
value
>>
{
static
PYBIND11_DESCR
name
()
{
return
_
(
"struct"
);
}
static
pybind11
::
dtype
dtype
()
{
return
object
(
dtype_ptr
(),
true
);
}
static
std
::
string
format
()
{
static
auto
format_str
=
get_numpy_internals
().
get_type_info
<
T
>
(
true
)
->
format_str
;
return
format_str
;
}
static
void
register_dtype
(
std
::
initializer_list
<
field_descriptor
>
fields
)
{
inline
PYBIND11_NOINLINE
void
register_structured_dtype
(
const
std
::
initializer_list
<
field_descriptor
>&
fields
,
const
std
::
type_info
&
tinfo
,
size_t
itemsize
,
bool
(
*
direct_converter
)(
PyObject
*
,
void
*&
))
{
auto
&
numpy_internals
=
get_numpy_internals
();
if
(
numpy_internals
.
get_type_info
<
T
>
(
false
))
if
(
numpy_internals
.
get_type_info
(
tinfo
,
false
))
pybind11_fail
(
"NumPy: dtype is already registered"
);
list
names
,
formats
,
offsets
;
for
(
auto
field
:
fields
)
{
if
(
!
field
.
descr
)
pybind11_fail
(
std
::
string
(
"NumPy: unsupported field dtype: `"
)
+
field
.
name
+
"` @ "
+
typeid
(
T
)
.
name
());
field
.
name
+
"` @ "
+
tinfo
.
name
());
names
.
append
(
PYBIND11_STR_TYPE
(
field
.
name
));
formats
.
append
(
field
.
descr
);
offsets
.
append
(
pybind11
::
int_
(
field
.
offset
));
}
auto
dtype_ptr
=
pybind11
::
dtype
(
names
,
formats
,
offsets
,
sizeof
(
T
)
).
release
().
ptr
();
auto
dtype_ptr
=
pybind11
::
dtype
(
names
,
formats
,
offsets
,
itemsize
).
release
().
ptr
();
// There is an existing bug in NumPy (as of v1.11): trailing bytes are
// not encoded explicitly into the format string. This will supposedly
...
...
@@ -735,20 +730,38 @@ struct npy_format_descriptor<T, enable_if_t<is_pod_struct<T>::value>> {
oss
<<
'='
<<
field
.
format
<<
':'
<<
field
.
name
<<
':'
;
offset
=
field
.
offset
+
field
.
size
;
}
if
(
sizeof
(
T
)
>
offset
)
oss
<<
(
sizeof
(
T
)
-
offset
)
<<
'x'
;
if
(
itemsize
>
offset
)
oss
<<
(
itemsize
-
offset
)
<<
'x'
;
oss
<<
'}'
;
auto
format_str
=
oss
.
str
();
// Sanity check: verify that NumPy properly parses our buffer format string
auto
&
api
=
npy_api
::
get
();
auto
arr
=
array
(
buffer_info
(
nullptr
,
sizeof
(
T
)
,
format_str
,
1
));
auto
arr
=
array
(
buffer_info
(
nullptr
,
itemsize
,
format_str
,
1
));
if
(
!
api
.
PyArray_EquivTypes_
(
dtype_ptr
,
arr
.
dtype
().
ptr
()))
pybind11_fail
(
"NumPy: invalid buffer descriptor!"
);
auto
tindex
=
std
::
type_index
(
typeid
(
T
)
);
auto
tindex
=
std
::
type_index
(
tinfo
);
numpy_internals
.
registered_dtypes
[
tindex
]
=
{
dtype_ptr
,
format_str
};
get_internals
().
direct_conversions
[
tindex
].
push_back
(
direct_converter
);
}
template
<
typename
T
>
struct
npy_format_descriptor
<
T
,
enable_if_t
<
is_pod_struct
<
T
>::
value
>>
{
static
PYBIND11_DESCR
name
()
{
return
_
(
"struct"
);
}
static
pybind11
::
dtype
dtype
()
{
return
object
(
dtype_ptr
(),
true
);
}
static
std
::
string
format
()
{
static
auto
format_str
=
get_numpy_internals
().
get_type_info
<
T
>
(
true
)
->
format_str
;
return
format_str
;
}
static
void
register_dtype
(
const
std
::
initializer_list
<
field_descriptor
>&
fields
)
{
register_structured_dtype
(
fields
,
typeid
(
typename
std
::
remove_cv
<
T
>::
type
),
sizeof
(
T
),
&
direct_converter
);
}
private
:
...
...
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