mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-11 08:03:55 +00:00
Make any_container implicitly constructible from arithmetic values
This further reduces the constructors required in buffer_info/numpy by removing the need for the constructors that take a single size_t and just forward it on via an initializer_list to the container-accepting constructor. Unfortunately, in `array` one of the constructors runs into an ambiguity problem with the deprecated `array(handle, bool)` constructor (because both the bool constructor and the any_container constructor involve an implicit conversion, so neither has precedence), so a forwarding constructor is kept there (until the deprecated constructor is eventually removed).
This commit is contained in:
parent
5f38386293
commit
201796d94f
@ -36,7 +36,7 @@ struct buffer_info {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t size)
|
buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t size)
|
||||||
: buffer_info(ptr, itemsize, format, 1, { size }, { itemsize }) { }
|
: buffer_info(ptr, itemsize, format, 1, size, itemsize) { }
|
||||||
|
|
||||||
explicit buffer_info(Py_buffer *view, bool ownview_in = true)
|
explicit buffer_info(Py_buffer *view, bool ownview_in = true)
|
||||||
: buffer_info(view->buf, (size_t) view->itemsize, view->format, (size_t) view->ndim,
|
: buffer_info(view->buf, (size_t) view->itemsize, view->format, (size_t) view->ndim,
|
||||||
|
@ -660,7 +660,8 @@ static constexpr auto const_ = std::true_type{};
|
|||||||
NAMESPACE_BEGIN(detail)
|
NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
// Adaptor for converting arbitrary container arguments into a vector; implicitly convertible from
|
// Adaptor for converting arbitrary container arguments into a vector; implicitly convertible from
|
||||||
// any standard container (or C-style array) supporting std::begin/std::end.
|
// any standard container (or C-style array) supporting std::begin/std::end, any singleton
|
||||||
|
// arithmetic type (if T is arithmetic), or explicitly constructible from an iterator pair.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class any_container {
|
class any_container {
|
||||||
std::vector<T> v;
|
std::vector<T> v;
|
||||||
@ -680,6 +681,11 @@ public:
|
|||||||
template <typename TIn, typename = enable_if_t<std::is_convertible<TIn, T>::value>>
|
template <typename TIn, typename = enable_if_t<std::is_convertible<TIn, T>::value>>
|
||||||
any_container(const std::initializer_list<TIn> &c) : any_container(c.begin(), c.end()) { }
|
any_container(const std::initializer_list<TIn> &c) : any_container(c.begin(), c.end()) { }
|
||||||
|
|
||||||
|
// Implicit conversion constructor from any arithmetic type (only participates if T is also
|
||||||
|
// arithmetic).
|
||||||
|
template <typename TIn, typename = enable_if_t<std::is_arithmetic<T>::value && std::is_arithmetic<TIn>::value>>
|
||||||
|
any_container(TIn singleton) : v(1, static_cast<T>(singleton)) { }
|
||||||
|
|
||||||
// Avoid copying if given an rvalue vector of the correct type.
|
// Avoid copying if given an rvalue vector of the correct type.
|
||||||
any_container(std::vector<T> &&v) : v(std::move(v)) { }
|
any_container(std::vector<T> &&v) : v(std::move(v)) { }
|
||||||
|
|
||||||
|
@ -463,7 +463,7 @@ public:
|
|||||||
const void *ptr = nullptr, handle base = handle()) {
|
const void *ptr = nullptr, handle base = handle()) {
|
||||||
|
|
||||||
if (strides->empty())
|
if (strides->empty())
|
||||||
strides = default_strides(*shape, dt.itemsize());
|
*strides = default_strides(*shape, dt.itemsize());
|
||||||
|
|
||||||
auto ndim = shape->size();
|
auto ndim = shape->size();
|
||||||
if (ndim != strides->size())
|
if (ndim != strides->size())
|
||||||
@ -499,9 +499,12 @@ public:
|
|||||||
array(const pybind11::dtype &dt, ShapeContainer shape, const void *ptr = nullptr, handle base = handle())
|
array(const pybind11::dtype &dt, ShapeContainer shape, const void *ptr = nullptr, handle base = handle())
|
||||||
: array(dt, std::move(shape), {}, ptr, base) { }
|
: array(dt, std::move(shape), {}, ptr, base) { }
|
||||||
|
|
||||||
array(const pybind11::dtype &dt, size_t count, const void *ptr = nullptr,
|
// This constructor is only needed to avoid ambiguity with the deprecated (handle, bool)
|
||||||
handle base = handle())
|
// constructor that comes from PYBIND11_OBJECT_CVT; once that is gone, the above constructor can
|
||||||
: array(dt, ShapeContainer{{ count }}, ptr, base) { }
|
// handle it (because ShapeContainer is implicitly constructible from arithmetic types)
|
||||||
|
template <typename T, typename = detail::enable_if_t<std::is_arithmetic<T>::value && !std::is_same<bool, T>::value>>
|
||||||
|
array(const pybind11::dtype &dt, T count)
|
||||||
|
: array(dt, count, nullptr) { }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
array(ShapeContainer shape, StridesContainer strides, const T *ptr, handle base = handle())
|
array(ShapeContainer shape, StridesContainer strides, const T *ptr, handle base = handle())
|
||||||
@ -511,10 +514,6 @@ public:
|
|||||||
array(ShapeContainer shape, const T *ptr, handle base = handle())
|
array(ShapeContainer shape, const T *ptr, handle base = handle())
|
||||||
: array(std::move(shape), {}, ptr, base) { }
|
: array(std::move(shape), {}, ptr, base) { }
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
array(size_t count, const T *ptr, handle base = handle())
|
|
||||||
: array({{ count }}, ptr, base) { }
|
|
||||||
|
|
||||||
explicit array(const buffer_info &info)
|
explicit array(const buffer_info &info)
|
||||||
: array(pybind11::dtype(info), info.shape, info.strides, info.ptr) { }
|
: array(pybind11::dtype(info), info.shape, info.strides, info.ptr) { }
|
||||||
|
|
||||||
@ -739,9 +738,6 @@ public:
|
|||||||
explicit array_t(ShapeContainer shape, const T *ptr = nullptr, handle base = handle())
|
explicit array_t(ShapeContainer shape, const T *ptr = nullptr, handle base = handle())
|
||||||
: array(std::move(shape), ptr, base) { }
|
: array(std::move(shape), ptr, base) { }
|
||||||
|
|
||||||
explicit array_t(size_t count, const T *ptr = nullptr, handle base = handle())
|
|
||||||
: array(count, ptr, base) { }
|
|
||||||
|
|
||||||
constexpr size_t itemsize() const {
|
constexpr size_t itemsize() const {
|
||||||
return sizeof(T);
|
return sizeof(T);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user