10#ifndef XTENSOR_ARRAY_HPP
11#define XTENSOR_ARRAY_HPP
14#include <initializer_list>
17#include <xtl/xsequence.hpp>
19#include "xbuffer_adaptor.hpp"
20#include "xcontainer.hpp"
21#include "xsemantic.hpp"
32 template <
class EC, layout_type L,
class SC,
class Tag>
35 template <
class EC, layout_type L,
class SC>
41 template <
class EC, layout_type L,
class SC,
class Tag>
45 template <
class EC, layout_type L,
class SC,
class Tag>
48 using storage_type = EC;
49 using reference = inner_reference_t<storage_type>;
50 using const_reference =
typename storage_type::const_reference;
51 using size_type =
typename storage_type::size_type;
52 using shape_type = SC;
53 using strides_type = get_strides_t<shape_type>;
54 using backstrides_type = get_strides_t<shape_type>;
55 using inner_shape_type = shape_type;
56 using inner_strides_type = strides_type;
57 using inner_backstrides_type = backstrides_type;
62 template <
class EC, layout_type L,
class SC,
class Tag>
81 template <
class EC, layout_type L,
class SC,
class Tag>
83 public xcontainer_semantic<xarray_container<EC, L, SC, Tag>>,
84 public extension::xarray_container_base_t<EC, L, SC, Tag>
89 using base_type = xstrided_container<self_type>;
90 using semantic_base = xcontainer_semantic<self_type>;
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;
123 template <
class S = shape_type>
134 template <std::
size_t N>
136 template <std::
size_t N>
147 storage_type m_storage;
149 storage_type& storage_impl() noexcept;
150 const storage_type& storage_impl() const noexcept;
161 template <
class EC, layout_type L,
class SC,
class Tag>
164 template <
class EC, layout_type L,
class SC>
170 template <
class EC, layout_type L,
class SC,
class Tag>
174 template <
class EC, layout_type L,
class SC,
class Tag>
177 using storage_type = std::remove_reference_t<EC>;
178 using reference = inner_reference_t<storage_type>;
179 using const_reference =
typename storage_type::const_reference;
180 using size_type =
typename storage_type::size_type;
181 using shape_type = SC;
182 using strides_type = get_strides_t<shape_type>;
183 using backstrides_type = get_strides_t<shape_type>;
184 using inner_shape_type = shape_type;
185 using inner_strides_type = strides_type;
186 using inner_backstrides_type = backstrides_type;
191 template <
class EC, layout_type L,
class SC,
class Tag>
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>
220 using container_closure_type = EC;
223 using base_type = xstrided_container<self_type>;
224 using semantic_base = xcontainer_semantic<self_type>;
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;
256 template <
class P,
class S>
257 void reset_buffer(P&& pointer, S&&
size);
261 container_closure_type m_storage;
263 storage_type& storage_impl() noexcept;
264 const storage_type& storage_impl() const noexcept;
280 template <class EC,
layout_type L, class SC, class Tag>
283 , m_storage(1, value_type())
293 template <
class EC, layout_type L,
class SC,
class Tag>
307 template <
class EC, layout_type L,
class SC,
class Tag>
309 const shape_type& shape,
310 const_reference value,
316 std::fill(m_storage.begin(), m_storage.end(), value);
324 template <
class EC, layout_type L,
class SC,
class Tag>
338 template <
class EC, layout_type L,
class SC,
class Tag>
340 const shape_type& shape,
342 const_reference value
347 std::fill(m_storage.begin(), m_storage.end(), value);
355 template <
class EC, layout_type L,
class SC,
class Tag>
360 nested_copy(m_storage.begin(), t);
370 template <
class EC, layout_type L,
class SC,
class Tag>
373 inner_shape_type&& shape,
376 : base_type(std::move(shape), std::move(
strides))
377 , m_storage(std::move(
storage))
391 template <
class EC, layout_type L,
class SC,
class Tag>
397 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->
template begin<tmp>(), t);
404 template <
class EC, layout_type L,
class SC,
class Tag>
410 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->
template begin<tmp>(), t);
417 template <
class EC, layout_type L,
class SC,
class Tag>
423 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->
template begin<tmp>(), t);
430 template <
class EC, layout_type L,
class SC,
class Tag>
436 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->
template begin<tmp>(), t);
443 template <
class EC, layout_type L,
class SC,
class Tag>
449 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->
template begin<tmp>(), t);
458 template <
class EC, layout_type L,
class SC,
class Tag>
462 shape_type
shape = xtl::forward_sequence<shape_type, S>(s);
463 return self_type(
shape);
466 template <
class EC, layout_type L,
class SC,
class Tag>
467 template <std::
size_t N>
470 inner_shape_type(rhs.shape().cbegin(), rhs.shape().cend()),
472 inner_backstrides_type(rhs.backstrides().cbegin(), rhs.backstrides().cend()),
473 std::move(rhs.layout())
475 , m_storage(std::move(rhs.storage()))
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)
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());
499 template <
class EC, layout_type L,
class SC,
class Tag>
508 detail::resize_data_container(m_storage, std::size_t(1));
510 semantic_base::assign(e);
516 template <
class EC, layout_type L,
class SC,
class Tag>
518 inline auto xarray_container<EC, L, SC, Tag>::operator=(
const xexpression<E>& e) -> self_type&
520 return semantic_base::operator=(e);
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&
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&
549 template <
class EC, layout_type L,
class SC,
class Tag>
552 , m_storage(std::move(
storage))
560 template <
class EC, layout_type L,
class SC,
class Tag>
574 template <
class EC, layout_type L,
class SC,
class Tag>
578 , m_storage(std::forward<D>(
storage))
590 template <
class EC, layout_type L,
class SC,
class Tag>
594 const shape_type& shape,
598 , m_storage(std::forward<D>(
storage))
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&
608 base_type::operator=(rhs);
609 m_storage = rhs.m_storage;
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&
616 base_type::operator=(std::move(rhs));
617 m_storage = rhs.m_storage;
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&
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());
638 template <
class EC, layout_type L,
class SC,
class Tag>
640 inline auto xarray_adaptor<EC, L, SC, Tag>::operator=(
const xexpression<E>& e) -> self_type&
642 return semantic_base::operator=(e);
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&
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&
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)
663 return m_storage.reset_data(std::forward<P>(pointer), std::forward<S>(size));
Dense multidimensional container adaptor with tensor semantic.
xarray_adaptor(D &&storage, const shape_type &shape, layout_type l=L)
Constructs an xarray_adaptor of the given stl-like container, with the specified shape and layout_typ...
xarray_adaptor(D &&storage, const shape_type &shape, const strides_type &strides)
Constructs an xarray_adaptor of the given stl-like container, with the specified shape and strides.
xarray_adaptor(const storage_type &storage)
Constructs an xarray_adaptor of the given stl-like container.
xarray_adaptor(storage_type &&storage)
Constructs an xarray_adaptor of the given stl-like container.
Dense multidimensional container with tensor semantic.
xarray_container(const shape_type &shape, const strides_type &strides, const_reference value)
Allocates an uninitialized xarray_container with the specified shape and strides.
xarray_container(const shape_type &shape, const strides_type &strides)
Allocates an uninitialized xarray_container with the specified shape and strides.
xarray_container(nested_initializer_list_t< value_type, 2 > t)
Allocates a two-dimensional xarray_container.
xarray_container(nested_initializer_list_t< value_type, 5 > t)
Allocates a five-dimensional xarray_container.
xarray_container(const shape_type &shape, layout_type l=L)
Allocates an uninitialized xarray_container with the specified shape and layout_type.
xarray_container(const shape_type &shape, const_reference value, layout_type l=L)
Allocates an xarray_container with the specified shape and layout_type.
xarray_container(const value_type &t)
Allocates an xarray_container that holds a single element initialized to the specified value.
xarray_container(nested_initializer_list_t< value_type, 1 > t)
Allocates a one-dimensional xarray_container.
xarray_container(storage_type &&storage, inner_shape_type &&shape, inner_strides_type &&strides)
Allocates an xarray_container by moving specified data, shape and strides.
xarray_container(nested_initializer_list_t< value_type, 3 > t)
Allocates a three-dimensional xarray_container.
xarray_container(nested_initializer_list_t< value_type, 4 > t)
Allocates a four-dimensional xarray_container.
xarray_container(const xexpression< E > &e)
The extended copy constructor.
xarray_container()
Allocates an uninitialized xarray_container that holds 0 element.
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 size_type dimension() const noexcept
Returns the number of dimensions of 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.
auto begin() noexcept -> select_iterator< L >
Base class for xexpressions.
derived_type & derived_cast() &noexcept
Returns a reference to the actual derived type of the xexpression.
void resize(S &&shape, bool force=false)
Dense multidimensional container with tensor semantic and fixed dimension.
auto strides(const E &e, stride_type type=stride_type::normal) noexcept
Get strides of an object.
standard mathematical functions for xexpressions