10#ifndef XTENSOR_SCALAR_HPP
11#define XTENSOR_SCALAR_HPP
16#include <xtl/xtype_traits.hpp>
18#include "../core/xaccessible.hpp"
19#include "../core/xexpression.hpp"
20#include "../core/xiterable.hpp"
21#include "../core/xlayout.hpp"
22#include "../utils/xtensor_simd.hpp"
33 template <
class Tag,
class CT>
59 template <
bool is_const,
class CT>
62 template <
bool is_const,
class CT>
68 using value_type = std::decay_t<CT>;
69 using inner_shape_type = std::array<std::size_t, 0>;
70 using shape_type = inner_shape_type;
78 using value_type = std::decay_t<CT>;
79 using reference = value_type&;
80 using const_reference =
const value_type&;
81 using size_type = std::size_t;
85 class xscalar :
public xsharable_expression<xscalar<CT>>,
87 private xaccessible<xscalar<CT>>,
88 public extension::xscalar_base_t<CT>
92 using self_type = xscalar<CT>;
93 using xexpression_type = std::decay_t<CT>;
94 using extension_base = extension::xscalar_base_t<CT>;
95 using accessible_base = xaccessible<self_type>;
96 using expression_tag =
typename extension_base::expression_tag;
99 using value_type =
typename inner_types::value_type;
100 using reference =
typename inner_types::reference;
101 using const_reference =
typename inner_types::const_reference;
102 using pointer = value_type*;
103 using const_pointer =
const value_type*;
104 using size_type =
typename inner_types::size_type;
105 using difference_type = std::ptrdiff_t;
106 using simd_value_type = xt_simd::simd_type<value_type>;
107 using bool_load_type = xt::bool_load_type<value_type>;
110 using inner_shape_type =
typename iterable_base::inner_shape_type;
111 using shape_type = inner_shape_type;
113 using stepper =
typename iterable_base::stepper;
114 using const_stepper =
typename iterable_base::const_stepper;
116 template <layout_type L>
117 using layout_iterator =
typename iterable_base::template layout_iterator<L>;
118 template <layout_type L>
119 using const_layout_iterator =
typename iterable_base::template const_layout_iterator<L>;
121 template <layout_type L>
122 using reverse_layout_iterator =
typename iterable_base::template reverse_layout_iterator<L>;
123 template <layout_type L>
124 using const_reverse_layout_iterator =
typename iterable_base::template const_reverse_layout_iterator<L>;
126 template <
class S, layout_type L>
127 using broadcast_iterator =
typename iterable_base::template broadcast_iterator<S, L>;
128 template <
class S, layout_type L>
129 using const_broadcast_iterator =
typename iterable_base::template const_broadcast_iterator<S, L>;
131 template <
class S, layout_type L>
132 using reverse_broadcast_iterator =
typename iterable_base::template reverse_broadcast_iterator<S, L>;
133 template <
class S, layout_type L>
134 using const_reverse_broadcast_iterator =
typename iterable_base::template const_reverse_broadcast_iterator<S, L>;
136 using iterator = value_type*;
137 using const_iterator =
const value_type*;
138 using reverse_iterator = std::reverse_iterator<iterator>;
139 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
145 static constexpr bool contiguous_layout =
true;
148 xscalar(CT value)
noexcept;
150 operator value_type&()
noexcept;
151 operator const value_type&()
const noexcept;
153 size_type size()
const noexcept;
154 const shape_type& shape()
const noexcept;
155 size_type shape(size_type i)
const noexcept;
157 bool is_contiguous()
const noexcept;
161 template <
class... Args>
162 reference operator()(Args...)
noexcept;
163 template <
class... Args>
164 reference unchecked(Args...)
noexcept;
166 template <
class... Args>
167 const_reference operator()(Args...)
const noexcept;
168 template <
class... Args>
169 const_reference unchecked(Args...)
const noexcept;
171 using accessible_base::at;
172 using accessible_base::operator[];
176 using accessible_base::periodic;
179 reference element(It, It)
noexcept;
182 const_reference element(It, It)
const noexcept;
184 xexpression_type& expression()
noexcept;
185 const xexpression_type& expression()
const noexcept;
188 bool broadcast_shape(S& shape,
bool reuse_cache =
false)
const noexcept;
191 bool has_linear_assign(
const S&
strides)
const noexcept;
193 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
194 iterator begin()
noexcept;
195 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
196 iterator end()
noexcept;
198 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
199 const_iterator begin()
const noexcept;
200 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
201 const_iterator end()
const noexcept;
202 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
203 const_iterator cbegin()
const noexcept;
204 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
205 const_iterator cend()
const noexcept;
207 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
208 reverse_iterator rbegin()
noexcept;
209 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
210 reverse_iterator rend()
noexcept;
212 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
213 const_reverse_iterator rbegin()
const noexcept;
214 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
215 const_reverse_iterator rend()
const noexcept;
216 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
217 const_reverse_iterator crbegin()
const noexcept;
218 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
219 const_reverse_iterator crend()
const noexcept;
221 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
222 broadcast_iterator<S, L> begin(
const S& shape)
noexcept;
223 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
224 broadcast_iterator<S, L> end(
const S& shape)
noexcept;
226 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
227 const_broadcast_iterator<S, L> begin(
const S& shape)
const noexcept;
228 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
229 const_broadcast_iterator<S, L> end(
const S& shape)
const noexcept;
230 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
231 const_broadcast_iterator<S, L> cbegin(
const S& shape)
const noexcept;
232 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
233 const_broadcast_iterator<S, L> cend(
const S& shape)
const noexcept;
236 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
237 reverse_broadcast_iterator<S, L> rbegin(
const S& shape)
noexcept;
238 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
239 reverse_broadcast_iterator<S, L> rend(
const S& shape)
noexcept;
241 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
242 const_reverse_broadcast_iterator<S, L> rbegin(
const S& shape)
const noexcept;
243 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
244 const_reverse_broadcast_iterator<S, L> rend(
const S& shape)
const noexcept;
245 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
246 const_reverse_broadcast_iterator<S, L> crbegin(
const S& shape)
const noexcept;
247 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
248 const_reverse_broadcast_iterator<S, L> crend(
const S& shape)
const noexcept;
250 iterator linear_begin()
noexcept;
251 iterator linear_end()
noexcept;
253 const_iterator linear_begin()
const noexcept;
254 const_iterator linear_end()
const noexcept;
255 const_iterator linear_cbegin()
const noexcept;
256 const_iterator linear_cend()
const noexcept;
258 reverse_iterator linear_rbegin()
noexcept;
259 reverse_iterator linear_rend()
noexcept;
261 const_reverse_iterator linear_rbegin()
const noexcept;
262 const_reverse_iterator linear_rend()
const noexcept;
263 const_reverse_iterator linear_crbegin()
const noexcept;
264 const_reverse_iterator linear_crend()
const noexcept;
267 stepper stepper_begin(
const S& shape)
noexcept;
269 stepper stepper_end(
const S& shape,
layout_type l)
noexcept;
272 const_stepper stepper_begin(
const S& shape)
const noexcept;
274 const_stepper stepper_end(
const S& shape,
layout_type l)
const noexcept;
276 dummy_iterator dummy_begin()
noexcept;
277 dummy_iterator dummy_end()
noexcept;
279 const_dummy_iterator dummy_begin()
const noexcept;
280 const_dummy_iterator dummy_end()
const noexcept;
282 reference data_element(size_type i)
noexcept;
283 const_reference data_element(size_type i)
const noexcept;
285 reference flat(size_type i)
noexcept;
286 const_reference flat(size_type i)
const noexcept;
288 template <
class align,
class simd = simd_value_type>
289 void store_simd(size_type i,
const simd& e);
290 template <class align, class requested_type = value_type, std::size_t N = xt_simd::simd_traits<requested_type>::size>
291 xt_simd::simd_return_type<value_type, requested_type> load_simd(size_type i)
const;
299 friend class xaccessible<self_type>;
306 struct is_xscalar_impl : std::false_type
311 struct is_xscalar_impl<xscalar<E>> : std::true_type
317 using is_xscalar = detail::is_xscalar_impl<E>;
324 template <
class... E>
327 static constexpr bool value = std::conjunction<is_xscalar<std::decay_t<E>>...>::value;
335 template <
class... E>
336 using all_xscalar = detail::all_xscalar<E...>;
352 template <
bool is_const,
class CT>
353 class xscalar_stepper
357 using self_type = xscalar_stepper<is_const, CT>;
358 using storage_type = std::conditional_t<is_const, const xscalar<CT>,
xscalar<CT>>;
360 using value_type =
typename storage_type::value_type;
361 using reference = std::
362 conditional_t<is_const, typename storage_type::const_reference, typename storage_type::reference>;
363 using pointer = std::conditional_t<is_const, typename storage_type::const_pointer, typename storage_type::pointer>;
364 using size_type =
typename storage_type::size_type;
365 using difference_type =
typename storage_type::difference_type;
366 using shape_type =
typename storage_type::shape_type;
368 template <
class requested_type>
369 using simd_return_type = xt_simd::simd_return_type<value_type, requested_type>;
371 xscalar_stepper(storage_type* c)
noexcept;
373 reference operator*()
const noexcept;
375 void step(size_type dim, size_type n = 1)
noexcept;
376 void step_back(size_type dim, size_type n = 1)
noexcept;
377 void reset(size_type dim)
noexcept;
378 void reset_back(size_type dim)
noexcept;
380 void to_begin()
noexcept;
384 simd_return_type<T> step_simd();
399 template <
bool is_const,
class CT>
400 using dummy_reference_t = std::
401 conditional_t<is_const, typename xscalar<CT>::const_reference,
typename xscalar<CT>::reference>;
403 template <
bool is_const,
class CT>
404 using dummy_pointer_t = std::
405 conditional_t<is_const, typename xscalar<CT>::const_pointer,
typename xscalar<CT>::pointer>;
408 template <
bool is_const,
class CT>
409 class xdummy_iterator :
public xtl::xrandom_access_iterator_base<
410 xdummy_iterator<is_const, CT>,
411 typename xscalar<CT>::value_type,
412 typename xscalar<CT>::difference_type,
413 detail::dummy_pointer_t<is_const, CT>,
414 detail::dummy_reference_t<is_const, CT>>
418 using self_type = xdummy_iterator<is_const, CT>;
419 using storage_type = std::conditional_t<is_const, const xscalar<CT>,
xscalar<CT>>;
421 using value_type =
typename storage_type::value_type;
422 using reference = detail::dummy_reference_t<is_const, CT>;
423 using pointer = detail::dummy_pointer_t<is_const, CT>;
424 using difference_type =
typename storage_type::difference_type;
425 using iterator_category = std::random_access_iterator_tag;
427 explicit xdummy_iterator(storage_type* c)
noexcept;
429 self_type& operator++()
noexcept;
430 self_type& operator--()
noexcept;
432 self_type& operator+=(difference_type n)
noexcept;
433 self_type& operator-=(difference_type n)
noexcept;
435 difference_type operator-(
const self_type& rhs)
const noexcept;
437 reference operator*()
const noexcept;
439 bool equal(
const self_type& rhs)
const noexcept;
440 bool less_than(
const self_type& rhs)
const noexcept;
447 template <
bool is_const,
class CT>
451 template <
bool is_const,
class CT>
459 template <
bool is_const,
class CT>
469 constexpr auto linear_begin(
xscalar<CT>& c)
noexcept ->
decltype(c.dummy_begin())
471 return c.dummy_begin();
475 constexpr auto linear_end(xscalar<CT>& c)
noexcept ->
decltype(c.dummy_end())
477 return c.dummy_end();
481 constexpr auto linear_begin(
const xscalar<CT>& c)
noexcept ->
decltype(c.dummy_begin())
483 return c.dummy_begin();
487 constexpr auto linear_end(
const xscalar<CT>& c)
noexcept ->
decltype(c.dummy_end())
489 return c.dummy_end();
498 inline xscalar<CT>::xscalar() noexcept
504 inline xscalar<CT>::xscalar(CT value) noexcept
522 inline auto xscalar<CT>::size() const noexcept -> size_type
528 inline auto xscalar<CT>::shape() const noexcept -> const shape_type&
530 static std::array<size_type, 0> zero_shape;
535 inline auto xscalar<CT>::shape(size_type)
const noexcept -> size_type
541 inline layout_type xscalar<CT>::layout() const noexcept
543 return static_layout;
547 inline bool xscalar<CT>::is_contiguous() const noexcept
553 template <
class... Args>
554 inline auto xscalar<CT>::operator()(Args...) noexcept -> reference
556 XTENSOR_CHECK_DIMENSION((std::array<int, 0>()), Args()...);
561 template <
class... Args>
562 inline auto xscalar<CT>::unchecked(Args...) noexcept -> reference
568 template <
class... Args>
569 inline auto xscalar<CT>::operator()(Args...) const noexcept -> const_reference
571 XTENSOR_CHECK_DIMENSION((std::array<int, 0>()), Args()...);
576 template <
class... Args>
577 inline auto xscalar<CT>::unchecked(Args...) const noexcept -> const_reference
584 inline auto xscalar<CT>::element(It, It)
noexcept -> reference
591 inline auto xscalar<CT>::element(It, It)
const noexcept -> const_reference
597 inline auto xscalar<CT>::expression() noexcept -> xexpression_type&
603 inline auto xscalar<CT>::expression() const noexcept -> const xexpression_type&
610 inline bool xscalar<CT>::broadcast_shape(S&,
bool)
const noexcept
617 inline bool xscalar<CT>::has_linear_assign(
const S&)
const noexcept
623 template <layout_type L>
624 inline auto xscalar<CT>::begin() noexcept -> iterator
630 template <layout_type L>
631 inline auto xscalar<CT>::end() noexcept -> iterator
637 template <layout_type L>
638 inline auto xscalar<CT>::begin() const noexcept -> const_iterator
644 template <layout_type L>
645 inline auto xscalar<CT>::end() const noexcept -> const_iterator
651 template <layout_type L>
652 inline auto xscalar<CT>::cbegin() const noexcept -> const_iterator
658 template <layout_type L>
659 inline auto xscalar<CT>::cend() const noexcept -> const_iterator
665 template <layout_type L>
666 inline auto xscalar<CT>::rbegin() noexcept -> reverse_iterator
668 return reverse_iterator(end());
672 template <layout_type L>
673 inline auto xscalar<CT>::rend() noexcept -> reverse_iterator
675 return reverse_iterator(begin());
679 template <layout_type L>
680 inline auto xscalar<CT>::rbegin() const noexcept -> const_reverse_iterator
686 template <layout_type L>
687 inline auto xscalar<CT>::rend() const noexcept -> const_reverse_iterator
693 template <layout_type L>
694 inline auto xscalar<CT>::crbegin() const noexcept -> const_reverse_iterator
696 return const_reverse_iterator(cend());
700 template <layout_type L>
701 inline auto xscalar<CT>::crend() const noexcept -> const_reverse_iterator
703 return const_reverse_iterator(cbegin());
711 template <
class S, layout_type L>
712 inline auto xscalar<CT>::begin(
const S& shape)
noexcept -> broadcast_iterator<S, L>
714 return iterable_base::template begin<S, L>(shape);
718 template <
class S, layout_type L>
719 inline auto xscalar<CT>::end(
const S& shape)
noexcept -> broadcast_iterator<S, L>
721 return iterable_base::template end<S, L>(shape);
725 template <
class S, layout_type L>
726 inline auto xscalar<CT>::begin(
const S& shape)
const noexcept -> const_broadcast_iterator<S, L>
728 return iterable_base::template begin<S, L>(shape);
732 template <
class S, layout_type L>
733 inline auto xscalar<CT>::end(
const S& shape)
const noexcept -> const_broadcast_iterator<S, L>
735 return iterable_base::template end<S, L>(shape);
739 template <
class S, layout_type L>
740 inline auto xscalar<CT>::cbegin(
const S& shape)
const noexcept -> const_broadcast_iterator<S, L>
742 return iterable_base::template cbegin<S, L>(shape);
746 template <
class S, layout_type L>
747 inline auto xscalar<CT>::cend(
const S& shape)
const noexcept -> const_broadcast_iterator<S, L>
749 return iterable_base::template cend<S, L>(shape);
753 template <
class S, layout_type L>
754 inline auto xscalar<CT>::rbegin(
const S& shape)
noexcept -> reverse_broadcast_iterator<S, L>
756 return iterable_base::template rbegin<S, L>(shape);
760 template <
class S, layout_type L>
761 inline auto xscalar<CT>::rend(
const S& shape)
noexcept -> reverse_broadcast_iterator<S, L>
763 return iterable_base::template rend<S, L>(shape);
767 template <
class S, layout_type L>
768 inline auto xscalar<CT>::rbegin(
const S& shape)
const noexcept -> const_reverse_broadcast_iterator<S, L>
770 return iterable_base::template rbegin<S, L>(shape);
774 template <
class S, layout_type L>
775 inline auto xscalar<CT>::rend(
const S& shape)
const noexcept -> const_reverse_broadcast_iterator<S, L>
777 return iterable_base::template rend<S, L>(shape);
781 template <
class S, layout_type L>
782 inline auto xscalar<CT>::crbegin(
const S& shape)
const noexcept -> const_reverse_broadcast_iterator<S, L>
784 return iterable_base::template crbegin<S, L>(shape);
788 template <
class S, layout_type L>
789 inline auto xscalar<CT>::crend(
const S& shape)
const noexcept -> const_reverse_broadcast_iterator<S, L>
791 return iterable_base::template crend<S, L>(shape);
795 inline auto xscalar<CT>::linear_begin() noexcept -> iterator
797 return this->
template begin<XTENSOR_DEFAULT_LAYOUT>();
801 inline auto xscalar<CT>::linear_end() noexcept -> iterator
803 return this->
template end<XTENSOR_DEFAULT_LAYOUT>();
807 inline auto xscalar<CT>::linear_begin() const noexcept -> const_iterator
809 return this->
template begin<XTENSOR_DEFAULT_LAYOUT>();
813 inline auto xscalar<CT>::linear_end() const noexcept -> const_iterator
815 return this->
template end<XTENSOR_DEFAULT_LAYOUT>();
819 inline auto xscalar<CT>::linear_cbegin() const noexcept -> const_iterator
821 return this->
template cbegin<XTENSOR_DEFAULT_LAYOUT>();
825 inline auto xscalar<CT>::linear_cend() const noexcept -> const_iterator
827 return this->
template cend<XTENSOR_DEFAULT_LAYOUT>();
831 inline auto xscalar<CT>::linear_rbegin() noexcept -> reverse_iterator
833 return this->
template rbegin<XTENSOR_DEFAULT_LAYOUT>();
837 inline auto xscalar<CT>::linear_rend() noexcept -> reverse_iterator
839 return this->
template rend<XTENSOR_DEFAULT_LAYOUT>();
843 inline auto xscalar<CT>::linear_rbegin() const noexcept -> const_reverse_iterator
845 return this->
template rbegin<XTENSOR_DEFAULT_LAYOUT>();
849 inline auto xscalar<CT>::linear_rend() const noexcept -> const_reverse_iterator
851 return this->
template rend<XTENSOR_DEFAULT_LAYOUT>();
855 inline auto xscalar<CT>::linear_crbegin() const noexcept -> const_reverse_iterator
857 return this->
template crbegin<XTENSOR_DEFAULT_LAYOUT>();
861 inline auto xscalar<CT>::linear_crend() const noexcept -> const_reverse_iterator
863 return this->
template crend<XTENSOR_DEFAULT_LAYOUT>();
868 inline auto xscalar<CT>::stepper_begin(
const S&)
noexcept -> stepper
870 return stepper(
this,
false);
875 inline auto xscalar<CT>::stepper_end(
const S&,
layout_type)
noexcept -> stepper
877 return stepper(
this);
882 inline auto xscalar<CT>::stepper_begin(
const S&)
const noexcept -> const_stepper
884 return const_stepper(
this);
889 inline auto xscalar<CT>::stepper_end(
const S&,
layout_type)
const noexcept -> const_stepper
891 return const_stepper(
this);
895 inline auto xscalar<CT>::dummy_begin() noexcept -> dummy_iterator
897 return dummy_iterator(
this);
901 inline auto xscalar<CT>::dummy_end() noexcept -> dummy_iterator
903 return dummy_iterator(
this);
907 inline auto xscalar<CT>::dummy_begin() const noexcept -> const_dummy_iterator
909 return const_dummy_iterator(
this);
913 inline auto xscalar<CT>::dummy_end() const noexcept -> const_dummy_iterator
915 return const_dummy_iterator(
this);
919 inline auto xscalar<CT>::data_element(size_type)
noexcept -> reference
925 inline auto xscalar<CT>::data_element(size_type)
const noexcept -> const_reference
931 inline auto xscalar<CT>::flat(size_type)
noexcept -> reference
937 inline auto xscalar<CT>::flat(size_type)
const noexcept -> const_reference
943 template <
class align,
class simd>
944 inline void xscalar<CT>::store_simd(size_type,
const simd& e)
946 m_value =
static_cast<value_type
>(e[0]);
950 template <
class align,
class requested_type, std::
size_t N>
951 inline auto xscalar<CT>::load_simd(size_type)
const
952 -> xt_simd::simd_return_type<value_type, requested_type>
954 return xt_simd::broadcast_as<requested_type>(m_value);
973 template <
bool is_const,
class CT>
974 inline xscalar_stepper<is_const, CT>::xscalar_stepper(storage_type* c) noexcept
979 template <
bool is_const,
class CT>
980 inline auto xscalar_stepper<is_const, CT>::operator*() const noexcept -> reference
982 return p_c->operator()();
985 template <
bool is_const,
class CT>
986 inline void xscalar_stepper<is_const, CT>::step(size_type , size_type )
noexcept
990 template <
bool is_const,
class CT>
991 inline void xscalar_stepper<is_const, CT>::step_back(size_type , size_type )
noexcept
995 template <
bool is_const,
class CT>
996 inline void xscalar_stepper<is_const, CT>::reset(size_type )
noexcept
1000 template <
bool is_const,
class CT>
1001 inline void xscalar_stepper<is_const, CT>::reset_back(size_type )
noexcept
1005 template <
bool is_const,
class CT>
1006 inline void xscalar_stepper<is_const, CT>::to_begin() noexcept
1010 template <
bool is_const,
class CT>
1011 inline void xscalar_stepper<is_const, CT>::to_end(
layout_type )
noexcept
1015 template <
bool is_const,
class CT>
1017 inline auto xscalar_stepper<is_const, CT>::step_simd() -> simd_return_type<T>
1019 return simd_return_type<T>(p_c->operator()());
1022 template <
bool is_const,
class CT>
1023 inline void xscalar_stepper<is_const, CT>::step_leading()
1031 template <
bool is_const,
class CT>
1032 inline xdummy_iterator<is_const, CT>::xdummy_iterator(storage_type* c) noexcept
1037 template <
bool is_const,
class CT>
1038 inline auto xdummy_iterator<is_const, CT>::operator++() noexcept -> self_type&
1043 template <
bool is_const,
class CT>
1044 inline auto xdummy_iterator<is_const, CT>::operator--() noexcept -> self_type&
1049 template <
bool is_const,
class CT>
1050 inline auto xdummy_iterator<is_const, CT>::operator+=(difference_type)
noexcept -> self_type&
1055 template <
bool is_const,
class CT>
1056 inline auto xdummy_iterator<is_const, CT>::operator-=(difference_type)
noexcept -> self_type&
1061 template <
bool is_const,
class CT>
1062 inline auto xdummy_iterator<is_const, CT>::operator-(
const self_type&)
const noexcept -> difference_type
1067 template <
bool is_const,
class CT>
1068 inline auto xdummy_iterator<is_const, CT>::operator*() const noexcept -> reference
1070 return p_c->operator()();
1073 template <
bool is_const,
class CT>
1074 inline bool xdummy_iterator<is_const, CT>::equal(
const self_type& rhs)
const noexcept
1076 return p_c == rhs.p_c;
1079 template <
bool is_const,
class CT>
1080 inline bool xdummy_iterator<is_const, CT>::less_than(
const self_type& rhs)
const noexcept
1082 return p_c < rhs.p_c;
1085 template <
bool is_const,
class CT>
1089 return lhs.equal(rhs);
1092 template <
bool is_const,
class CT>
1096 return lhs.less_than(rhs);
Base class for implementation of common expression constant access methods.
size_type dimension() const noexcept
bool in_bounds(Args... args) const
size_type shape(size_type index) const
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