17 m.attr(
"long_double_and_double_have_same_size") = (
sizeof(
long double) ==
sizeof(
double));
19 m.def(
"format_descriptor_format_buffer_info_equiv",
20 [](
const std::string &cpp_name,
const py::buffer &
buffer) {
22 static auto *format_table =
new std::map<std::string, std::string>;
23 static auto *equiv_table
24 =
new std::map<std::string, bool (py::buffer_info::*)()
const>;
25 if (format_table->empty()) {
26 #define PYBIND11_ASSIGN_HELPER(...) \
27 (*format_table)[#__VA_ARGS__] = py::format_descriptor<__VA_ARGS__>::format(); \
28 (*equiv_table)[#__VA_ARGS__] = &py::buffer_info::item_type_is_equivalent_to<__VA_ARGS__>;
45 #undef PYBIND11_ASSIGN_HELPER
47 return std::pair<std::string, bool>(
48 (*format_table)[cpp_name], (
buffer.
request().*((*equiv_table)[cpp_name]))());
55 print_created(
this, std::to_string(m_rows) +
"x" + std::to_string(m_cols) +
" matrix");
58 memset(m_data, 0,
sizeof(
float) * (
size_t) (
rows *
cols));
63 std::to_string(m_rows) +
"x" + std::to_string(m_cols) +
" matrix");
65 m_data =
new float[(
size_t) (m_rows * m_cols)];
66 memcpy(m_data,
s.m_data,
sizeof(
float) * (
size_t) (m_rows * m_cols));
69 Matrix(
Matrix &&
s) noexcept : m_rows(
s.m_rows), m_cols(
s.m_cols), m_data(
s.m_data) {
78 std::to_string(m_rows) +
"x" + std::to_string(m_cols) +
" matrix");
87 std::to_string(m_rows) +
"x" + std::to_string(m_cols) +
" matrix");
91 m_data =
new float[(
size_t) (m_rows * m_cols)];
92 memcpy(m_data,
s.m_data,
sizeof(
float) * (
size_t) (m_rows * m_cols));
98 std::to_string(m_rows) +
"x" + std::to_string(m_cols) +
" matrix");
112 return m_data[(
size_t) (
i * m_cols +
j)];
116 return m_data[(
size_t) (
i * m_cols +
j)];
119 float *
data() {
return m_data; }
129 py::class_<Matrix>(
m,
"Matrix", py::buffer_protocol())
130 .def(py::init<py::ssize_t, py::ssize_t>())
133 py::buffer_info
info =
b.request();
135 throw std::runtime_error(
"Incompatible buffer format!");
139 memcpy(
v->data(),
info.ptr,
sizeof(
float) * (
size_t) (
v->rows() *
v->cols()));
148 [](
const Matrix &
m, std::pair<py::ssize_t, py::ssize_t>
i) {
149 if (
i.first >=
m.rows() ||
i.second >=
m.cols()) {
150 throw py::index_error();
152 return m(
i.first,
i.second);
155 [](
Matrix &
m, std::pair<py::ssize_t, py::ssize_t>
i,
float v) {
156 if (
i.first >=
m.rows() ||
i.second >=
m.cols()) {
157 throw py::index_error();
159 m(
i.first,
i.second) =
v;
162 .def_buffer([](
Matrix &
m) -> py::buffer_info {
163 return py::buffer_info(
165 {m.rows(), m.cols()},
166 {sizeof(float) * size_t(m.cols()),
170 class BrokenMatrix :
public Matrix {
173 void throw_runtime_error() {
throw std::runtime_error(
"See PR #5324 for context."); }
175 py::class_<BrokenMatrix>(
m,
"BrokenMatrix", py::buffer_protocol())
176 .def(py::init<py::ssize_t, py::ssize_t>())
177 .def_buffer([](BrokenMatrix &
m) {
178 m.throw_runtime_error();
179 return py::buffer_info();
183 class SquareMatrix :
public Matrix {
188 py::class_<SquareMatrix, Matrix>(
m,
"SquareMatrix").def(py::init<py::ssize_t>());
196 py::buffer_info get_buffer_info() {
197 return py::buffer_info(
201 py::class_<Buffer>(
m,
"Buffer", py::buffer_protocol())
204 .def_buffer(&Buffer::get_buffer_info);
207 std::unique_ptr<int32_t>
value;
213 py::buffer_info get_buffer_info()
const {
214 return py::buffer_info(
220 py::class_<ConstBuffer>(
m,
"ConstBuffer", py::buffer_protocol())
222 .def_property(
"value", &ConstBuffer::get_value, &ConstBuffer::set_value)
223 .def_buffer(&ConstBuffer::get_buffer_info);
225 struct DerivedBuffer :
public Buffer {};
226 py::class_<DerivedBuffer>(
m,
"DerivedBuffer", py::buffer_protocol())
229 .def_buffer(&DerivedBuffer::get_buffer_info);
231 struct BufferReadOnly {
235 py::buffer_info get_buffer_info() {
return py::buffer_info(&
value, 1); }
237 py::class_<BufferReadOnly>(
m,
"BufferReadOnly", py::buffer_protocol())
238 .def(py::init<uint8_t>())
239 .def_buffer(&BufferReadOnly::get_buffer_info);
241 struct BufferReadOnlySelect {
243 bool readonly =
false;
245 py::buffer_info get_buffer_info() {
return py::buffer_info(&
value, 1, readonly); }
247 py::class_<BufferReadOnlySelect>(
m,
"BufferReadOnlySelect", py::buffer_protocol())
250 .def_readwrite(
"readonly", &BufferReadOnlySelect::readonly)
251 .def_buffer(&BufferReadOnlySelect::get_buffer_info);
254 py::class_<py::buffer_info>(
m,
"buffer_info")
256 .def_readonly(
"itemsize", &py::buffer_info::itemsize)
259 .def_readonly(
"ndim", &py::buffer_info::ndim)
260 .def_readonly(
"shape", &py::buffer_info::shape)
262 .def_readonly(
"readonly", &py::buffer_info::readonly)
263 .def(
"__repr__", [](py::handle
self) {
264 return py::str(
"itemsize={0.itemsize!r}, size={0.size!r}, format={0.format!r}, "
265 "ndim={0.ndim!r}, shape={0.shape!r}, strides={0.strides!r}, "
266 "readonly={0.readonly!r}")