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(ptr, itemsize, format, 1, { size }, { itemsize }) { }
|
||||
: buffer_info(ptr, itemsize, format, 1, size, itemsize) { }
|
||||
|
||||
explicit buffer_info(Py_buffer *view, bool ownview_in = true)
|
||||
: 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)
|
||||
|
||||
// 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>
|
||||
class any_container {
|
||||
std::vector<T> v;
|
||||
@ -680,6 +681,11 @@ public:
|
||||
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()) { }
|
||||
|
||||
// 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.
|
||||
any_container(std::vector<T> &&v) : v(std::move(v)) { }
|
||||
|
||||
|
@ -463,7 +463,7 @@ public:
|
||||
const void *ptr = nullptr, handle base = handle()) {
|
||||
|
||||
if (strides->empty())
|
||||
strides = default_strides(*shape, dt.itemsize());
|
||||
*strides = default_strides(*shape, dt.itemsize());
|
||||
|
||||
auto ndim = shape->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(dt, std::move(shape), {}, ptr, base) { }
|
||||
|
||||
array(const pybind11::dtype &dt, size_t count, const void *ptr = nullptr,
|
||||
handle base = handle())
|
||||
: array(dt, ShapeContainer{{ count }}, ptr, base) { }
|
||||
// This constructor is only needed to avoid ambiguity with the deprecated (handle, bool)
|
||||
// constructor that comes from PYBIND11_OBJECT_CVT; once that is gone, the above constructor can
|
||||
// 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>
|
||||
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(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)
|
||||
: 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())
|
||||
: 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 {
|
||||
return sizeof(T);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user