Skip to content

Commit 09f117d

Browse files
committed
Move buffer_info to its own header
Upcoming changes to buffer_info make it need some things declared in common.h; it also feels a bit misplaced in common.h (which is arguably too large already), so move it out. (Separating this and the subsequent changes into separate commits to make the changes easier to distinguish from the move.)
1 parent 4c72ec2 commit 09f117d

File tree

4 files changed

+98
-81
lines changed

4 files changed

+98
-81
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ set(PYTHON_MODULE_EXTENSION ${PYTHON_MODULE_EXTENSION} CACHE INTERNAL "")
3636

3737
set(PYBIND11_HEADERS
3838
include/pybind11/attr.h
39+
include/pybind11/buffer_info.h
3940
include/pybind11/cast.h
4041
include/pybind11/chrono.h
4142
include/pybind11/class_support.h

include/pybind11/buffer_info.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
pybind11/buffer_info.h: Python buffer object interface
3+
4+
Copyright (c) 2016 Wenzel Jakob <[email protected]>
5+
6+
All rights reserved. Use of this source code is governed by a
7+
BSD-style license that can be found in the LICENSE file.
8+
*/
9+
10+
#pragma once
11+
12+
#include "common.h"
13+
14+
NAMESPACE_BEGIN(pybind11)
15+
16+
/// Information record describing a Python buffer object
17+
struct buffer_info {
18+
void *ptr = nullptr; // Pointer to the underlying storage
19+
size_t itemsize = 0; // Size of individual items in bytes
20+
size_t size = 0; // Total number of entries
21+
std::string format; // For homogeneous buffers, this should be set to format_descriptor<T>::format()
22+
size_t ndim = 0; // Number of dimensions
23+
std::vector<size_t> shape; // Shape of the tensor (1 entry per dimension)
24+
std::vector<size_t> strides; // Number of entries between adjacent entries (for each per dimension)
25+
26+
buffer_info() { }
27+
28+
buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t ndim,
29+
const std::vector<size_t> &shape, const std::vector<size_t> &strides)
30+
: ptr(ptr), itemsize(itemsize), size(1), format(format),
31+
ndim(ndim), shape(shape), strides(strides) {
32+
for (size_t i = 0; i < ndim; ++i)
33+
size *= shape[i];
34+
}
35+
36+
buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t size)
37+
: buffer_info(ptr, itemsize, format, 1, std::vector<size_t> { size },
38+
std::vector<size_t> { itemsize }) { }
39+
40+
explicit buffer_info(Py_buffer *view, bool ownview = true)
41+
: ptr(view->buf), itemsize((size_t) view->itemsize), size(1), format(view->format),
42+
ndim((size_t) view->ndim), shape((size_t) view->ndim), strides((size_t) view->ndim), view(view), ownview(ownview) {
43+
for (size_t i = 0; i < (size_t) view->ndim; ++i) {
44+
shape[i] = (size_t) view->shape[i];
45+
strides[i] = (size_t) view->strides[i];
46+
size *= shape[i];
47+
}
48+
}
49+
50+
buffer_info(const buffer_info &) = delete;
51+
buffer_info& operator=(const buffer_info &) = delete;
52+
53+
buffer_info(buffer_info &&other) {
54+
(*this) = std::move(other);
55+
}
56+
57+
buffer_info& operator=(buffer_info &&rhs) {
58+
ptr = rhs.ptr;
59+
itemsize = rhs.itemsize;
60+
size = rhs.size;
61+
format = std::move(rhs.format);
62+
ndim = rhs.ndim;
63+
shape = std::move(rhs.shape);
64+
strides = std::move(rhs.strides);
65+
std::swap(view, rhs.view);
66+
std::swap(ownview, rhs.ownview);
67+
return *this;
68+
}
69+
70+
~buffer_info() {
71+
if (view && ownview) { PyBuffer_Release(view); delete view; }
72+
}
73+
74+
private:
75+
Py_buffer *view = nullptr;
76+
bool ownview = false;
77+
};
78+
79+
NAMESPACE_BEGIN(detail)
80+
81+
template <typename T, typename SFINAE = void> struct compare_buffer_info {
82+
static bool compare(const buffer_info& b) {
83+
return b.format == format_descriptor<T>::format() && b.itemsize == sizeof(T);
84+
}
85+
};
86+
87+
template <typename T> struct compare_buffer_info<T, detail::enable_if_t<std::is_integral<T>::value>> {
88+
static bool compare(const buffer_info& b) {
89+
return b.itemsize == sizeof(T) && (b.format == format_descriptor<T>::value ||
90+
((sizeof(T) == sizeof(long)) && b.format == (std::is_unsigned<T>::value ? "L" : "l")) ||
91+
((sizeof(T) == sizeof(size_t)) && b.format == (std::is_unsigned<T>::value ? "N" : "n")));
92+
}
93+
};
94+
95+
NAMESPACE_END(detail)
96+
NAMESPACE_END(pybind11)

include/pybind11/common.h

Lines changed: 0 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -286,69 +286,6 @@ enum class return_value_policy : uint8_t {
286286
reference_internal
287287
};
288288

289-
/// Information record describing a Python buffer object
290-
struct buffer_info {
291-
void *ptr = nullptr; // Pointer to the underlying storage
292-
size_t itemsize = 0; // Size of individual items in bytes
293-
size_t size = 0; // Total number of entries
294-
std::string format; // For homogeneous buffers, this should be set to format_descriptor<T>::format()
295-
size_t ndim = 0; // Number of dimensions
296-
std::vector<size_t> shape; // Shape of the tensor (1 entry per dimension)
297-
std::vector<size_t> strides; // Number of entries between adjacent entries (for each per dimension)
298-
299-
buffer_info() { }
300-
301-
buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t ndim,
302-
const std::vector<size_t> &shape, const std::vector<size_t> &strides)
303-
: ptr(ptr), itemsize(itemsize), size(1), format(format),
304-
ndim(ndim), shape(shape), strides(strides) {
305-
for (size_t i = 0; i < ndim; ++i)
306-
size *= shape[i];
307-
}
308-
309-
buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t size)
310-
: buffer_info(ptr, itemsize, format, 1, std::vector<size_t> { size },
311-
std::vector<size_t> { itemsize }) { }
312-
313-
explicit buffer_info(Py_buffer *view, bool ownview = true)
314-
: ptr(view->buf), itemsize((size_t) view->itemsize), size(1), format(view->format),
315-
ndim((size_t) view->ndim), shape((size_t) view->ndim), strides((size_t) view->ndim), view(view), ownview(ownview) {
316-
for (size_t i = 0; i < (size_t) view->ndim; ++i) {
317-
shape[i] = (size_t) view->shape[i];
318-
strides[i] = (size_t) view->strides[i];
319-
size *= shape[i];
320-
}
321-
}
322-
323-
buffer_info(const buffer_info &) = delete;
324-
buffer_info& operator=(const buffer_info &) = delete;
325-
326-
buffer_info(buffer_info &&other) {
327-
(*this) = std::move(other);
328-
}
329-
330-
buffer_info& operator=(buffer_info &&rhs) {
331-
ptr = rhs.ptr;
332-
itemsize = rhs.itemsize;
333-
size = rhs.size;
334-
format = std::move(rhs.format);
335-
ndim = rhs.ndim;
336-
shape = std::move(rhs.shape);
337-
strides = std::move(rhs.strides);
338-
std::swap(view, rhs.view);
339-
std::swap(ownview, rhs.ownview);
340-
return *this;
341-
}
342-
343-
~buffer_info() {
344-
if (view && ownview) { PyBuffer_Release(view); delete view; }
345-
}
346-
347-
private:
348-
Py_buffer *view = nullptr;
349-
bool ownview = false;
350-
};
351-
352289
NAMESPACE_BEGIN(detail)
353290

354291
inline static constexpr int log2(size_t n, int k = 0) { return (n <= 1) ? k : log2(n >> 1, k + 1); }
@@ -669,24 +606,6 @@ template <typename T> struct format_descriptor<T, detail::enable_if_t<detail::is
669606
template <typename T> constexpr const char format_descriptor<
670607
T, detail::enable_if_t<detail::is_fmt_numeric<T>::value>>::value[2];
671608

672-
NAMESPACE_BEGIN(detail)
673-
674-
template <typename T, typename SFINAE = void> struct compare_buffer_info {
675-
static bool compare(const buffer_info& b) {
676-
return b.format == format_descriptor<T>::format() && b.itemsize == sizeof(T);
677-
}
678-
};
679-
680-
template <typename T> struct compare_buffer_info<T, detail::enable_if_t<std::is_integral<T>::value>> {
681-
static bool compare(const buffer_info& b) {
682-
return b.itemsize == sizeof(T) && (b.format == format_descriptor<T>::value ||
683-
((sizeof(T) == sizeof(long)) && b.format == (std::is_unsigned<T>::value ? "L" : "l")) ||
684-
((sizeof(T) == sizeof(size_t)) && b.format == (std::is_unsigned<T>::value ? "N" : "n")));
685-
}
686-
};
687-
688-
NAMESPACE_END(detail)
689-
690609
/// RAII wrapper that temporarily clears any Python error state
691610
struct error_scope {
692611
PyObject *type, *value, *trace;

include/pybind11/pytypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#pragma once
1111

1212
#include "common.h"
13+
#include "buffer_info.h"
1314
#include <utility>
1415
#include <type_traits>
1516

0 commit comments

Comments
 (0)