Only mark unaligned types in buffers (#505)

Previously all types are marked unaligned in buffer format strings,
now we test for alignment before adding the '=' marker.
This commit is contained in:
patstew 2016-11-22 11:17:07 +00:00 committed by Wenzel Jakob
parent b14f065fa9
commit 47681c183d
2 changed files with 13 additions and 9 deletions

View File

@ -756,6 +756,7 @@ struct field_descriptor {
const char *name;
size_t offset;
size_t size;
size_t alignment;
std::string format;
dtype descr;
};
@ -796,8 +797,10 @@ inline PYBIND11_NOINLINE void register_structured_dtype(
for (auto& field : ordered_fields) {
if (field.offset > offset)
oss << (field.offset - offset) << 'x';
// note that '=' is required to cover the case of unaligned fields
oss << '=' << field.format << ':' << field.name << ':';
// mark unaligned fields with '='
if (field.offset % field.alignment)
oss << '=';
oss << field.format << ':' << field.name << ':';
offset = field.offset + field.size;
}
if (itemsize > offset)
@ -857,6 +860,7 @@ private:
#define PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, Name) \
::pybind11::detail::field_descriptor { \
Name, offsetof(T, Field), sizeof(decltype(std::declval<T>().Field)), \
alignof(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() \
}

View File

@ -30,13 +30,13 @@ def test_format_descriptors():
assert re.match('^NumPy type info missing for .*UnboundStruct.*$', str(excinfo.value))
assert print_format_descriptors() == [
"T{=?:x:3x=I:y:=f:z:}",
"T{=?:x:=I:y:=f:z:}",
"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{8x=T{=?:x:3x=I:y:=f:z:12x}:a:8x}",
"T{=3s:a:=3s:b:}",
'T{=q:e1:=B:e2:}'
"T{?:x:3xI:y:f:z:}",
"T{?:x:=I:y:=f:z:}",
"T{T{?:x:3xI:y:f:z:}:a:T{?:x:=I:y:=f:z:}:b:}",
"T{?:x:3xI:y:f:z:12x}",
"T{8xT{?:x:3xI:y:f:z:12x}:a:8x}",
"T{3s:a:3s:b:}",
'T{q:e1:B:e2:}'
]