From 007a7214dec2ef86f910dfd7ff0b92f5d0221b1a Mon Sep 17 00:00:00 2001 From: Sylvain Corlay Date: Tue, 15 Nov 2016 21:17:10 +0100 Subject: [PATCH] Simplify byte_offset --- include/xtensor-python/pyarray.hpp | 16 ++----- include/xtensor-python/pybind11_backport.hpp | 45 +++----------------- 2 files changed, 10 insertions(+), 51 deletions(-) diff --git a/include/xtensor-python/pyarray.hpp b/include/xtensor-python/pyarray.hpp index 40e15b6..0ccbdc5 100644 --- a/include/xtensor-python/pyarray.hpp +++ b/include/xtensor-python/pyarray.hpp @@ -330,24 +330,14 @@ namespace xt template inline auto pyarray::operator()(Args... args) -> reference { - if (sizeof...(args) != dimension()) - { - pybind_array::fail_dim_check(sizeof...(args), "index dimension mismatch"); - } - // not using pybind_array::offset_at() / index_at() here so as to avoid another dimension check. - return *(static_cast(pybind_array::mutable_data()) + pybind_array::get_byte_offset(args...) / itemsize()); + return *(static_cast(pybind_array::mutable_data()) + pybind_array::byte_offset(args...) / itemsize()); } template template inline auto pyarray::operator()(Args... args) const -> const_reference { - if (sizeof...(args) != dimension()) - { - pybind_array::fail_dim_check(sizeof...(args), "index dimension mismatch"); - } - // not using pybind_array::offset_at() / index_at() here so as to avoid another dimension check. - return *(static_cast(pybind_array::data()) + pybind_array::get_byte_offset(args...) / itemsize()); + return *(static_cast(pybind_array::data()) + pybind_array::byte_offset(args...) / itemsize()); } template @@ -522,7 +512,7 @@ namespace xt template inline auto pyarray::index_at(Args... args) const -> size_type { - return pybind_array::offset_at(args...) / itemsize(); + return pybind_array::byte_offset(args...) / itemsize(); } template diff --git a/include/xtensor-python/pybind11_backport.hpp b/include/xtensor-python/pybind11_backport.hpp index d2ad8e6..19d4a2d 100644 --- a/include/xtensor-python/pybind11_backport.hpp +++ b/include/xtensor-python/pybind11_backport.hpp @@ -91,7 +91,7 @@ namespace pybind11 size_type size() const { - return std::accumulate(shape(), shape() + ndim(), size_type{1}, std::multiplies()); + return std::accumulate(shape(), shape() + ndim(), size_type(1), std::multiplies()); } size_type itemsize() const @@ -114,61 +114,30 @@ namespace pybind11 return reinterpret_cast(PyArray_GET_(m_ptr, strides)); } - template void* data() { return static_cast(PyArray_GET_(m_ptr, data)); } - template void* mutable_data() { - // check_writeable(); return static_cast(PyArray_GET_(m_ptr, data)); } - template - size_type offset_at(Ix... index) const - { - if (sizeof...(index) > ndim()) - { - fail_dim_check(sizeof...(index), "too many indices for an array"); - } - return get_byte_offset(index...); - } + protected: - size_type offset_at() const + template + inline size_type byte_offset() const { return 0; } - protected: - - void fail_dim_check(size_type dim, const std::string& msg) const + template + inline size_type byte_offset(size_type i, Args... args) const { - throw index_error(msg + ": " + std::to_string(dim) + - " (ndim = " + std::to_string(ndim()) + ")"); + return i * strides()[dim] + byte_offset(args...); } - template - size_type get_byte_offset(Ix... index) const - { - const size_type idx[] = { static_cast(index)... }; - if (!std::equal(idx + 0, idx + sizeof...(index), shape(), std::less{})) - { - auto mismatch = std::mismatch(idx + 0, idx + sizeof...(index), shape(), std::less{}); - throw index_error(std::string("index ") + std::to_string(*mismatch.first) + - " is out of bounds for axis " + std::to_string(mismatch.first - idx) + - " with size " + std::to_string(*mismatch.second)); - } - return std::inner_product(idx + 0, idx + sizeof...(index), strides(), size_type{0}); - } - - size_type get_byte_offset() const - { - return 0; - } - static std::vector default_strides(const std::vector& shape, size_type itemsize) {