Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 56 additions & 5 deletions include/xtensor-python/pyarray.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,6 @@ namespace xt
using inner_backstrides_type = typename base_type::inner_backstrides_type;

pyarray();
pyarray(const self_type&) = default;
pyarray(self_type&&) = default;
pyarray(const value_type& t);
pyarray(nested_initializer_list_t<T, 1> t);
pyarray(nested_initializer_list_t<T, 2> t);
Expand All @@ -152,12 +150,15 @@ namespace xt
explicit pyarray(const shape_type& shape, const strides_type& strides, const_reference value);
explicit pyarray(const shape_type& shape, const strides_type& strides);

template <class E>
pyarray(const xexpression<E>& e);
pyarray(const self_type& rhs);
self_type& operator=(const self_type& rhs);

self_type& operator=(const self_type& e) = default;
pyarray(self_type&&) = default;
self_type& operator=(self_type&& e) = default;

template <class E>
pyarray(const xexpression<E>& e);

template <class E>
self_type& operator=(const xexpression<E>& e);

Expand Down Expand Up @@ -221,6 +222,7 @@ namespace xt
//@{
template <class T>
inline pyarray<T>::pyarray()
: base_type()
{
// TODO: avoid allocation
shape_type shape = make_sequence<shape_type>(0, size_type(1));
Expand All @@ -234,41 +236,47 @@ namespace xt
*/
template <class T>
inline pyarray<T>::pyarray(const value_type& t)
: base_type()
{
base_type::reshape(xt::shape<shape_type>(t), layout::row_major);
nested_copy(m_data.begin(), t);
}

template <class T>
inline pyarray<T>::pyarray(nested_initializer_list_t<T, 1> t)
: base_type()
{
base_type::reshape(xt::shape<shape_type>(t), layout::row_major);
nested_copy(m_data.begin(), t);
}

template <class T>
inline pyarray<T>::pyarray(nested_initializer_list_t<T, 2> t)
: base_type()
{
base_type::reshape(xt::shape<shape_type>(t), layout::row_major);
nested_copy(m_data.begin(), t);
}

template <class T>
inline pyarray<T>::pyarray(nested_initializer_list_t<T, 3> t)
: base_type()
{
base_type::reshape(xt::shape<shape_type>(t), layout::row_major);
nested_copy(m_data.begin(), t);
}

template <class T>
inline pyarray<T>::pyarray(nested_initializer_list_t<T, 4> t)
: base_type()
{
base_type::reshape(xt::shape<shape_type>(t), layout::row_major);
nested_copy(m_data.begin(), t);
}

template <class T>
inline pyarray<T>::pyarray(nested_initializer_list_t<T, 5> t)
: base_type()
{
base_type::reshape(xt::shape<shape_type>(t), layout::row_major);
nested_copy(m_data.begin(), t);
Expand Down Expand Up @@ -303,6 +311,7 @@ namespace xt
*/
template <class T>
inline pyarray<T>::pyarray(const shape_type& shape, layout l)
: base_type()
{
strides_type strides(shape.size());
compute_strides(shape, l, strides);
Expand All @@ -318,6 +327,7 @@ namespace xt
*/
template <class T>
inline pyarray<T>::pyarray(const shape_type& shape, const_reference value, layout l)
: base_type()
{
strides_type strides(shape.size());
compute_strides(shape, l, strides);
Expand All @@ -334,6 +344,7 @@ namespace xt
*/
template <class T>
inline pyarray<T>::pyarray(const shape_type& shape, const strides_type& strides, const_reference value)
: base_type()
{
init_array(shape, strides);
std::fill(m_data.begin(), m_data.end(), value);
Expand All @@ -346,11 +357,50 @@ namespace xt
*/
template <class T>
inline pyarray<T>::pyarray(const shape_type& shape, const strides_type& strides)
: base_type()
{
init_array(shape, strides);
}
//@}

/**
* @name Copy semantic
*/
//@{
/**
* The copy constructor.
*/
template <class T>
inline pyarray<T>::pyarray(const self_type& rhs)
: base_type()
{
auto tmp = pybind11::reinterpret_steal<pybind11::object>(
PyArray_NewLikeArray(rhs.python_array(), NPY_KEEPORDER, nullptr, 1)
);

if (!tmp)
{
throw std::runtime_error("NumPy: unable to create ndarray");
}

this->m_ptr = tmp.release().ptr();
init_from_python();
std::copy(rhs.data().begin(), rhs.data().end(), this->data().begin());
}

/**
* The assignment operator.
*/
template <class T>
inline auto pyarray<T>::operator=(const self_type& rhs) -> self_type&
{
self_type tmp(rhs);
*this = std::move(tmp);
return *this;
}

//@}

/**
* @name Extended copy semantic
*/
Expand All @@ -361,6 +411,7 @@ namespace xt
template <class T>
template <class E>
inline pyarray<T>::pyarray(const xexpression<E>& e)
: base_type()
{
semantic_base::assign(e);
}
Expand Down
4 changes: 2 additions & 2 deletions include/xtensor-python/pycontainer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ namespace xt
static bool check_(pybind11::handle h);
static PyObject* raw_array_t(PyObject* ptr);

PyArrayObject* python_array();
PyArrayObject* python_array() const;
};

namespace detail
Expand Down Expand Up @@ -199,7 +199,7 @@ namespace xt
}

template <class D>
inline PyArrayObject* pycontainer<D>::python_array()
inline PyArrayObject* pycontainer<D>::python_array() const
{
return reinterpret_cast<PyArrayObject*>(this->m_ptr);
}
Expand Down
37 changes: 34 additions & 3 deletions include/xtensor-python/pytensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,6 @@ namespace xt
using inner_backstrides_type = typename base_type::inner_backstrides_type;

pytensor();
pytensor(const self_type&) = default;
pytensor(self_type&&) = default;
pytensor(nested_initializer_list_t<T, N> t);
pytensor(pybind11::handle h, pybind11::object::borrowed_t);
pytensor(pybind11::handle h, pybind11::object::stolen_t);
Expand All @@ -130,7 +128,10 @@ namespace xt
explicit pytensor(const shape_type& shape, const strides_type& strides, const_reference value);
explicit pytensor(const shape_type& shape, const strides_type& strides);

self_type& operator=(const self_type& e) = default;
pytensor(const self_type& rhs) ;
self_type& operator=(const self_type& rhs);

pytensor(self_type&&) = default;
self_type& operator=(self_type&& e) = default;

template <class E>
Expand Down Expand Up @@ -181,6 +182,7 @@ namespace xt
*/
template <class T, std::size_t N>
inline pytensor<T, N>::pytensor()
: base_type()
{
m_shape = make_sequence<shape_type>(N, size_type(1));
m_strides = make_sequence<strides_type>(N, size_type(0));
Expand All @@ -193,6 +195,7 @@ namespace xt
*/
template <class T, std::size_t N>
inline pytensor<T, N>::pytensor(nested_initializer_list_t<T, N> t)
: base_type()
{
base_type::reshape(xt::shape<shape_type>(t), layout::row_major);
nested_copy(m_data.begin(), t);
Expand Down Expand Up @@ -278,6 +281,33 @@ namespace xt
}
//@}

/**
* @name Copy semantic
*/
//@{
/**
* The copy constructor.
*/
template <class T, std::size_t N>
inline pytensor<T, N>::pytensor(const self_type& rhs)
: base_type()
{
init_tensor(rhs.shape(), rhs.strides());
std::copy(rhs.data().begin(), rhs.data().end(), this->data().begin());
}

/**
* The assignment operator.
*/
template <class T, std::size_t N>
inline auto pytensor<T, N>::operator=(const self_type& rhs) -> self_type&
{
self_type tmp(rhs);
*this = std::move(tmp);
return *this;
}
//@}

/**
* @name Extended copy semantic
*/
Expand All @@ -288,6 +318,7 @@ namespace xt
template <class T, std::size_t N>
template <class E>
inline pytensor<T, N>::pytensor(const xexpression<E>& e)
: base_type()
{
semantic_base::assign(e);
}
Expand Down
4 changes: 4 additions & 0 deletions test/test_pyarray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ namespace xt
pyarray<int> b(a);
compare_shape(a, b);
EXPECT_EQ(a.data(), b.data());
a.data()[0] += 1;
EXPECT_NE(a.data()[0], b.data()[0]);
}

{
Expand All @@ -107,6 +109,8 @@ namespace xt
c = a;
compare_shape(a, c);
EXPECT_EQ(a.data(), c.data());
a.data()[0] += 1;
EXPECT_NE(a.data()[0], c.data()[0]);
}
}

Expand Down
4 changes: 4 additions & 0 deletions test/test_pytensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ namespace xt
pytensor<int, 3> b(a);
compare_shape(a, b);
EXPECT_EQ(a.data(), b.data());
a.data()[0] += 1;
EXPECT_NE(a.data()[0], b.data()[0]);
}

{
Expand All @@ -106,6 +108,8 @@ namespace xt
c = a;
compare_shape(a, c);
EXPECT_EQ(a.data(), c.data());
a.data()[0] += 1;
EXPECT_NE(a.data()[0], c.data()[0]);
}
}

Expand Down