10#ifndef XTENSOR_TENSOR_HPP
11#define XTENSOR_TENSOR_HPP
19#include "xbuffer_adaptor.hpp"
20#include "xcontainer.hpp"
21#include "xsemantic.hpp"
32 template <
class EC, std::
size_t N, layout_type L,
class Tag>
35 template <
class EC, std::
size_t N, layout_type L>
41 template <
class EC, std::
size_t N, layout_type L,
class Tag>
45 template <
class EC, std::
size_t N, layout_type L,
class Tag>
50 using const_reference =
typename storage_type::const_reference;
51 using size_type =
typename storage_type::size_type;
52 using shape_type = std::array<typename storage_type::size_type, N>;
55 using inner_shape_type = shape_type;
62 template <
class EC, std::
size_t N, layout_type L,
class Tag>
82 template <
class EC, std::
size_t N, layout_type L,
class Tag>
85 public extension::xtensor_container_base_t<EC, N, L, Tag>
92 using extension_base = extension::xtensor_container_base_t<EC, N, L, Tag>;
93 using storage_type =
typename base_type::storage_type;
95 using value_type =
typename base_type::value_type;
96 using reference =
typename base_type::reference;
97 using const_reference =
typename base_type::const_reference;
98 using pointer =
typename base_type::pointer;
99 using const_pointer =
typename base_type::const_pointer;
100 using shape_type =
typename base_type::shape_type;
101 using inner_shape_type =
typename base_type::inner_shape_type;
102 using strides_type =
typename base_type::strides_type;
103 using backstrides_type =
typename base_type::backstrides_type;
104 using inner_backstrides_type =
typename base_type::inner_backstrides_type;
105 using inner_strides_type =
typename base_type::inner_strides_type;
106 using temporary_type =
typename semantic_base::temporary_type;
108 static constexpr std::size_t rank = N;
118 template <
class S = shape_type>
142 storage_type m_storage;
144 storage_type& storage_impl()
noexcept;
145 const storage_type& storage_impl()
const noexcept;
156 template <
class EC, std::
size_t N, layout_type L,
class Tag>
159 template <
class EC, std::
size_t N, layout_type L>
165 template <
class EC, std::
size_t N, layout_type L,
class Tag>
169 template <
class EC, std::
size_t N, layout_type L,
class Tag>
172 using storage_type = std::remove_reference_t<EC>;
174 using const_reference =
typename storage_type::const_reference;
175 using size_type =
typename storage_type::size_type;
176 using shape_type = std::array<typename storage_type::size_type, N>;
179 using inner_shape_type = shape_type;
186 template <
class EC, std::
size_t N, layout_type L,
class Tag>
208 template <
class EC, std::
size_t N, layout_type L,
class Tag>
211 public extension::xtensor_adaptor_base_t<EC, N, L, Tag>
220 using extension_base = extension::xtensor_adaptor_base_t<EC, N, L, Tag>;
221 using storage_type =
typename base_type::storage_type;
223 using shape_type =
typename base_type::shape_type;
224 using strides_type =
typename base_type::strides_type;
225 using backstrides_type =
typename base_type::backstrides_type;
226 using temporary_type =
typename semantic_base::temporary_type;
228 static constexpr std::size_t rank = N;
251 template <
class P,
class S>
252 void reset_buffer(
P&& pointer,
S&&
size);
258 storage_type& storage_impl()
noexcept;
259 const storage_type& storage_impl()
const noexcept;
268 template <
class EC, std::
size_t N, layout_type L,
class Tag>
273 template <
class EC, std::
size_t N, layout_type L,
class Tag>
276 template <
class EC, std::
size_t N, layout_type L>
282 template <
class EC, std::
size_t N, layout_type L,
class Tag>
286 template <
class EC, std::
size_t N, layout_type L,
class Tag>
289 using storage_type = std::remove_reference_t<EC>;
291 using const_reference =
typename storage_type::const_reference;
292 using size_type =
typename storage_type::size_type;
293 using shape_type = std::array<typename storage_type::size_type, N>;
296 using inner_shape_type = shape_type;
303 template <
class EC, std::
size_t N, layout_type L,
class Tag>
325 template <
class EC, std::
size_t N, layout_type L,
class Tag>
328 public extension::xtensor_view_base_t<EC, N, L, Tag>
337 using extension_base = extension::xtensor_adaptor_base_t<EC, N, L, Tag>;
338 using storage_type =
typename base_type::storage_type;
340 using shape_type =
typename base_type::shape_type;
341 using strides_type =
typename base_type::strides_type;
342 using backstrides_type =
typename base_type::backstrides_type;
343 using temporary_type =
typename semantic_base::temporary_type;
373 storage_type& storage_impl()
noexcept;
374 const storage_type& storage_impl()
const noexcept;
376 void assign_temporary_impl(temporary_type&&
tmp);
385 struct tensor_view_simd_helper
387 using valid_return_type = detail::has_simd_interface_impl<V, typename V::value_type>;
388 using valid_reference = std::is_lvalue_reference<typename V::reference>;
389 static constexpr bool value = valid_return_type::value && valid_reference::value;
390 using type = std::integral_constant<bool, value>;
398 template <
class EC, std::
size_t N, layout_type L,
class Tag>
400 : detail::tensor_view_simd_helper<xtensor_view<EC, N, L, Tag>>::type
415 template <
class EC, std::
size_t N, layout_type L,
class Tag>
418 , m_storage(N == 0 ? 1 : 0, value_type())
425 template <
class EC, std::
size_t N, layout_type L,
class Tag>
431 L ==
tmp ? nested_copy(m_storage.begin(),
t) : nested_copy(this->
template begin<tmp>(),
t);
440 template <
class EC, std::
size_t N, layout_type L,
class Tag>
454 template <
class EC, std::
size_t N, layout_type L,
class Tag>
456 const shape_type& shape,
457 const_reference value,
463 std::fill(m_storage.begin(), m_storage.end(), value);
471 template <
class EC, std::
size_t N, layout_type L,
class Tag>
485 template <
class EC, std::
size_t N, layout_type L,
class Tag>
487 const shape_type& shape,
489 const_reference value
494 std::fill(m_storage.begin(), m_storage.end(), value);
504 template <
class EC, std::
size_t N, layout_type L,
class Tag>
506 storage_type&& storage,
507 inner_shape_type&& shape,
511 , m_storage(std::
move(storage))
515 template <
class EC, std::
size_t N, layout_type L,
class Tag>
524 , m_storage(std::
move(
rhs.storage()))
528 template <
class EC, std::
size_t N, layout_type L,
class Tag>
530 inline xtensor_container<EC, N, L, Tag>&
531 xtensor_container<EC, N, L, Tag>::operator=(xarray_container<EC, L, SC, Tag>&& rhs)
533 XTENSOR_ASSERT_MSG(N == rhs.dimension(),
"Cannot change dimension of xtensor.");
534 std::copy(rhs.shape().begin(), rhs.shape().end(), this->shape_impl().begin());
535 std::copy(rhs.strides().cbegin(), rhs.strides().cend(), this->strides_impl().begin());
536 std::copy(rhs.backstrides().cbegin(), rhs.backstrides().cend(), this->backstrides_impl().begin());
537 this->mutable_layout() = std::move(rhs.layout());
538 m_storage = std::move(std::move(rhs.storage()));
542 template <
class EC, std::
size_t N, layout_type L,
class Tag>
544 inline xtensor_container<EC, N, L, Tag> xtensor_container<EC, N, L, Tag>::from_shape(S&& s)
546 XTENSOR_ASSERT_MSG(s.size() == N,
"Cannot change dimension of xtensor.");
547 shape_type shape = xtl::forward_sequence<shape_type, S>(s);
548 return self_type(shape);
560 template <
class EC, std::
size_t N, layout_type L,
class Tag>
565 XTENSOR_ASSERT_MSG(N ==
e.derived_cast().dimension(),
"Cannot change dimension of xtensor.");
568 if (
e.derived_cast().dimension() == 0)
570 detail::resize_data_container(m_storage, std::size_t(1));
572 semantic_base::assign(
e);
578 template <
class EC, std::
size_t N, layout_type L,
class Tag>
582 return semantic_base::operator=(
e);
587 template <
class EC, std::
size_t N, layout_type L,
class Tag>
593 template <
class EC, std::
size_t N, layout_type L,
class Tag>
594 inline auto xtensor_container<EC, N, L, Tag>::storage_impl() const noexcept -> const storage_type&
611 template <
class EC, std::
size_t N, layout_type L,
class Tag>
614 , m_storage(std::
move(storage))
622 template <
class EC, std::
size_t N, layout_type L,
class Tag>
636 template <
class EC, std::
size_t N, layout_type L,
class Tag>
640 , m_storage(std::
forward<
D>(storage))
652 template <
class EC, std::
size_t N, layout_type L,
class Tag>
656 const shape_type& shape,
660 , m_storage(std::
forward<
D>(storage))
667 template <
class EC, std::
size_t N, layout_type L,
class Tag>
670 base_type::operator=(
rhs);
671 m_storage =
rhs.m_storage;
675 template <
class EC, std::
size_t N, layout_type L,
class Tag>
676 inline auto xtensor_adaptor<EC, N, L, Tag>::operator=(xtensor_adaptor&& rhs) -> self_type&
678 base_type::operator=(std::move(rhs));
679 m_storage = rhs.m_storage;
683 template <
class EC, std::
size_t N, layout_type L,
class Tag>
684 inline auto xtensor_adaptor<EC, N, L, Tag>::operator=(temporary_type&& rhs) -> self_type&
686 base_type::shape_impl() = std::move(
const_cast<shape_type&
>(rhs.shape()));
687 base_type::strides_impl() = std::move(
const_cast<strides_type&
>(rhs.strides()));
688 base_type::backstrides_impl() = std::move(
const_cast<backstrides_type&
>(rhs.backstrides()));
689 m_storage = std::move(rhs.storage());
700 template <
class EC, std::
size_t N, layout_type L,
class Tag>
704 return semantic_base::operator=(
e);
709 template <
class EC, std::
size_t N, layout_type L,
class Tag>
715 template <
class EC, std::
size_t N, layout_type L,
class Tag>
716 inline auto xtensor_adaptor<EC, N, L, Tag>::storage_impl() const noexcept -> const storage_type&
721 template <
class EC, std::
size_t N, layout_type L,
class Tag>
722 template <
class P,
class S>
723 inline void xtensor_adaptor<EC, N, L, Tag>::reset_buffer(P&& pointer, S&& size)
725 return m_storage.reset_data(std::forward<P>(pointer), std::forward<S>(size));
740 template <
class EC, std::
size_t N, layout_type L,
class Tag>
743 , m_storage(std::
move(storage))
751 template <
class EC, std::
size_t N, layout_type L,
class Tag>
765 template <
class EC, std::
size_t N, layout_type L,
class Tag>
769 , m_storage(std::
forward<
D>(storage))
781 template <
class EC, std::
size_t N, layout_type L,
class Tag>
785 , m_storage(std::
forward<
D>(storage))
792 template <
class EC, std::
size_t N, layout_type L,
class Tag>
795 base_type::operator=(
rhs);
796 m_storage =
rhs.m_storage;
800 template <
class EC, std::
size_t N, layout_type L,
class Tag>
801 inline auto xtensor_view<EC, N, L, Tag>::operator=(xtensor_view&& rhs) -> self_type&
803 base_type::operator=(std::move(rhs));
804 m_storage = rhs.m_storage;
815 template <
class EC, std::
size_t N, layout_type L,
class Tag>
819 return semantic_base::operator=(
e);
824 template <
class EC, std::
size_t N, layout_type L,
class Tag>
828 std::fill(m_storage.begin(), m_storage.end(),
e);
832 template <
class EC, std::
size_t N, layout_type L,
class Tag>
833 inline auto xtensor_view<EC, N, L, Tag>::storage_impl() noexcept -> storage_type&
838 template <
class EC, std::
size_t N, layout_type L,
class Tag>
839 inline auto xtensor_view<EC, N, L, Tag>::storage_impl() const noexcept -> const storage_type&
844 template <
class EC, std::
size_t N, layout_type L,
class Tag>
845 inline void xtensor_view<EC, N, L, Tag>::assign_temporary_impl(temporary_type&& tmp)
847 std::copy(tmp.cbegin(), tmp.cend(), m_storage.begin());
861 using size_type =
typename return_type::size_type;
865 return return_type::from_shape({size_type(0), size_type(0)});
868 return_type
out = return_type::from_shape({idx.size(), idx[0].size()});
870 for (size_type
i = 0;
i <
out.shape()[0]; ++
i)
872 for (size_type
j = 0;
j <
out.shape()[1]; ++
j)
899 return_type
out = return_type::from_shape({
n});
904 [&
iter](
const auto&
t)
906 iter = std::copy(t.cbegin(), t.cend(), iter);
913 struct ravel_vector_tag;
914 struct ravel_tensor_tag;
918 template <
class C,
class Tag>
919 struct ravel_return_type;
922 struct ravel_return_type<C, ravel_vector_tag>
924 using index_type =
typename C::value_type;
925 using value_type =
typename index_type::value_type;
926 using type = std::vector<value_type>;
929 static std::vector<value_type> init(T n)
931 return std::vector<value_type>(n);
936 struct ravel_return_type<C, ravel_tensor_tag>
938 using index_type =
typename C::value_type;
939 using value_type =
typename index_type::value_type;
945 return xtensor<value_type, 1>::from_shape({n});
950 template <
class C,
class Tag>
951 using ravel_return_type_t =
typename detail::ravel_return_type<C, Tag>::type;
963 template <
class Tag = ravel_tensor_tag,
class C,
class S>
964 ravel_return_type_t<C, Tag>
967 using return_type =
typename detail::ravel_return_type<C, Tag>::type;
968 using value_type =
typename detail::ravel_return_type<C, Tag>::value_type;
970 strides_type
strides = xtl::make_sequence<strides_type>(shape.size(), 0);
972 return_type
out = detail::ravel_return_type<C, Tag>::init(idx.size());
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.
Dense multidimensional container adaptor with tensor semantics and fixed dimension.
xtensor_adaptor(storage_type &&storage)
Constructs an xtensor_adaptor of the given stl-like container.
Dense multidimensional container with tensor semantic and fixed dimension.
xtensor_container()
Allocates an uninitialized xtensor_container that holds 0 elements.
Dense multidimensional container adaptor with view semantics and fixed dimension.
xtensor_view(storage_type &&storage)
Constructs an xtensor_view of the given stl-like container.
Implementation of the xsemantic_base interface for multidimensional views.
std::size_t compute_strides(const shape_type &shape, layout_type l, strides_type &strides)
Compute the strides given the shape and the layout of an array.
auto strides(const E &e, stride_type type=stride_type::normal) noexcept
Get strides of an object.
standard mathematical functions for xexpressions
auto flatten_indices(const std::vector< T > &idx)
Converts std::vector<index_type> (returned e.g.
ravel_return_type_t< C, Tag > ravel_indices(const C &idx, const S &shape, layout_type l=layout_type::row_major)
Converts std::vector<index_type> (returned e.g.
auto from_indices(const std::vector< T > &idx)
Converts std::vector<index_type> (returned e.g.