10#ifndef XTENSOR_SCALAR_HPP
11#define XTENSOR_SCALAR_HPP
17#include <xtl/xtype_traits.hpp>
19#include "xaccessible.hpp"
20#include "xexpression.hpp"
21#include "xiterable.hpp"
23#include "xtensor_simd.hpp"
34 template <
class Tag,
class CT>
60 template <
bool is_const,
class CT>
63 template <
bool is_const,
class CT>
69 using value_type = std::decay_t<CT>;
70 using inner_shape_type = std::array<std::size_t, 0>;
71 using shape_type = inner_shape_type;
79 using value_type = std::decay_t<CT>;
80 using reference = value_type&;
81 using const_reference =
const value_type&;
82 using size_type = std::size_t;
89 public extension::xscalar_base_t<CT>
94 using xexpression_type = std::decay_t<CT>;
95 using extension_base = extension::xscalar_base_t<CT>;
97 using expression_tag =
typename extension_base::expression_tag;
100 using value_type =
typename inner_types::value_type;
101 using reference =
typename inner_types::reference;
102 using const_reference =
typename inner_types::const_reference;
103 using pointer = value_type*;
104 using const_pointer =
const value_type*;
105 using size_type =
typename inner_types::size_type;
106 using difference_type = std::ptrdiff_t;
107 using simd_value_type = xt_simd::simd_type<value_type>;
111 using inner_shape_type =
typename iterable_base::inner_shape_type;
112 using shape_type = inner_shape_type;
114 using stepper =
typename iterable_base::stepper;
115 using const_stepper =
typename iterable_base::const_stepper;
117 template <layout_type L>
119 template <layout_type L>
122 template <layout_type L>
124 template <layout_type L>
127 template <
class S, layout_type L>
129 template <
class S, layout_type L>
132 template <
class S, layout_type L>
134 template <
class S, layout_type L>
137 using iterator = value_type*;
138 using const_iterator =
const value_type*;
139 using reverse_iterator = std::reverse_iterator<iterator>;
140 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
146 static constexpr bool contiguous_layout =
true;
151 operator value_type&()
noexcept;
152 operator const value_type&()
const noexcept;
154 size_type size()
const noexcept;
155 const shape_type& shape()
const noexcept;
156 size_type shape(size_type
i)
const noexcept;
158 bool is_contiguous()
const noexcept;
162 template <
class...
Args>
163 reference operator()(
Args...)
noexcept;
164 template <
class...
Args>
165 reference unchecked(
Args...)
noexcept;
167 template <
class...
Args>
168 const_reference operator()(
Args...)
const noexcept;
169 template <
class...
Args>
170 const_reference unchecked(
Args...)
const noexcept;
172 using accessible_base::at;
173 using accessible_base::operator[];
177 using accessible_base::periodic;
180 reference element(
It,
It)
noexcept;
183 const_reference element(
It,
It)
const noexcept;
185 xexpression_type& expression()
noexcept;
186 const xexpression_type& expression()
const noexcept;
189 bool broadcast_shape(
S& shape,
bool reuse_cache =
false)
const noexcept;
192 bool has_linear_assign(
const S&
strides)
const noexcept;
194 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
195 iterator begin()
noexcept;
196 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
197 iterator end()
noexcept;
199 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
200 const_iterator begin()
const noexcept;
201 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
202 const_iterator end()
const noexcept;
203 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
204 const_iterator cbegin()
const noexcept;
205 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
206 const_iterator cend()
const noexcept;
208 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
209 reverse_iterator rbegin()
noexcept;
210 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
211 reverse_iterator rend()
noexcept;
213 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
214 const_reverse_iterator rbegin()
const noexcept;
215 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
216 const_reverse_iterator rend()
const noexcept;
217 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
218 const_reverse_iterator crbegin()
const noexcept;
219 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
220 const_reverse_iterator crend()
const noexcept;
222 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
224 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
227 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
229 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
231 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
233 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
237 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
239 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
242 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
244 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
246 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
248 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
251 iterator linear_begin()
noexcept;
252 iterator linear_end()
noexcept;
254 const_iterator linear_begin()
const noexcept;
255 const_iterator linear_end()
const noexcept;
256 const_iterator linear_cbegin()
const noexcept;
257 const_iterator linear_cend()
const noexcept;
259 reverse_iterator linear_rbegin()
noexcept;
260 reverse_iterator linear_rend()
noexcept;
262 const_reverse_iterator linear_rbegin()
const noexcept;
263 const_reverse_iterator linear_rend()
const noexcept;
264 const_reverse_iterator linear_crbegin()
const noexcept;
265 const_reverse_iterator linear_crend()
const noexcept;
268 stepper stepper_begin(
const S& shape)
noexcept;
273 const_stepper stepper_begin(
const S& shape)
const noexcept;
275 const_stepper stepper_end(
const S& shape,
layout_type l)
const noexcept;
283 reference data_element(size_type
i)
noexcept;
284 const_reference data_element(size_type
i)
const noexcept;
286 reference flat(size_type
i)
noexcept;
287 const_reference flat(size_type
i)
const noexcept;
289 template <
class align,
class simd = simd_value_type>
290 void store_simd(size_type
i,
const simd&
e);
292 xt_simd::simd_return_type<value_type, requested_type> load_simd(size_type
i)
const;
307 struct is_xscalar_impl : std::false_type
312 struct is_xscalar_impl<xscalar<E>> : std::true_type
318 using is_xscalar = detail::is_xscalar_impl<E>;
322 template <
class... E>
333 template <
class... E>
334 using all_xscalar = detail::all_xscalar<E...>;
341 xscalar<T&> xref(T& t);
344 xscalar<const T&> xcref(T& t);
350 template <
bool is_const,
class CT>
356 using storage_type = std::conditional_t<is_const, const xscalar<CT>,
xscalar<CT>>;
358 using value_type =
typename storage_type::value_type;
359 using reference = std::
360 conditional_t<is_const, typename storage_type::const_reference, typename storage_type::reference>;
361 using pointer = std::conditional_t<is_const, typename storage_type::const_pointer, typename storage_type::pointer>;
362 using size_type =
typename storage_type::size_type;
363 using difference_type =
typename storage_type::difference_type;
364 using shape_type =
typename storage_type::shape_type;
366 template <
class requested_type>
367 using simd_return_type = xt_simd::simd_return_type<value_type, requested_type>;
371 reference operator*()
const noexcept;
373 void step(size_type
dim, size_type
n = 1)
noexcept;
374 void step_back(size_type
dim, size_type
n = 1)
noexcept;
375 void reset(size_type
dim)
noexcept;
376 void reset_back(size_type
dim)
noexcept;
378 void to_begin()
noexcept;
397 template <
bool is_const,
class CT>
398 using dummy_reference_t = std::
399 conditional_t<is_const, typename xscalar<CT>::const_reference,
typename xscalar<CT>::reference>;
401 template <
bool is_const,
class CT>
402 using dummy_pointer_t = std::
403 conditional_t<is_const, typename xscalar<CT>::const_pointer,
typename xscalar<CT>::pointer>;
406 template <
bool is_const,
class CT>
408 xdummy_iterator<is_const, CT>,
409 typename xscalar<CT>::value_type,
410 typename xscalar<CT>::difference_type,
411 detail::dummy_pointer_t<is_const, CT>,
412 detail::dummy_reference_t<is_const, CT>>
417 using storage_type = std::conditional_t<is_const, const xscalar<CT>,
xscalar<CT>>;
419 using value_type =
typename storage_type::value_type;
420 using reference = detail::dummy_reference_t<is_const, CT>;
421 using pointer = detail::dummy_pointer_t<is_const, CT>;
422 using difference_type =
typename storage_type::difference_type;
423 using iterator_category = std::random_access_iterator_tag;
430 self_type& operator+=(difference_type
n)
noexcept;
431 self_type& operator-=(difference_type
n)
noexcept;
433 difference_type operator-(
const self_type&
rhs)
const noexcept;
435 reference operator*()
const noexcept;
445 template <
bool is_const,
class CT>
449 template <
bool is_const,
class CT>
457 template <
bool is_const,
class CT>
467 XTENSOR_CONSTEXPR_RETURN
auto linear_begin(
xscalar<CT>&
c)
noexcept ->
decltype(
c.dummy_begin())
469 return c.dummy_begin();
473 XTENSOR_CONSTEXPR_RETURN
auto linear_end(xscalar<CT>& c)
noexcept ->
decltype(c.dummy_end())
475 return c.dummy_end();
479 XTENSOR_CONSTEXPR_RETURN
auto linear_begin(
const xscalar<CT>& c)
noexcept ->
decltype(c.dummy_begin())
481 return c.dummy_begin();
485 XTENSOR_CONSTEXPR_RETURN
auto linear_end(
const xscalar<CT>& c)
noexcept ->
decltype(c.dummy_end())
487 return c.dummy_end();
496 inline xscalar<CT>::xscalar() noexcept
502 inline xscalar<CT>::xscalar(CT value) noexcept
508 inline xscalar<CT>::operator value_type&()
noexcept
514 inline xscalar<CT>::operator
const value_type&()
const noexcept
520 inline auto xscalar<CT>::size() const noexcept -> size_type
526 inline auto xscalar<CT>::shape() const noexcept -> const shape_type&
528 static std::array<size_type, 0> zero_shape;
533 inline auto xscalar<CT>::shape(size_type)
const noexcept -> size_type
539 inline layout_type xscalar<CT>::layout() const noexcept
541 return static_layout;
545 inline bool xscalar<CT>::is_contiguous() const noexcept
551 template <
class... Args>
552 inline auto xscalar<CT>::operator()(Args...) noexcept -> reference
554 XTENSOR_CHECK_DIMENSION((std::array<int, 0>()), Args()...);
559 template <
class... Args>
560 inline auto xscalar<CT>::unchecked(Args...) noexcept -> reference
566 template <
class... Args>
567 inline auto xscalar<CT>::operator()(Args...) const noexcept -> const_reference
569 XTENSOR_CHECK_DIMENSION((std::array<int, 0>()), Args()...);
574 template <
class... Args>
575 inline auto xscalar<CT>::unchecked(Args...) const noexcept -> const_reference
582 inline auto xscalar<CT>::element(It, It)
noexcept -> reference
589 inline auto xscalar<CT>::element(It, It)
const noexcept -> const_reference
595 inline auto xscalar<CT>::expression() noexcept -> xexpression_type&
601 inline auto xscalar<CT>::expression() const noexcept -> const xexpression_type&
608 inline bool xscalar<CT>::broadcast_shape(S&,
bool)
const noexcept
615 inline bool xscalar<CT>::has_linear_assign(
const S&)
const noexcept
621 template <layout_type L>
622 inline auto xscalar<CT>::begin() noexcept -> iterator
628 template <layout_type L>
629 inline auto xscalar<CT>::end() noexcept -> iterator
635 template <layout_type L>
636 inline auto xscalar<CT>::begin() const noexcept -> const_iterator
642 template <layout_type L>
643 inline auto xscalar<CT>::end() const noexcept -> const_iterator
649 template <layout_type L>
650 inline auto xscalar<CT>::cbegin() const noexcept -> const_iterator
656 template <layout_type L>
657 inline auto xscalar<CT>::cend() const noexcept -> const_iterator
663 template <layout_type L>
664 inline auto xscalar<CT>::rbegin() noexcept -> reverse_iterator
666 return reverse_iterator(end());
670 template <layout_type L>
671 inline auto xscalar<CT>::rend() noexcept -> reverse_iterator
673 return reverse_iterator(begin());
677 template <layout_type L>
678 inline auto xscalar<CT>::rbegin() const noexcept -> const_reverse_iterator
684 template <layout_type L>
685 inline auto xscalar<CT>::rend() const noexcept -> const_reverse_iterator
691 template <layout_type L>
692 inline auto xscalar<CT>::crbegin() const noexcept -> const_reverse_iterator
694 return const_reverse_iterator(cend());
698 template <layout_type L>
699 inline auto xscalar<CT>::crend() const noexcept -> const_reverse_iterator
701 return const_reverse_iterator(cbegin());
709 template <
class S, layout_type L>
710 inline auto xscalar<CT>::begin(
const S& shape)
noexcept -> broadcast_iterator<S, L>
712 return iterable_base::template begin<S, L>(shape);
716 template <
class S, layout_type L>
717 inline auto xscalar<CT>::end(
const S& shape)
noexcept -> broadcast_iterator<S, L>
719 return iterable_base::template end<S, L>(shape);
723 template <
class S, layout_type L>
724 inline auto xscalar<CT>::begin(
const S& shape)
const noexcept -> const_broadcast_iterator<S, L>
726 return iterable_base::template begin<S, L>(shape);
730 template <
class S, layout_type L>
731 inline auto xscalar<CT>::end(
const S& shape)
const noexcept -> const_broadcast_iterator<S, L>
733 return iterable_base::template end<S, L>(shape);
737 template <
class S, layout_type L>
738 inline auto xscalar<CT>::cbegin(
const S& shape)
const noexcept -> const_broadcast_iterator<S, L>
740 return iterable_base::template cbegin<S, L>(shape);
744 template <
class S, layout_type L>
745 inline auto xscalar<CT>::cend(
const S& shape)
const noexcept -> const_broadcast_iterator<S, L>
747 return iterable_base::template cend<S, L>(shape);
751 template <
class S, layout_type L>
752 inline auto xscalar<CT>::rbegin(
const S& shape)
noexcept -> reverse_broadcast_iterator<S, L>
754 return iterable_base::template rbegin<S, L>(shape);
758 template <
class S, layout_type L>
759 inline auto xscalar<CT>::rend(
const S& shape)
noexcept -> reverse_broadcast_iterator<S, L>
761 return iterable_base::template rend<S, L>(shape);
765 template <
class S, layout_type L>
766 inline auto xscalar<CT>::rbegin(
const S& shape)
const noexcept -> const_reverse_broadcast_iterator<S, L>
768 return iterable_base::template rbegin<S, L>(shape);
772 template <
class S, layout_type L>
773 inline auto xscalar<CT>::rend(
const S& shape)
const noexcept -> const_reverse_broadcast_iterator<S, L>
775 return iterable_base::template rend<S, L>(shape);
779 template <
class S, layout_type L>
780 inline auto xscalar<CT>::crbegin(
const S& shape)
const noexcept -> const_reverse_broadcast_iterator<S, L>
782 return iterable_base::template crbegin<S, L>(shape);
786 template <
class S, layout_type L>
787 inline auto xscalar<CT>::crend(
const S& shape)
const noexcept -> const_reverse_broadcast_iterator<S, L>
789 return iterable_base::template crend<S, L>(shape);
793 inline auto xscalar<CT>::linear_begin() noexcept -> iterator
795 return this->
template begin<XTENSOR_DEFAULT_LAYOUT>();
799 inline auto xscalar<CT>::linear_end() noexcept -> iterator
801 return this->
template end<XTENSOR_DEFAULT_LAYOUT>();
805 inline auto xscalar<CT>::linear_begin() const noexcept -> const_iterator
807 return this->
template begin<XTENSOR_DEFAULT_LAYOUT>();
811 inline auto xscalar<CT>::linear_end() const noexcept -> const_iterator
813 return this->
template end<XTENSOR_DEFAULT_LAYOUT>();
817 inline auto xscalar<CT>::linear_cbegin() const noexcept -> const_iterator
819 return this->
template cbegin<XTENSOR_DEFAULT_LAYOUT>();
823 inline auto xscalar<CT>::linear_cend() const noexcept -> const_iterator
825 return this->
template cend<XTENSOR_DEFAULT_LAYOUT>();
829 inline auto xscalar<CT>::linear_rbegin() noexcept -> reverse_iterator
831 return this->
template rbegin<XTENSOR_DEFAULT_LAYOUT>();
835 inline auto xscalar<CT>::linear_rend() noexcept -> reverse_iterator
837 return this->
template rend<XTENSOR_DEFAULT_LAYOUT>();
841 inline auto xscalar<CT>::linear_rbegin() const noexcept -> const_reverse_iterator
843 return this->
template rbegin<XTENSOR_DEFAULT_LAYOUT>();
847 inline auto xscalar<CT>::linear_rend() const noexcept -> const_reverse_iterator
849 return this->
template rend<XTENSOR_DEFAULT_LAYOUT>();
853 inline auto xscalar<CT>::linear_crbegin() const noexcept -> const_reverse_iterator
855 return this->
template crbegin<XTENSOR_DEFAULT_LAYOUT>();
859 inline auto xscalar<CT>::linear_crend() const noexcept -> const_reverse_iterator
861 return this->
template crend<XTENSOR_DEFAULT_LAYOUT>();
866 inline auto xscalar<CT>::stepper_begin(
const S&)
noexcept -> stepper
868 return stepper(
this,
false);
873 inline auto xscalar<CT>::stepper_end(
const S&,
layout_type)
noexcept -> stepper
875 return stepper(
this);
880 inline auto xscalar<CT>::stepper_begin(
const S&)
const noexcept -> const_stepper
882 return const_stepper(
this);
887 inline auto xscalar<CT>::stepper_end(
const S&,
layout_type)
const noexcept -> const_stepper
889 return const_stepper(
this);
893 inline auto xscalar<CT>::dummy_begin() noexcept -> dummy_iterator
895 return dummy_iterator(
this);
899 inline auto xscalar<CT>::dummy_end() noexcept -> dummy_iterator
901 return dummy_iterator(
this);
905 inline auto xscalar<CT>::dummy_begin() const noexcept -> const_dummy_iterator
907 return const_dummy_iterator(
this);
911 inline auto xscalar<CT>::dummy_end() const noexcept -> const_dummy_iterator
913 return const_dummy_iterator(
this);
917 inline auto xscalar<CT>::data_element(size_type)
noexcept -> reference
923 inline auto xscalar<CT>::data_element(size_type)
const noexcept -> const_reference
929 inline auto xscalar<CT>::flat(size_type)
noexcept -> reference
935 inline auto xscalar<CT>::flat(size_type)
const noexcept -> const_reference
941 template <
class align,
class simd>
942 inline void xscalar<CT>::store_simd(size_type,
const simd& e)
944 m_value =
static_cast<value_type
>(e[0]);
948 template <
class align,
class requested_type, std::
size_t N>
949 inline auto xscalar<CT>::load_simd(size_type)
const
950 -> xt_simd::simd_return_type<value_type, requested_type>
952 return xt_simd::broadcast_as<requested_type>(m_value);
956 inline xscalar<T&> xref(T& t)
958 return xscalar<T&>(t);
962 inline xscalar<const T&> xcref(T& t)
964 return xscalar<const T&>(t);
971 template <
bool is_const,
class CT>
972 inline xscalar_stepper<is_const, CT>::xscalar_stepper(storage_type* c) noexcept
977 template <
bool is_const,
class CT>
978 inline auto xscalar_stepper<is_const, CT>::operator*() const noexcept -> reference
980 return p_c->operator()();
983 template <
bool is_const,
class CT>
984 inline void xscalar_stepper<is_const, CT>::step(size_type , size_type )
noexcept
988 template <
bool is_const,
class CT>
989 inline void xscalar_stepper<is_const, CT>::step_back(size_type , size_type )
noexcept
993 template <
bool is_const,
class CT>
994 inline void xscalar_stepper<is_const, CT>::reset(size_type )
noexcept
998 template <
bool is_const,
class CT>
999 inline void xscalar_stepper<is_const, CT>::reset_back(size_type )
noexcept
1003 template <
bool is_const,
class CT>
1004 inline void xscalar_stepper<is_const, CT>::to_begin() noexcept
1008 template <
bool is_const,
class CT>
1009 inline void xscalar_stepper<is_const, CT>::to_end(
layout_type )
noexcept
1013 template <
bool is_const,
class CT>
1015 inline auto xscalar_stepper<is_const, CT>::step_simd() -> simd_return_type<T>
1017 return simd_return_type<T>(p_c->operator()());
1020 template <
bool is_const,
class CT>
1021 inline void xscalar_stepper<is_const, CT>::step_leading()
1029 template <
bool is_const,
class CT>
1030 inline xdummy_iterator<is_const, CT>::xdummy_iterator(storage_type* c) noexcept
1035 template <
bool is_const,
class CT>
1036 inline auto xdummy_iterator<is_const, CT>::operator++() noexcept -> self_type&
1041 template <
bool is_const,
class CT>
1042 inline auto xdummy_iterator<is_const, CT>::operator--() noexcept -> self_type&
1047 template <
bool is_const,
class CT>
1048 inline auto xdummy_iterator<is_const, CT>::operator+=(difference_type)
noexcept -> self_type&
1053 template <
bool is_const,
class CT>
1054 inline auto xdummy_iterator<is_const, CT>::operator-=(difference_type)
noexcept -> self_type&
1059 template <
bool is_const,
class CT>
1060 inline auto xdummy_iterator<is_const, CT>::operator-(
const self_type&)
const noexcept -> difference_type
1065 template <
bool is_const,
class CT>
1066 inline auto xdummy_iterator<is_const, CT>::operator*() const noexcept -> reference
1068 return p_c->operator()();
1071 template <
bool is_const,
class CT>
1072 inline bool xdummy_iterator<is_const, CT>::equal(
const self_type& rhs)
const noexcept
1074 return p_c == rhs.p_c;
1077 template <
bool is_const,
class CT>
1078 inline bool xdummy_iterator<is_const, CT>::less_than(
const self_type& rhs)
const noexcept
1080 return p_c < rhs.p_c;
1083 template <
bool is_const,
class CT>
1085 operator==(
const xdummy_iterator<is_const, CT>& lhs,
const xdummy_iterator<is_const, CT>& rhs)
noexcept
1087 return lhs.equal(rhs);
1090 template <
bool is_const,
class CT>
1092 operator<(
const xdummy_iterator<is_const, CT>& lhs,
const xdummy_iterator<is_const, CT>& rhs)
noexcept
1094 return lhs.less_than(rhs);
Base class for implementation of common expression access methods.
reference back()
Returns a reference to the last element of the expression.
reference front()
Returns a reference to the first element of the expression.
Base class for implementation of common expression constant access methods.
size_type dimension() const noexcept
Returns the number of dimensions of the expression.
bool in_bounds(Args... args) const
Returns true only if the the specified position is a valid entry in the expression.
size_type shape(size_type index) const
Returns the i-th dimension of the expression.
Base class for multidimensional iterable constant expressions.
Base class for multidimensional iterable expressions.
auto strides(const E &e, stride_type type=stride_type::normal) noexcept
Get strides of an object.
standard mathematical functions for xexpressions
bool operator==(const xaxis_iterator< CT > &lhs, const xaxis_iterator< CT > &rhs)
Checks equality of the iterators.