GeezerVison is showing github.com — Merge pull request #76 from JohanMabille/semantic_fix · wolfv/xtensor-python@14e912b
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: include/xtensor-python/pyarray.hpp +56-5Lines changed: 56 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -134,8 +134,6 @@ namespace xt | 134 | 134 | using inner_backstrides_type = typename base_type::inner_backstrides_type; | 135 | 135 |
| 136 | 136 | pyarray(); | 137 | | - pyarray(const self_type&) = default; | 138 | | - pyarray(self_type&&) = default; | 139 | 137 | pyarray(const value_type& t); | 140 | 138 | pyarray(nested_initializer_list_t<T, 1> t); | 141 | 139 | pyarray(nested_initializer_list_t<T, 2> t); | @@ -152,12 +150,15 @@ namespace xt | 152 | 150 | explicit pyarray(const shape_type& shape, const strides_type& strides, const_reference value); | 153 | 151 | explicit pyarray(const shape_type& shape, const strides_type& strides); | 154 | 152 |
| 155 | | - template <class E> | 156 | | - pyarray(const xexpression<E>& e); | | 153 | + pyarray(const self_type& rhs); | | 154 | + self_type& operator=(const self_type& rhs); | 157 | 155 |
| 158 | | - self_type& operator=(const self_type& e) = default; | | 156 | + pyarray(self_type&&) = default; | 159 | 157 | self_type& operator=(self_type&& e) = default; | 160 | 158 |
| | 159 | + template <class E> | | 160 | + pyarray(const xexpression<E>& e); | | 161 | + | 161 | 162 | template <class E> | 162 | 163 | self_type& operator=(const xexpression<E>& e); | 163 | 164 |
| @@ -221,6 +222,7 @@ namespace xt | 221 | 222 | //@{ | 222 | 223 | template <class T> | 223 | 224 | inline pyarray<T>::pyarray() | | 225 | + : base_type() | 224 | 226 | { | 225 | 227 | // TODO: avoid allocation | 226 | 228 | shape_type shape = make_sequence<shape_type>(0, size_type(1)); | @@ -234,41 +236,47 @@ namespace xt | 234 | 236 | */ | 235 | 237 | template <class T> | 236 | 238 | inline pyarray<T>::pyarray(const value_type& t) | | 239 | + : base_type() | 237 | 240 | { | 238 | 241 | base_type::reshape(xt::shape<shape_type>(t), layout::row_major); | 239 | 242 | nested_copy(m_data.begin(), t); | 240 | 243 | } | 241 | 244 |
| 242 | 245 | template <class T> | 243 | 246 | inline pyarray<T>::pyarray(nested_initializer_list_t<T, 1> t) | | 247 | + : base_type() | 244 | 248 | { | 245 | 249 | base_type::reshape(xt::shape<shape_type>(t), layout::row_major); | 246 | 250 | nested_copy(m_data.begin(), t); | 247 | 251 | } | 248 | 252 |
| 249 | 253 | template <class T> | 250 | 254 | inline pyarray<T>::pyarray(nested_initializer_list_t<T, 2> t) | | 255 | + : base_type() | 251 | 256 | { | 252 | 257 | base_type::reshape(xt::shape<shape_type>(t), layout::row_major); | 253 | 258 | nested_copy(m_data.begin(), t); | 254 | 259 | } | 255 | 260 |
| 256 | 261 | template <class T> | 257 | 262 | inline pyarray<T>::pyarray(nested_initializer_list_t<T, 3> t) | | 263 | + : base_type() | 258 | 264 | { | 259 | 265 | base_type::reshape(xt::shape<shape_type>(t), layout::row_major); | 260 | 266 | nested_copy(m_data.begin(), t); | 261 | 267 | } | 262 | 268 |
| 263 | 269 | template <class T> | 264 | 270 | inline pyarray<T>::pyarray(nested_initializer_list_t<T, 4> t) | | 271 | + : base_type() | 265 | 272 | { | 266 | 273 | base_type::reshape(xt::shape<shape_type>(t), layout::row_major); | 267 | 274 | nested_copy(m_data.begin(), t); | 268 | 275 | } | 269 | 276 |
| 270 | 277 | template <class T> | 271 | 278 | inline pyarray<T>::pyarray(nested_initializer_list_t<T, 5> t) | | 279 | + : base_type() | 272 | 280 | { | 273 | 281 | base_type::reshape(xt::shape<shape_type>(t), layout::row_major); | 274 | 282 | nested_copy(m_data.begin(), t); | @@ -303,6 +311,7 @@ namespace xt | 303 | 311 | */ | 304 | 312 | template <class T> | 305 | 313 | inline pyarray<T>::pyarray(const shape_type& shape, layout l) | | 314 | + : base_type() | 306 | 315 | { | 307 | 316 | strides_type strides(shape.size()); | 308 | 317 | compute_strides(shape, l, strides); | @@ -318,6 +327,7 @@ namespace xt | 318 | 327 | */ | 319 | 328 | template <class T> | 320 | 329 | inline pyarray<T>::pyarray(const shape_type& shape, const_reference value, layout l) | | 330 | + : base_type() | 321 | 331 | { | 322 | 332 | strides_type strides(shape.size()); | 323 | 333 | compute_strides(shape, l, strides); | @@ -334,6 +344,7 @@ namespace xt | 334 | 344 | */ | 335 | 345 | template <class T> | 336 | 346 | inline pyarray<T>::pyarray(const shape_type& shape, const strides_type& strides, const_reference value) | | 347 | + : base_type() | 337 | 348 | { | 338 | 349 | init_array(shape, strides); | 339 | 350 | std::fill(m_data.begin(), m_data.end(), value); | @@ -346,11 +357,50 @@ namespace xt | 346 | 357 | */ | 347 | 358 | template <class T> | 348 | 359 | inline pyarray<T>::pyarray(const shape_type& shape, const strides_type& strides) | | 360 | + : base_type() | 349 | 361 | { | 350 | 362 | init_array(shape, strides); | 351 | 363 | } | 352 | 364 | //@} | 353 | 365 |
| | 366 | + /** | | 367 | + * @name Copy semantic | | 368 | + */ | | 369 | + //@{ | | 370 | + /** | | 371 | + * The copy constructor. | | 372 | + */ | | 373 | + template <class T> | | 374 | + inline pyarray<T>::pyarray(const self_type& rhs) | | 375 | + : base_type() | | 376 | + { | | 377 | + auto tmp = pybind11::reinterpret_steal<pybind11::object>( | | 378 | + PyArray_NewLikeArray(rhs.python_array(), NPY_KEEPORDER, nullptr, 1) | | 379 | + ); | | 380 | + | | 381 | + if (!tmp) | | 382 | + { | | 383 | + throw std::runtime_error("NumPy: unable to create ndarray"); | | 384 | + } | | 385 | + | | 386 | + this->m_ptr = tmp.release().ptr(); | | 387 | + init_from_python(); | | 388 | + std::copy(rhs.data().begin(), rhs.data().end(), this->data().begin()); | | 389 | + } | | 390 | + | | 391 | + /** | | 392 | + * The assignment operator. | | 393 | + */ | | 394 | + template <class T> | | 395 | + inline auto pyarray<T>::operator=(const self_type& rhs) -> self_type& | | 396 | + { | | 397 | + self_type tmp(rhs); | | 398 | + *this = std::move(tmp); | | 399 | + return *this; | | 400 | + } | | 401 | + | | 402 | + //@} | | 403 | + | 354 | 404 | /** | 355 | 405 | * @name Extended copy semantic | 356 | 406 | */ | @@ -361,6 +411,7 @@ namespace xt | 361 | 411 | template <class T> | 362 | 412 | template <class E> | 363 | 413 | inline pyarray<T>::pyarray(const xexpression<E>& e) | | 414 | + : base_type() | 364 | 415 | { | 365 | 416 | shape_type shape = forward_sequence<shape_type>(e.derived_cast().shape()); | 366 | 417 | strides_type strides = make_sequence<strides_type>(shape.size(), size_type(0)); | |
Collapse file Copy file name to clipboardExpand all lines: include/xtensor-python/pycontainer.hpp +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -108,7 +108,7 @@ namespace xt | 108 | 108 | static bool check_(pybind11::handle h); | 109 | 109 | static PyObject* raw_array_t(PyObject* ptr); | 110 | 110 |
| 111 | | - PyArrayObject* python_array(); | | 111 | + PyArrayObject* python_array() const; | 112 | 112 | }; | 113 | 113 |
| 114 | 114 | namespace detail | @@ -199,7 +199,7 @@ namespace xt | 199 | 199 | } | 200 | 200 |
| 201 | 201 | template <class D> | 202 | | - inline PyArrayObject* pycontainer<D>::python_array() | | 202 | + inline PyArrayObject* pycontainer<D>::python_array() const | 203 | 203 | { | 204 | 204 | return reinterpret_cast<PyArrayObject*>(this->m_ptr); | 205 | 205 | } | |
Collapse file Copy file name to clipboardExpand all lines: include/xtensor-python/pytensor.hpp +34-3Lines changed: 34 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -118,8 +118,6 @@ namespace xt | 118 | 118 | using inner_backstrides_type = typename base_type::inner_backstrides_type; | 119 | 119 |
| 120 | 120 | pytensor(); | 121 | | - pytensor(const self_type&) = default; | 122 | | - pytensor(self_type&&) = default; | 123 | 121 | pytensor(nested_initializer_list_t<T, N> t); | 124 | 122 | pytensor(pybind11::handle h, pybind11::object::borrowed_t); | 125 | 123 | pytensor(pybind11::handle h, pybind11::object::stolen_t); | @@ -130,7 +128,10 @@ namespace xt | 130 | 128 | explicit pytensor(const shape_type& shape, const strides_type& strides, const_reference value); | 131 | 129 | explicit pytensor(const shape_type& shape, const strides_type& strides); | 132 | 130 |
| 133 | | - self_type& operator=(const self_type& e) = default; | | 131 | + pytensor(const self_type& rhs) ; | | 132 | + self_type& operator=(const self_type& rhs); | | 133 | + | | 134 | + pytensor(self_type&&) = default; | 134 | 135 | self_type& operator=(self_type&& e) = default; | 135 | 136 |
| 136 | 137 | template <class E> | @@ -181,6 +182,7 @@ namespace xt | 181 | 182 | */ | 182 | 183 | template <class T, std::size_t N> | 183 | 184 | inline pytensor<T, N>::pytensor() | | 185 | + : base_type() | 184 | 186 | { | 185 | 187 | m_shape = make_sequence<shape_type>(N, size_type(1)); | 186 | 188 | m_strides = make_sequence<strides_type>(N, size_type(0)); | @@ -193,6 +195,7 @@ namespace xt | 193 | 195 | */ | 194 | 196 | template <class T, std::size_t N> | 195 | 197 | inline pytensor<T, N>::pytensor(nested_initializer_list_t<T, N> t) | | 198 | + : base_type() | 196 | 199 | { | 197 | 200 | base_type::reshape(xt::shape<shape_type>(t), layout::row_major); | 198 | 201 | nested_copy(m_data.begin(), t); | @@ -278,6 +281,33 @@ namespace xt | 278 | 281 | } | 279 | 282 | //@} | 280 | 283 |
| | 284 | + /** | | 285 | + * @name Copy semantic | | 286 | + */ | | 287 | + //@{ | | 288 | + /** | | 289 | + * The copy constructor. | | 290 | + */ | | 291 | + template <class T, std::size_t N> | | 292 | + inline pytensor<T, N>::pytensor(const self_type& rhs) | | 293 | + : base_type() | | 294 | + { | | 295 | + init_tensor(rhs.shape(), rhs.strides()); | | 296 | + std::copy(rhs.data().begin(), rhs.data().end(), this->data().begin()); | | 297 | + } | | 298 | + | | 299 | + /** | | 300 | + * The assignment operator. | | 301 | + */ | | 302 | + template <class T, std::size_t N> | | 303 | + inline auto pytensor<T, N>::operator=(const self_type& rhs) -> self_type& | | 304 | + { | | 305 | + self_type tmp(rhs); | | 306 | + *this = std::move(tmp); | | 307 | + return *this; | | 308 | + } | | 309 | + //@} | | 310 | + | 281 | 311 | /** | 282 | 312 | * @name Extended copy semantic | 283 | 313 | */ | @@ -288,6 +318,7 @@ namespace xt | 288 | 318 | template <class T, std::size_t N> | 289 | 319 | template <class E> | 290 | 320 | inline pytensor<T, N>::pytensor(const xexpression<E>& e) | | 321 | + : base_type() | 291 | 322 | { | 292 | 323 | shape_type shape = forward_sequence<shape_type>(e.derived_cast().shape()); | 293 | 324 | strides_type strides = make_sequence<strides_type>(N, size_type(0)); | |
Collapse file Copy file name to clipboardExpand all lines: test/test_pyarray.cpp +4Lines changed: 4 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -97,6 +97,8 @@ namespace xt | 97 | 97 | pyarray<int> b(a); | 98 | 98 | compare_shape(a, b); | 99 | 99 | EXPECT_EQ(a.data(), b.data()); | | 100 | + a.data()[0] += 1; | | 101 | + EXPECT_NE(a.data()[0], b.data()[0]); | 100 | 102 | } | 101 | 103 |
| 102 | 104 | { | @@ -107,6 +109,8 @@ namespace xt | 107 | 109 | c = a; | 108 | 110 | compare_shape(a, c); | 109 | 111 | EXPECT_EQ(a.data(), c.data()); | | 112 | + a.data()[0] += 1; | | 113 | + EXPECT_NE(a.data()[0], c.data()[0]); | 110 | 114 | } | 111 | 115 | } | 112 | 116 |
| |
Collapse file Copy file name to clipboardExpand all lines: test/test_pytensor.cpp +4Lines changed: 4 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -96,6 +96,8 @@ namespace xt | 96 | 96 | pytensor<int, 3> b(a); | 97 | 97 | compare_shape(a, b); | 98 | 98 | EXPECT_EQ(a.data(), b.data()); | | 99 | + a.data()[0] += 1; | | 100 | + EXPECT_NE(a.data()[0], b.data()[0]); | 99 | 101 | } | 100 | 102 |
| 101 | 103 | { | @@ -106,6 +108,8 @@ namespace xt | 106 | 108 | c = a; | 107 | 109 | compare_shape(a, c); | 108 | 110 | EXPECT_EQ(a.data(), c.data()); | | 111 | + a.data()[0] += 1; | | 112 | + EXPECT_NE(a.data()[0], c.data()[0]); | 109 | 113 | } | 110 | 114 | } | 111 | 115 |
| |
|