xtensor
Loading...
Searching...
No Matches
xarray.hpp
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
10#ifndef XTENSOR_ARRAY_HPP
11#define XTENSOR_ARRAY_HPP
12
13#include <algorithm>
14#include <initializer_list>
15#include <utility>
16
17#include <xtl/xsequence.hpp>
18
19#include "xbuffer_adaptor.hpp"
20#include "xcontainer.hpp"
21#include "xsemantic.hpp"
22
23namespace xt
24{
25
26 /********************************
27 * xarray_container declaration *
28 ********************************/
29
30 namespace extension
31 {
32 template <class EC, layout_type L, class SC, class Tag>
34
35 template <class EC, layout_type L, class SC>
40
41 template <class EC, layout_type L, class SC, class Tag>
42 using xarray_container_base_t = typename xarray_container_base<EC, L, SC, Tag>::type;
43 }
44
45 template <class EC, layout_type L, class SC, class Tag>
47 {
48 using storage_type = EC;
50 using const_reference = typename storage_type::const_reference;
51 using size_type = typename storage_type::size_type;
52 using shape_type = SC;
59 static constexpr layout_type layout = L;
60 };
61
62 template <class EC, layout_type L, class SC, class Tag>
64 : xcontainer_iterable_types<xarray_container<EC, L, SC, Tag>>
65 {
66 };
67
81 template <class EC, layout_type L, class SC, class Tag>
82 class xarray_container : public xstrided_container<xarray_container<EC, L, SC, Tag>>,
83 public xcontainer_semantic<xarray_container<EC, L, SC, Tag>>,
84 public extension::xarray_container_base_t<EC, L, SC, Tag>
85 {
86 public:
87
91 using extension_base = extension::xarray_container_base_t<EC, L, SC, Tag>;
92 using storage_type = typename base_type::storage_type;
93 using allocator_type = typename base_type::allocator_type;
94 using value_type = typename base_type::value_type;
95 using reference = typename base_type::reference;
96 using const_reference = typename base_type::const_reference;
97 using pointer = typename base_type::pointer;
98 using const_pointer = typename base_type::const_pointer;
99 using shape_type = typename base_type::shape_type;
100 using inner_shape_type = typename base_type::inner_shape_type;
101 using strides_type = typename base_type::strides_type;
102 using backstrides_type = typename base_type::backstrides_type;
103 using inner_strides_type = typename base_type::inner_strides_type;
104 using inner_backstrides_type = typename base_type::inner_backstrides_type;
105 using temporary_type = typename semantic_base::temporary_type;
106 using expression_tag = Tag;
107 static constexpr std::size_t rank = SIZE_MAX;
108
110 explicit xarray_container(const shape_type& shape, layout_type l = L);
111 explicit xarray_container(const shape_type& shape, const_reference value, layout_type l = L);
112 explicit xarray_container(const shape_type& shape, const strides_type& strides);
113 explicit xarray_container(const shape_type& shape, const strides_type& strides, const_reference value);
114 explicit xarray_container(storage_type&& storage, inner_shape_type&& shape, inner_strides_type&& strides);
115
116 xarray_container(const value_type& t);
122
123 template <class S = shape_type>
124 static xarray_container from_shape(S&& s);
125
126 ~xarray_container() = default;
127
128 xarray_container(const xarray_container&) = default;
129 xarray_container& operator=(const xarray_container&) = default;
130
132 xarray_container& operator=(xarray_container&&) = default;
133
134 template <std::size_t N>
136 template <std::size_t N>
138
139 template <class E>
141
142 template <class E>
143 xarray_container& operator=(const xexpression<E>& e);
144
145 private:
146
147 storage_type m_storage;
148
149 storage_type& storage_impl() noexcept;
150 const storage_type& storage_impl() const noexcept;
151
152 friend class xcontainer<xarray_container<EC, L, SC, Tag>>;
153 };
154
155 /******************************
156 * xarray_adaptor declaration *
157 ******************************/
158
159 namespace extension
160 {
161 template <class EC, layout_type L, class SC, class Tag>
163
164 template <class EC, layout_type L, class SC>
169
170 template <class EC, layout_type L, class SC, class Tag>
171 using xarray_adaptor_base_t = typename xarray_adaptor_base<EC, L, SC, Tag>::type;
172 }
173
174 template <class EC, layout_type L, class SC, class Tag>
176 {
177 using storage_type = std::remove_reference_t<EC>;
179 using const_reference = typename storage_type::const_reference;
180 using size_type = typename storage_type::size_type;
181 using shape_type = SC;
188 static constexpr layout_type layout = L;
189 };
190
191 template <class EC, layout_type L, class SC, class Tag>
193 : xcontainer_iterable_types<xarray_adaptor<EC, L, SC, Tag>>
194 {
195 };
196
213 template <class EC, layout_type L, class SC, class Tag>
214 class xarray_adaptor : public xstrided_container<xarray_adaptor<EC, L, SC, Tag>>,
215 public xcontainer_semantic<xarray_adaptor<EC, L, SC, Tag>>,
216 public extension::xarray_adaptor_base_t<EC, L, SC, Tag>
217 {
218 public:
219
221
225 using extension_base = extension::xarray_adaptor_base_t<EC, L, SC, Tag>;
226 using storage_type = typename base_type::storage_type;
227 using allocator_type = typename base_type::allocator_type;
228 using shape_type = typename base_type::shape_type;
229 using strides_type = typename base_type::strides_type;
230 using backstrides_type = typename base_type::backstrides_type;
231 using temporary_type = typename semantic_base::temporary_type;
232 using expression_tag = Tag;
233 static constexpr std::size_t rank = SIZE_MAX;
234
235 xarray_adaptor(storage_type&& storage);
236 xarray_adaptor(const storage_type& storage);
237
238 template <class D>
239 xarray_adaptor(D&& storage, const shape_type& shape, layout_type l = L);
240
241 template <class D>
242 xarray_adaptor(D&& storage, const shape_type& shape, const strides_type& strides);
243
244 ~xarray_adaptor() = default;
245
246 xarray_adaptor(const xarray_adaptor&) = default;
247 xarray_adaptor& operator=(const xarray_adaptor&);
248
249 xarray_adaptor(xarray_adaptor&&) = default;
250 xarray_adaptor& operator=(xarray_adaptor&&);
251 xarray_adaptor& operator=(temporary_type&&);
252
253 template <class E>
254 xarray_adaptor& operator=(const xexpression<E>& e);
255
256 template <class P, class S>
257 void reset_buffer(P&& pointer, S&& size);
258
259 private:
260
261 container_closure_type m_storage;
262
263 storage_type& storage_impl() noexcept;
264 const storage_type& storage_impl() const noexcept;
265
266 friend class xcontainer<xarray_adaptor<EC, L, SC, Tag>>;
267 };
268
269 /***********************************
270 * xarray_container implementation *
271 ***********************************/
272
280 template <class EC, layout_type L, class SC, class Tag>
282 : base_type()
283 , m_storage(1, value_type())
284 {
285 }
286
293 template <class EC, layout_type L, class SC, class Tag>
295 : base_type()
296 {
298 }
299
307 template <class EC, layout_type L, class SC, class Tag>
309 const shape_type& shape,
310 const_reference value,
312 )
313 : base_type()
314 {
316 std::fill(m_storage.begin(), m_storage.end(), value);
317 }
318
324 template <class EC, layout_type L, class SC, class Tag>
325 inline xarray_container<EC, L, SC, Tag>::xarray_container(const shape_type& shape, const strides_type& strides)
326 : base_type()
327 {
329 }
330
338 template <class EC, layout_type L, class SC, class Tag>
340 const shape_type& shape,
341 const strides_type& strides,
342 const_reference value
343 )
344 : base_type()
345 {
347 std::fill(m_storage.begin(), m_storage.end(), value);
348 }
349
355 template <class EC, layout_type L, class SC, class Tag>
357 : base_type()
358 {
360 nested_copy(m_storage.begin(), t);
361 }
362
370 template <class EC, layout_type L, class SC, class Tag>
372 storage_type&& storage,
373 inner_shape_type&& shape,
374 inner_strides_type&& strides
375 )
376 : base_type(std::move(shape), std::move(strides))
377 , m_storage(std::move(storage))
378 {
379 }
380
382
391 template <class EC, layout_type L, class SC, class Tag>
393 : base_type()
394 {
396 constexpr auto tmp = layout_type::row_major;
397 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
398 }
399
404 template <class EC, layout_type L, class SC, class Tag>
406 : base_type()
407 {
409 constexpr auto tmp = layout_type::row_major;
410 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
411 }
412
417 template <class EC, layout_type L, class SC, class Tag>
419 : base_type()
420 {
422 constexpr auto tmp = layout_type::row_major;
423 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
424 }
425
430 template <class EC, layout_type L, class SC, class Tag>
432 : base_type()
433 {
435 constexpr auto tmp = layout_type::row_major;
436 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
437 }
438
443 template <class EC, layout_type L, class SC, class Tag>
445 : base_type()
446 {
448 constexpr auto tmp = layout_type::row_major;
449 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
450 }
451
453
458 template <class EC, layout_type L, class SC, class Tag>
459 template <class S>
461 {
462 shape_type shape = xtl::forward_sequence<shape_type, S>(s);
463 return self_type(shape);
464 }
465
466 template <class EC, layout_type L, class SC, class Tag>
467 template <std::size_t N>
469 : base_type(
470 inner_shape_type(rhs.shape().cbegin(), rhs.shape().cend()),
471 inner_strides_type(rhs.strides().cbegin(), rhs.strides().cend()),
472 inner_backstrides_type(rhs.backstrides().cbegin(), rhs.backstrides().cend()),
473 std::move(rhs.layout())
474 )
475 , m_storage(std::move(rhs.storage()))
476 {
477 }
478
479 template <class EC, layout_type L, class SC, class Tag>
480 template <std::size_t N>
481 inline xarray_container<EC, L, SC, Tag>&
482 xarray_container<EC, L, SC, Tag>::operator=(xtensor_container<EC, N, L, Tag>&& rhs)
483 {
484 this->shape_impl().assign(rhs.shape().cbegin(), rhs.shape().cend());
485 this->strides_impl().assign(rhs.strides().cbegin(), rhs.strides().cend());
486 this->backstrides_impl().assign(rhs.backstrides().cbegin(), rhs.backstrides().cend());
487 this->mutable_layout() = rhs.layout();
488 m_storage = std::move(rhs.storage());
489 return *this;
490 }
491
499 template <class EC, layout_type L, class SC, class Tag>
500 template <class E>
502 : base_type()
503 {
504 // Avoids unintialized data because of (m_shape == shape) condition
505 // in resize (called by assign), which is always true when dimension == 0.
506 if (e.derived_cast().dimension() == 0)
507 {
508 detail::resize_data_container(m_storage, std::size_t(1));
509 }
510 semantic_base::assign(e);
511 }
512
516 template <class EC, layout_type L, class SC, class Tag>
517 template <class E>
519 {
520 return semantic_base::operator=(e);
521 }
522
524
525 template <class EC, layout_type L, class SC, class Tag>
526 inline auto xarray_container<EC, L, SC, Tag>::storage_impl() noexcept -> storage_type&
527 {
528 return m_storage;
529 }
530
531 template <class EC, layout_type L, class SC, class Tag>
532 inline auto xarray_container<EC, L, SC, Tag>::storage_impl() const noexcept -> const storage_type&
533 {
534 return m_storage;
535 }
536
537 /******************
538 * xarray_adaptor *
539 ******************/
540
549 template <class EC, layout_type L, class SC, class Tag>
551 : base_type()
552 , m_storage(std::move(storage))
553 {
554 }
555
560 template <class EC, layout_type L, class SC, class Tag>
561 inline xarray_adaptor<EC, L, SC, Tag>::xarray_adaptor(const storage_type& storage)
562 : base_type()
563 , m_storage(storage)
564 {
565 }
566
574 template <class EC, layout_type L, class SC, class Tag>
575 template <class D>
576 inline xarray_adaptor<EC, L, SC, Tag>::xarray_adaptor(D&& storage, const shape_type& shape, layout_type l)
577 : base_type()
578 , m_storage(std::forward<D>(storage))
579 {
581 }
582
590 template <class EC, layout_type L, class SC, class Tag>
591 template <class D>
593 D&& storage,
594 const shape_type& shape,
595 const strides_type& strides
596 )
597 : base_type()
598 , m_storage(std::forward<D>(storage))
599 {
601 }
602
604
605 template <class EC, layout_type L, class SC, class Tag>
606 inline auto xarray_adaptor<EC, L, SC, Tag>::operator=(const xarray_adaptor& rhs) -> self_type&
607 {
608 base_type::operator=(rhs);
609 m_storage = rhs.m_storage;
610 return *this;
611 }
612
613 template <class EC, layout_type L, class SC, class Tag>
614 inline auto xarray_adaptor<EC, L, SC, Tag>::operator=(xarray_adaptor&& rhs) -> self_type&
615 {
616 base_type::operator=(std::move(rhs));
617 m_storage = rhs.m_storage;
618 return *this;
619 }
620
621 template <class EC, layout_type L, class SC, class Tag>
622 inline auto xarray_adaptor<EC, L, SC, Tag>::operator=(temporary_type&& rhs) -> self_type&
623 {
624 base_type::shape_impl() = std::move(const_cast<shape_type&>(rhs.shape()));
625 base_type::strides_impl() = std::move(const_cast<strides_type&>(rhs.strides()));
626 base_type::backstrides_impl() = std::move(const_cast<backstrides_type&>(rhs.backstrides()));
627 m_storage = std::move(rhs.storage());
628 return *this;
629 }
630
638 template <class EC, layout_type L, class SC, class Tag>
639 template <class E>
641 {
642 return semantic_base::operator=(e);
643 }
644
646
647 template <class EC, layout_type L, class SC, class Tag>
648 inline auto xarray_adaptor<EC, L, SC, Tag>::storage_impl() noexcept -> storage_type&
649 {
650 return m_storage;
651 }
652
653 template <class EC, layout_type L, class SC, class Tag>
654 inline auto xarray_adaptor<EC, L, SC, Tag>::storage_impl() const noexcept -> const storage_type&
655 {
656 return m_storage;
657 }
658
659 template <class EC, layout_type L, class SC, class Tag>
660 template <class P, class S>
661 inline void xarray_adaptor<EC, L, SC, Tag>::reset_buffer(P&& pointer, S&& size)
662 {
663 return m_storage.reset_data(std::forward<P>(pointer), std::forward<S>(size));
664 }
665}
666
667#endif
Dense multidimensional container adaptor with tensor semantic.
Definition xarray.hpp:217
xarray_adaptor(storage_type &&storage)
Constructs an xarray_adaptor of the given stl-like container.
Definition xarray.hpp:550
Dense multidimensional container with tensor semantic.
Definition xarray.hpp:85
xarray_container()
Allocates an uninitialized xarray_container that holds 0 element.
Definition xarray.hpp:281
Implementation of the xsemantic_base interface for dense multidimensional containers.
Base class for dense multidimensional containers.
storage_type & storage() noexcept
Returns a reference to the buffer containing the elements of the container.
size_type size() const noexcept
Returns the number of element in the container.
constexpr const inner_strides_type & strides() const noexcept
Returns the strides of the container.
constexpr const inner_shape_type & shape() const noexcept
Returns the shape of the container.
Partial implementation of xcontainer that embeds the strides and the shape.
void resize(S &&shape, bool force=false)
Resizes the container.
auto strides(const E &e, stride_type type=stride_type::normal) noexcept
Get strides of an object.
Definition xstrides.hpp:248
standard mathematical functions for xexpressions
layout_type
Definition xlayout.hpp:24