1
0

xarray.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. /***************************************************************************
  2. * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
  3. * Copyright (c) QuantStack *
  4. * *
  5. * Distributed under the terms of the BSD 3-Clause License. *
  6. * *
  7. * The full license is in the file LICENSE, distributed with this software. *
  8. ****************************************************************************/
  9. #ifndef XTENSOR_ARRAY_HPP
  10. #define XTENSOR_ARRAY_HPP
  11. #include <algorithm>
  12. #include <initializer_list>
  13. #include <utility>
  14. #include <xtl/xsequence.hpp>
  15. #include "xbuffer_adaptor.hpp"
  16. #include "xcontainer.hpp"
  17. #include "xsemantic.hpp"
  18. namespace xt
  19. {
  20. /********************************
  21. * xarray_container declaration *
  22. ********************************/
  23. namespace extension
  24. {
  25. template <class EC, layout_type L, class SC, class Tag>
  26. struct xarray_container_base;
  27. template <class EC, layout_type L, class SC>
  28. struct xarray_container_base<EC, L, SC, xtensor_expression_tag>
  29. {
  30. using type = xtensor_empty_base;
  31. };
  32. template <class EC, layout_type L, class SC, class Tag>
  33. using xarray_container_base_t = typename xarray_container_base<EC, L, SC, Tag>::type;
  34. }
  35. template <class EC, layout_type L, class SC, class Tag>
  36. struct xcontainer_inner_types<xarray_container<EC, L, SC, Tag>>
  37. {
  38. using storage_type = EC;
  39. using reference = inner_reference_t<storage_type>;
  40. using const_reference = typename storage_type::const_reference;
  41. using size_type = typename storage_type::size_type;
  42. using shape_type = SC;
  43. using strides_type = get_strides_t<shape_type>;
  44. using backstrides_type = get_strides_t<shape_type>;
  45. using inner_shape_type = shape_type;
  46. using inner_strides_type = strides_type;
  47. using inner_backstrides_type = backstrides_type;
  48. using temporary_type = xarray_container<EC, L, SC, Tag>;
  49. static constexpr layout_type layout = L;
  50. };
  51. template <class EC, layout_type L, class SC, class Tag>
  52. struct xiterable_inner_types<xarray_container<EC, L, SC, Tag>>
  53. : xcontainer_iterable_types<xarray_container<EC, L, SC, Tag>>
  54. {
  55. };
  56. /**
  57. * @class xarray_container
  58. * @brief Dense multidimensional container with tensor semantic.
  59. *
  60. * The xarray_container class implements a dense multidimensional container
  61. * with tensor semantic.
  62. *
  63. * @tparam EC The type of the container holding the elements.
  64. * @tparam L The layout_type of the container.
  65. * @tparam SC The type of the containers holding the shape and the strides.
  66. * @tparam Tag The expression tag.
  67. * @sa xarray, xstrided_container, xcontainer
  68. */
  69. template <class EC, layout_type L, class SC, class Tag>
  70. class xarray_container : public xstrided_container<xarray_container<EC, L, SC, Tag>>,
  71. public xcontainer_semantic<xarray_container<EC, L, SC, Tag>>,
  72. public extension::xarray_container_base_t<EC, L, SC, Tag>
  73. {
  74. public:
  75. using self_type = xarray_container<EC, L, SC, Tag>;
  76. using base_type = xstrided_container<self_type>;
  77. using semantic_base = xcontainer_semantic<self_type>;
  78. using extension_base = extension::xarray_container_base_t<EC, L, SC, Tag>;
  79. using storage_type = typename base_type::storage_type;
  80. using allocator_type = typename base_type::allocator_type;
  81. using value_type = typename base_type::value_type;
  82. using reference = typename base_type::reference;
  83. using const_reference = typename base_type::const_reference;
  84. using pointer = typename base_type::pointer;
  85. using const_pointer = typename base_type::const_pointer;
  86. using shape_type = typename base_type::shape_type;
  87. using inner_shape_type = typename base_type::inner_shape_type;
  88. using strides_type = typename base_type::strides_type;
  89. using backstrides_type = typename base_type::backstrides_type;
  90. using inner_strides_type = typename base_type::inner_strides_type;
  91. using inner_backstrides_type = typename base_type::inner_backstrides_type;
  92. using temporary_type = typename semantic_base::temporary_type;
  93. using expression_tag = Tag;
  94. static constexpr std::size_t rank = SIZE_MAX;
  95. xarray_container();
  96. explicit xarray_container(const shape_type& shape, layout_type l = L);
  97. explicit xarray_container(const shape_type& shape, const_reference value, layout_type l = L);
  98. explicit xarray_container(const shape_type& shape, const strides_type& strides);
  99. explicit xarray_container(const shape_type& shape, const strides_type& strides, const_reference value);
  100. explicit xarray_container(storage_type&& storage, inner_shape_type&& shape, inner_strides_type&& strides);
  101. xarray_container(const value_type& t);
  102. xarray_container(nested_initializer_list_t<value_type, 1> t);
  103. xarray_container(nested_initializer_list_t<value_type, 2> t);
  104. xarray_container(nested_initializer_list_t<value_type, 3> t);
  105. xarray_container(nested_initializer_list_t<value_type, 4> t);
  106. xarray_container(nested_initializer_list_t<value_type, 5> t);
  107. template <class S = shape_type>
  108. static xarray_container from_shape(S&& s);
  109. ~xarray_container() = default;
  110. xarray_container(const xarray_container&) = default;
  111. xarray_container& operator=(const xarray_container&) = default;
  112. xarray_container(xarray_container&&) = default;
  113. xarray_container& operator=(xarray_container&&) = default;
  114. template <std::size_t N>
  115. explicit xarray_container(xtensor_container<EC, N, L, Tag>&& rhs);
  116. template <std::size_t N>
  117. xarray_container& operator=(xtensor_container<EC, N, L, Tag>&& rhs);
  118. template <class E>
  119. xarray_container(const xexpression<E>& e);
  120. template <class E>
  121. xarray_container& operator=(const xexpression<E>& e);
  122. private:
  123. storage_type m_storage;
  124. storage_type& storage_impl() noexcept;
  125. const storage_type& storage_impl() const noexcept;
  126. friend class xcontainer<xarray_container<EC, L, SC, Tag>>;
  127. };
  128. /******************************
  129. * xarray_adaptor declaration *
  130. ******************************/
  131. namespace extension
  132. {
  133. template <class EC, layout_type L, class SC, class Tag>
  134. struct xarray_adaptor_base;
  135. template <class EC, layout_type L, class SC>
  136. struct xarray_adaptor_base<EC, L, SC, xtensor_expression_tag>
  137. {
  138. using type = xtensor_empty_base;
  139. };
  140. template <class EC, layout_type L, class SC, class Tag>
  141. using xarray_adaptor_base_t = typename xarray_adaptor_base<EC, L, SC, Tag>::type;
  142. }
  143. template <class EC, layout_type L, class SC, class Tag>
  144. struct xcontainer_inner_types<xarray_adaptor<EC, L, SC, Tag>>
  145. {
  146. using storage_type = std::remove_reference_t<EC>;
  147. using reference = inner_reference_t<storage_type>;
  148. using const_reference = typename storage_type::const_reference;
  149. using size_type = typename storage_type::size_type;
  150. using shape_type = SC;
  151. using strides_type = get_strides_t<shape_type>;
  152. using backstrides_type = get_strides_t<shape_type>;
  153. using inner_shape_type = shape_type;
  154. using inner_strides_type = strides_type;
  155. using inner_backstrides_type = backstrides_type;
  156. using temporary_type = xarray_container<temporary_container_t<storage_type>, L, SC, Tag>;
  157. static constexpr layout_type layout = L;
  158. };
  159. template <class EC, layout_type L, class SC, class Tag>
  160. struct xiterable_inner_types<xarray_adaptor<EC, L, SC, Tag>>
  161. : xcontainer_iterable_types<xarray_adaptor<EC, L, SC, Tag>>
  162. {
  163. };
  164. /**
  165. * @class xarray_adaptor
  166. * @brief Dense multidimensional container adaptor with
  167. * tensor semantic.
  168. *
  169. * The xarray_adaptor class implements a dense multidimensional
  170. * container adaptor with tensor semantic. It is used to provide
  171. * a multidimensional container semantic and a tensor semantic to
  172. * stl-like containers.
  173. *
  174. * @tparam EC The closure for the container type to adapt.
  175. * @tparam L The layout_type of the adaptor.
  176. * @tparam SC The type of the containers holding the shape and the strides.
  177. * @tparam Tag The expression tag.
  178. * @sa xstrided_container, xcontainer
  179. */
  180. template <class EC, layout_type L, class SC, class Tag>
  181. class xarray_adaptor : public xstrided_container<xarray_adaptor<EC, L, SC, Tag>>,
  182. public xcontainer_semantic<xarray_adaptor<EC, L, SC, Tag>>,
  183. public extension::xarray_adaptor_base_t<EC, L, SC, Tag>
  184. {
  185. public:
  186. using container_closure_type = EC;
  187. using self_type = xarray_adaptor<EC, L, SC, Tag>;
  188. using base_type = xstrided_container<self_type>;
  189. using semantic_base = xcontainer_semantic<self_type>;
  190. using extension_base = extension::xarray_adaptor_base_t<EC, L, SC, Tag>;
  191. using storage_type = typename base_type::storage_type;
  192. using allocator_type = typename base_type::allocator_type;
  193. using shape_type = typename base_type::shape_type;
  194. using strides_type = typename base_type::strides_type;
  195. using backstrides_type = typename base_type::backstrides_type;
  196. using temporary_type = typename semantic_base::temporary_type;
  197. using expression_tag = Tag;
  198. static constexpr std::size_t rank = SIZE_MAX;
  199. xarray_adaptor(storage_type&& storage);
  200. xarray_adaptor(const storage_type& storage);
  201. template <class D>
  202. xarray_adaptor(D&& storage, const shape_type& shape, layout_type l = L);
  203. template <class D>
  204. xarray_adaptor(D&& storage, const shape_type& shape, const strides_type& strides);
  205. ~xarray_adaptor() = default;
  206. xarray_adaptor(const xarray_adaptor&) = default;
  207. xarray_adaptor& operator=(const xarray_adaptor&);
  208. xarray_adaptor(xarray_adaptor&&) = default;
  209. xarray_adaptor& operator=(xarray_adaptor&&);
  210. xarray_adaptor& operator=(temporary_type&&);
  211. template <class E>
  212. xarray_adaptor& operator=(const xexpression<E>& e);
  213. template <class P, class S>
  214. void reset_buffer(P&& pointer, S&& size);
  215. private:
  216. container_closure_type m_storage;
  217. storage_type& storage_impl() noexcept;
  218. const storage_type& storage_impl() const noexcept;
  219. friend class xcontainer<xarray_adaptor<EC, L, SC, Tag>>;
  220. };
  221. /***********************************
  222. * xarray_container implementation *
  223. ***********************************/
  224. /**
  225. * @name Constructors
  226. */
  227. //@{
  228. /**
  229. * Allocates an uninitialized xarray_container that holds 0 element.
  230. */
  231. template <class EC, layout_type L, class SC, class Tag>
  232. inline xarray_container<EC, L, SC, Tag>::xarray_container()
  233. : base_type()
  234. , m_storage(1, value_type())
  235. {
  236. }
  237. /**
  238. * Allocates an uninitialized xarray_container with the specified shape and
  239. * layout_type.
  240. * @param shape the shape of the xarray_container
  241. * @param l the layout_type of the xarray_container
  242. */
  243. template <class EC, layout_type L, class SC, class Tag>
  244. inline xarray_container<EC, L, SC, Tag>::xarray_container(const shape_type& shape, layout_type l)
  245. : base_type()
  246. {
  247. base_type::resize(shape, l);
  248. }
  249. /**
  250. * Allocates an xarray_container with the specified shape and layout_type. Elements
  251. * are initialized to the specified value.
  252. * @param shape the shape of the xarray_container
  253. * @param value the value of the elements
  254. * @param l the layout_type of the xarray_container
  255. */
  256. template <class EC, layout_type L, class SC, class Tag>
  257. inline xarray_container<EC, L, SC, Tag>::xarray_container(
  258. const shape_type& shape,
  259. const_reference value,
  260. layout_type l
  261. )
  262. : base_type()
  263. {
  264. base_type::resize(shape, l);
  265. std::fill(m_storage.begin(), m_storage.end(), value);
  266. }
  267. /**
  268. * Allocates an uninitialized xarray_container with the specified shape and strides.
  269. * @param shape the shape of the xarray_container
  270. * @param strides the strides of the xarray_container
  271. */
  272. template <class EC, layout_type L, class SC, class Tag>
  273. inline xarray_container<EC, L, SC, Tag>::xarray_container(const shape_type& shape, const strides_type& strides)
  274. : base_type()
  275. {
  276. base_type::resize(shape, strides);
  277. }
  278. /**
  279. * Allocates an uninitialized xarray_container with the specified shape and strides.
  280. * Elements are initialized to the specified value.
  281. * @param shape the shape of the xarray_container
  282. * @param strides the strides of the xarray_container
  283. * @param value the value of the elements
  284. */
  285. template <class EC, layout_type L, class SC, class Tag>
  286. inline xarray_container<EC, L, SC, Tag>::xarray_container(
  287. const shape_type& shape,
  288. const strides_type& strides,
  289. const_reference value
  290. )
  291. : base_type()
  292. {
  293. base_type::resize(shape, strides);
  294. std::fill(m_storage.begin(), m_storage.end(), value);
  295. }
  296. /**
  297. * Allocates an xarray_container that holds a single element initialized to the
  298. * specified value.
  299. * @param t the value of the element
  300. */
  301. template <class EC, layout_type L, class SC, class Tag>
  302. inline xarray_container<EC, L, SC, Tag>::xarray_container(const value_type& t)
  303. : base_type()
  304. {
  305. base_type::resize(xt::shape<shape_type>(t), true);
  306. nested_copy(m_storage.begin(), t);
  307. }
  308. /**
  309. * Allocates an xarray_container by moving specified data, shape and strides
  310. *
  311. * @param storage the data for the xarray_container
  312. * @param shape the shape of the xarray_container
  313. * @param strides the strides of the xarray_container
  314. */
  315. template <class EC, layout_type L, class SC, class Tag>
  316. inline xarray_container<EC, L, SC, Tag>::xarray_container(
  317. storage_type&& storage,
  318. inner_shape_type&& shape,
  319. inner_strides_type&& strides
  320. )
  321. : base_type(std::move(shape), std::move(strides))
  322. , m_storage(std::move(storage))
  323. {
  324. }
  325. //@}
  326. /**
  327. * @name Constructors from initializer list
  328. */
  329. //@{
  330. /**
  331. * Allocates a one-dimensional xarray_container.
  332. * @param t the elements of the xarray_container
  333. */
  334. template <class EC, layout_type L, class SC, class Tag>
  335. inline xarray_container<EC, L, SC, Tag>::xarray_container(nested_initializer_list_t<value_type, 1> t)
  336. : base_type()
  337. {
  338. base_type::resize(xt::shape<shape_type>(t));
  339. constexpr auto tmp = layout_type::row_major;
  340. L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
  341. }
  342. /**
  343. * Allocates a two-dimensional xarray_container.
  344. * @param t the elements of the xarray_container
  345. */
  346. template <class EC, layout_type L, class SC, class Tag>
  347. inline xarray_container<EC, L, SC, Tag>::xarray_container(nested_initializer_list_t<value_type, 2> t)
  348. : base_type()
  349. {
  350. base_type::resize(xt::shape<shape_type>(t));
  351. constexpr auto tmp = layout_type::row_major;
  352. L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
  353. }
  354. /**
  355. * Allocates a three-dimensional xarray_container.
  356. * @param t the elements of the xarray_container
  357. */
  358. template <class EC, layout_type L, class SC, class Tag>
  359. inline xarray_container<EC, L, SC, Tag>::xarray_container(nested_initializer_list_t<value_type, 3> t)
  360. : base_type()
  361. {
  362. base_type::resize(xt::shape<shape_type>(t));
  363. constexpr auto tmp = layout_type::row_major;
  364. L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
  365. }
  366. /**
  367. * Allocates a four-dimensional xarray_container.
  368. * @param t the elements of the xarray_container
  369. */
  370. template <class EC, layout_type L, class SC, class Tag>
  371. inline xarray_container<EC, L, SC, Tag>::xarray_container(nested_initializer_list_t<value_type, 4> t)
  372. : base_type()
  373. {
  374. base_type::resize(xt::shape<shape_type>(t));
  375. constexpr auto tmp = layout_type::row_major;
  376. L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
  377. }
  378. /**
  379. * Allocates a five-dimensional xarray_container.
  380. * @param t the elements of the xarray_container
  381. */
  382. template <class EC, layout_type L, class SC, class Tag>
  383. inline xarray_container<EC, L, SC, Tag>::xarray_container(nested_initializer_list_t<value_type, 5> t)
  384. : base_type()
  385. {
  386. base_type::resize(xt::shape<shape_type>(t));
  387. constexpr auto tmp = layout_type::row_major;
  388. L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
  389. }
  390. //@}
  391. /**
  392. * Allocates and returns an xarray_container with the specified shape.
  393. * @param s the shape of the xarray_container
  394. */
  395. template <class EC, layout_type L, class SC, class Tag>
  396. template <class S>
  397. inline xarray_container<EC, L, SC, Tag> xarray_container<EC, L, SC, Tag>::from_shape(S&& s)
  398. {
  399. shape_type shape = xtl::forward_sequence<shape_type, S>(s);
  400. return self_type(shape);
  401. }
  402. template <class EC, layout_type L, class SC, class Tag>
  403. template <std::size_t N>
  404. inline xarray_container<EC, L, SC, Tag>::xarray_container(xtensor_container<EC, N, L, Tag>&& rhs)
  405. : base_type(
  406. inner_shape_type(rhs.shape().cbegin(), rhs.shape().cend()),
  407. inner_strides_type(rhs.strides().cbegin(), rhs.strides().cend()),
  408. inner_backstrides_type(rhs.backstrides().cbegin(), rhs.backstrides().cend()),
  409. std::move(rhs.layout())
  410. )
  411. , m_storage(std::move(rhs.storage()))
  412. {
  413. }
  414. template <class EC, layout_type L, class SC, class Tag>
  415. template <std::size_t N>
  416. inline xarray_container<EC, L, SC, Tag>&
  417. xarray_container<EC, L, SC, Tag>::operator=(xtensor_container<EC, N, L, Tag>&& rhs)
  418. {
  419. this->shape_impl().assign(rhs.shape().cbegin(), rhs.shape().cend());
  420. this->strides_impl().assign(rhs.strides().cbegin(), rhs.strides().cend());
  421. this->backstrides_impl().assign(rhs.backstrides().cbegin(), rhs.backstrides().cend());
  422. this->mutable_layout() = rhs.layout();
  423. m_storage = std::move(rhs.storage());
  424. return *this;
  425. }
  426. /**
  427. * @name Extended copy semantic
  428. */
  429. //@{
  430. /**
  431. * The extended copy constructor.
  432. */
  433. template <class EC, layout_type L, class SC, class Tag>
  434. template <class E>
  435. inline xarray_container<EC, L, SC, Tag>::xarray_container(const xexpression<E>& e)
  436. : base_type()
  437. {
  438. // Avoids unintialized data because of (m_shape == shape) condition
  439. // in resize (called by assign), which is always true when dimension == 0.
  440. if (e.derived_cast().dimension() == 0)
  441. {
  442. detail::resize_data_container(m_storage, std::size_t(1));
  443. }
  444. semantic_base::assign(e);
  445. }
  446. /**
  447. * The extended assignment operator.
  448. */
  449. template <class EC, layout_type L, class SC, class Tag>
  450. template <class E>
  451. inline auto xarray_container<EC, L, SC, Tag>::operator=(const xexpression<E>& e) -> self_type&
  452. {
  453. return semantic_base::operator=(e);
  454. }
  455. //@}
  456. template <class EC, layout_type L, class SC, class Tag>
  457. inline auto xarray_container<EC, L, SC, Tag>::storage_impl() noexcept -> storage_type&
  458. {
  459. return m_storage;
  460. }
  461. template <class EC, layout_type L, class SC, class Tag>
  462. inline auto xarray_container<EC, L, SC, Tag>::storage_impl() const noexcept -> const storage_type&
  463. {
  464. return m_storage;
  465. }
  466. /******************
  467. * xarray_adaptor *
  468. ******************/
  469. /**
  470. * @name Constructors
  471. */
  472. //@{
  473. /**
  474. * Constructs an xarray_adaptor of the given stl-like container.
  475. * @param storage the container to adapt
  476. */
  477. template <class EC, layout_type L, class SC, class Tag>
  478. inline xarray_adaptor<EC, L, SC, Tag>::xarray_adaptor(storage_type&& storage)
  479. : base_type()
  480. , m_storage(std::move(storage))
  481. {
  482. }
  483. /**
  484. * Constructs an xarray_adaptor of the given stl-like container.
  485. * @param storage the container to adapt
  486. */
  487. template <class EC, layout_type L, class SC, class Tag>
  488. inline xarray_adaptor<EC, L, SC, Tag>::xarray_adaptor(const storage_type& storage)
  489. : base_type()
  490. , m_storage(storage)
  491. {
  492. }
  493. /**
  494. * Constructs an xarray_adaptor of the given stl-like container,
  495. * with the specified shape and layout_type.
  496. * @param storage the container to adapt
  497. * @param shape the shape of the xarray_adaptor
  498. * @param l the layout_type of the xarray_adaptor
  499. */
  500. template <class EC, layout_type L, class SC, class Tag>
  501. template <class D>
  502. inline xarray_adaptor<EC, L, SC, Tag>::xarray_adaptor(D&& storage, const shape_type& shape, layout_type l)
  503. : base_type()
  504. , m_storage(std::forward<D>(storage))
  505. {
  506. base_type::resize(shape, l);
  507. }
  508. /**
  509. * Constructs an xarray_adaptor of the given stl-like container,
  510. * with the specified shape and strides.
  511. * @param storage the container to adapt
  512. * @param shape the shape of the xarray_adaptor
  513. * @param strides the strides of the xarray_adaptor
  514. */
  515. template <class EC, layout_type L, class SC, class Tag>
  516. template <class D>
  517. inline xarray_adaptor<EC, L, SC, Tag>::xarray_adaptor(
  518. D&& storage,
  519. const shape_type& shape,
  520. const strides_type& strides
  521. )
  522. : base_type()
  523. , m_storage(std::forward<D>(storage))
  524. {
  525. base_type::resize(shape, strides);
  526. }
  527. //@}
  528. template <class EC, layout_type L, class SC, class Tag>
  529. inline auto xarray_adaptor<EC, L, SC, Tag>::operator=(const xarray_adaptor& rhs) -> self_type&
  530. {
  531. base_type::operator=(rhs);
  532. m_storage = rhs.m_storage;
  533. return *this;
  534. }
  535. template <class EC, layout_type L, class SC, class Tag>
  536. inline auto xarray_adaptor<EC, L, SC, Tag>::operator=(xarray_adaptor&& rhs) -> self_type&
  537. {
  538. base_type::operator=(std::move(rhs));
  539. m_storage = rhs.m_storage;
  540. return *this;
  541. }
  542. template <class EC, layout_type L, class SC, class Tag>
  543. inline auto xarray_adaptor<EC, L, SC, Tag>::operator=(temporary_type&& rhs) -> self_type&
  544. {
  545. base_type::shape_impl() = std::move(const_cast<shape_type&>(rhs.shape()));
  546. base_type::strides_impl() = std::move(const_cast<strides_type&>(rhs.strides()));
  547. base_type::backstrides_impl() = std::move(const_cast<backstrides_type&>(rhs.backstrides()));
  548. m_storage = std::move(rhs.storage());
  549. return *this;
  550. }
  551. /**
  552. * @name Extended copy semantic
  553. */
  554. //@{
  555. /**
  556. * The extended assignment operator.
  557. */
  558. template <class EC, layout_type L, class SC, class Tag>
  559. template <class E>
  560. inline auto xarray_adaptor<EC, L, SC, Tag>::operator=(const xexpression<E>& e) -> self_type&
  561. {
  562. return semantic_base::operator=(e);
  563. }
  564. //@}
  565. template <class EC, layout_type L, class SC, class Tag>
  566. inline auto xarray_adaptor<EC, L, SC, Tag>::storage_impl() noexcept -> storage_type&
  567. {
  568. return m_storage;
  569. }
  570. template <class EC, layout_type L, class SC, class Tag>
  571. inline auto xarray_adaptor<EC, L, SC, Tag>::storage_impl() const noexcept -> const storage_type&
  572. {
  573. return m_storage;
  574. }
  575. template <class EC, layout_type L, class SC, class Tag>
  576. template <class P, class S>
  577. inline void xarray_adaptor<EC, L, SC, Tag>::reset_buffer(P&& pointer, S&& size)
  578. {
  579. return m_storage.reset_data(std::forward<P>(pointer), std::forward<S>(size));
  580. }
  581. }
  582. #endif