10#ifndef XTENSOR_SCALAR_HPP
11#define XTENSOR_SCALAR_HPP
17#include <xtl/xtype_traits.hpp>
19#include "../core/xaccessible.hpp"
20#include "../core/xexpression.hpp"
21#include "../core/xiterable.hpp"
22#include "../core/xlayout.hpp"
23#include "../utils/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;
86 class xscalar :
public xsharable_expression<xscalar<CT>>,
88 private xaccessible<xscalar<CT>>,
89 public extension::xscalar_base_t<CT>
93 using self_type = xscalar<CT>;
94 using xexpression_type = std::decay_t<CT>;
95 using extension_base = extension::xscalar_base_t<CT>;
96 using accessible_base = xaccessible<self_type>;
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>;
108 using bool_load_type = xt::bool_load_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>
118 using layout_iterator =
typename iterable_base::template layout_iterator<L>;
119 template <layout_type L>
120 using const_layout_iterator =
typename iterable_base::template const_layout_iterator<L>;
122 template <layout_type L>
123 using reverse_layout_iterator =
typename iterable_base::template reverse_layout_iterator<L>;
124 template <layout_type L>
125 using const_reverse_layout_iterator =
typename iterable_base::template const_reverse_layout_iterator<L>;
127 template <
class S, layout_type L>
128 using broadcast_iterator =
typename iterable_base::template broadcast_iterator<S, L>;
129 template <
class S, layout_type L>
130 using const_broadcast_iterator =
typename iterable_base::template const_broadcast_iterator<S, L>;
132 template <
class S, layout_type L>
133 using reverse_broadcast_iterator =
typename iterable_base::template reverse_broadcast_iterator<S, L>;
134 template <
class S, layout_type L>
135 using const_reverse_broadcast_iterator =
typename iterable_base::template const_reverse_broadcast_iterator<S, 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;
149 xscalar(CT value)
noexcept;
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>
223 broadcast_iterator<S, L> begin(
const S& shape)
noexcept;
224 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
225 broadcast_iterator<S, L> end(
const S& shape)
noexcept;
227 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
228 const_broadcast_iterator<S, L> begin(
const S& shape)
const noexcept;
229 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
230 const_broadcast_iterator<S, L> end(
const S& shape)
const noexcept;
231 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
232 const_broadcast_iterator<S, L> cbegin(
const S& shape)
const noexcept;
233 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
234 const_broadcast_iterator<S, L> cend(
const S& shape)
const noexcept;
237 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
238 reverse_broadcast_iterator<S, L> rbegin(
const S& shape)
noexcept;
239 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
240 reverse_broadcast_iterator<S, L> rend(
const S& shape)
noexcept;
242 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
243 const_reverse_broadcast_iterator<S, L> rbegin(
const S& shape)
const noexcept;
244 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
245 const_reverse_broadcast_iterator<S, L> rend(
const S& shape)
const noexcept;
246 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
247 const_reverse_broadcast_iterator<S, L> crbegin(
const S& shape)
const noexcept;
248 template <
class S, layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
249 const_reverse_broadcast_iterator<S, L> crend(
const S& shape)
const noexcept;
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;
270 stepper stepper_end(
const S& shape,
layout_type l)
noexcept;
273 const_stepper stepper_begin(
const S& shape)
const noexcept;
275 const_stepper stepper_end(
const S& shape,
layout_type l)
const noexcept;
277 dummy_iterator dummy_begin()
noexcept;
278 dummy_iterator dummy_end()
noexcept;
280 const_dummy_iterator dummy_begin()
const noexcept;
281 const_dummy_iterator dummy_end()
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);
291 template <class align, class requested_type = value_type, std::size_t N = xt_simd::simd_traits<requested_type>::size>
292 xt_simd::simd_return_type<value_type, requested_type> load_simd(size_type i)
const;
300 friend class xaccessible<self_type>;
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>;
325 template <
class... E>
328 static constexpr bool value = std::conjunction<is_xscalar<std::decay_t<E>>...>::value;
336 template <
class... E>
337 using all_xscalar = detail::all_xscalar<E...>;
353 template <
bool is_const,
class CT>
354 class xscalar_stepper
358 using self_type = xscalar_stepper<is_const, CT>;
359 using storage_type = std::conditional_t<is_const, const xscalar<CT>,
xscalar<CT>>;
361 using value_type =
typename storage_type::value_type;
362 using reference = std::
363 conditional_t<is_const, typename storage_type::const_reference, typename storage_type::reference>;
364 using pointer = std::conditional_t<is_const, typename storage_type::const_pointer, typename storage_type::pointer>;
365 using size_type =
typename storage_type::size_type;
366 using difference_type =
typename storage_type::difference_type;
367 using shape_type =
typename storage_type::shape_type;
369 template <
class requested_type>
370 using simd_return_type = xt_simd::simd_return_type<value_type, requested_type>;
372 xscalar_stepper(storage_type* c)
noexcept;
374 reference operator*()
const noexcept;
376 void step(size_type dim, size_type n = 1)
noexcept;
377 void step_back(size_type dim, size_type n = 1)
noexcept;
378 void reset(size_type dim)
noexcept;
379 void reset_back(size_type dim)
noexcept;
381 void to_begin()
noexcept;
385 simd_return_type<T> step_simd();
400 template <
bool is_const,
class CT>
401 using dummy_reference_t = std::
402 conditional_t<is_const, typename xscalar<CT>::const_reference,
typename xscalar<CT>::reference>;
404 template <
bool is_const,
class CT>
405 using dummy_pointer_t = std::
406 conditional_t<is_const, typename xscalar<CT>::const_pointer,
typename xscalar<CT>::pointer>;
409 template <
bool is_const,
class CT>
410 class xdummy_iterator :
public xtl::xrandom_access_iterator_base<
411 xdummy_iterator<is_const, CT>,
412 typename xscalar<CT>::value_type,
413 typename xscalar<CT>::difference_type,
414 detail::dummy_pointer_t<is_const, CT>,
415 detail::dummy_reference_t<is_const, CT>>
419 using self_type = xdummy_iterator<is_const, CT>;
420 using storage_type = std::conditional_t<is_const, const xscalar<CT>,
xscalar<CT>>;
422 using value_type =
typename storage_type::value_type;
423 using reference = detail::dummy_reference_t<is_const, CT>;
424 using pointer = detail::dummy_pointer_t<is_const, CT>;
425 using difference_type =
typename storage_type::difference_type;
426 using iterator_category = std::random_access_iterator_tag;
428 explicit xdummy_iterator(storage_type* c)
noexcept;
430 self_type& operator++()
noexcept;
431 self_type& operator--()
noexcept;
433 self_type& operator+=(difference_type n)
noexcept;
434 self_type& operator-=(difference_type n)
noexcept;
436 difference_type operator-(
const self_type& rhs)
const noexcept;
438 reference operator*()
const noexcept;
440 bool equal(
const self_type& rhs)
const noexcept;
441 bool less_than(
const self_type& rhs)
const noexcept;
448 template <
bool is_const,
class CT>
452 template <
bool is_const,
class CT>
460 template <
bool is_const,
class CT>
470 XTENSOR_CONSTEXPR_RETURN
auto linear_begin(
xscalar<CT>& c)
noexcept ->
decltype(c.dummy_begin())
472 return c.dummy_begin();
476 XTENSOR_CONSTEXPR_RETURN
auto linear_end(xscalar<CT>& c)
noexcept ->
decltype(c.dummy_end())
478 return c.dummy_end();
482 XTENSOR_CONSTEXPR_RETURN
auto linear_begin(
const xscalar<CT>& c)
noexcept ->
decltype(c.dummy_begin())
484 return c.dummy_begin();
488 XTENSOR_CONSTEXPR_RETURN
auto linear_end(
const xscalar<CT>& c)
noexcept ->
decltype(c.dummy_end())
490 return c.dummy_end();
499 inline xscalar<CT>::xscalar() noexcept
505 inline xscalar<CT>::xscalar(CT value) noexcept
523 inline auto xscalar<CT>::size() const noexcept -> size_type
529 inline auto xscalar<CT>::shape() const noexcept -> const shape_type&
531 static std::array<size_type, 0> zero_shape;
536 inline auto xscalar<CT>::shape(size_type)
const noexcept -> size_type
542 inline layout_type xscalar<CT>::layout() const noexcept
544 return static_layout;
548 inline bool xscalar<CT>::is_contiguous() const noexcept
554 template <
class... Args>
555 inline auto xscalar<CT>::operator()(Args...) noexcept -> reference
557 XTENSOR_CHECK_DIMENSION((std::array<int, 0>()), Args()...);
562 template <
class... Args>
563 inline auto xscalar<CT>::unchecked(Args...) noexcept -> reference
569 template <
class... Args>
570 inline auto xscalar<CT>::operator()(Args...) const noexcept -> const_reference
572 XTENSOR_CHECK_DIMENSION((std::array<int, 0>()), Args()...);
577 template <
class... Args>
578 inline auto xscalar<CT>::unchecked(Args...) const noexcept -> const_reference
585 inline auto xscalar<CT>::element(It, It)
noexcept -> reference
592 inline auto xscalar<CT>::element(It, It)
const noexcept -> const_reference
598 inline auto xscalar<CT>::expression() noexcept -> xexpression_type&
604 inline auto xscalar<CT>::expression() const noexcept -> const xexpression_type&
611 inline bool xscalar<CT>::broadcast_shape(S&,
bool)
const noexcept
618 inline bool xscalar<CT>::has_linear_assign(
const S&)
const noexcept
624 template <layout_type L>
625 inline auto xscalar<CT>::begin() noexcept -> iterator
631 template <layout_type L>
632 inline auto xscalar<CT>::end() noexcept -> iterator
638 template <layout_type L>
639 inline auto xscalar<CT>::begin() const noexcept -> const_iterator
645 template <layout_type L>
646 inline auto xscalar<CT>::end() const noexcept -> const_iterator
652 template <layout_type L>
653 inline auto xscalar<CT>::cbegin() const noexcept -> const_iterator
659 template <layout_type L>
660 inline auto xscalar<CT>::cend() const noexcept -> const_iterator
666 template <layout_type L>
667 inline auto xscalar<CT>::rbegin() noexcept -> reverse_iterator
669 return reverse_iterator(end());
673 template <layout_type L>
674 inline auto xscalar<CT>::rend() noexcept -> reverse_iterator
676 return reverse_iterator(begin());
680 template <layout_type L>
681 inline auto xscalar<CT>::rbegin() const noexcept -> const_reverse_iterator
687 template <layout_type L>
688 inline auto xscalar<CT>::rend() const noexcept -> const_reverse_iterator
694 template <layout_type L>
695 inline auto xscalar<CT>::crbegin() const noexcept -> const_reverse_iterator
697 return const_reverse_iterator(cend());
701 template <layout_type L>
702 inline auto xscalar<CT>::crend() const noexcept -> const_reverse_iterator
704 return const_reverse_iterator(cbegin());
712 template <
class S, layout_type L>
713 inline auto xscalar<CT>::begin(
const S& shape)
noexcept -> broadcast_iterator<S, L>
715 return iterable_base::template begin<S, L>(shape);
719 template <
class S, layout_type L>
720 inline auto xscalar<CT>::end(
const S& shape)
noexcept -> broadcast_iterator<S, L>
722 return iterable_base::template end<S, L>(shape);
726 template <
class S, layout_type L>
727 inline auto xscalar<CT>::begin(
const S& shape)
const noexcept -> const_broadcast_iterator<S, L>
729 return iterable_base::template begin<S, L>(shape);
733 template <
class S, layout_type L>
734 inline auto xscalar<CT>::end(
const S& shape)
const noexcept -> const_broadcast_iterator<S, L>
736 return iterable_base::template end<S, L>(shape);
740 template <
class S, layout_type L>
741 inline auto xscalar<CT>::cbegin(
const S& shape)
const noexcept -> const_broadcast_iterator<S, L>
743 return iterable_base::template cbegin<S, L>(shape);
747 template <
class S, layout_type L>
748 inline auto xscalar<CT>::cend(
const S& shape)
const noexcept -> const_broadcast_iterator<S, L>
750 return iterable_base::template cend<S, L>(shape);
754 template <
class S, layout_type L>
755 inline auto xscalar<CT>::rbegin(
const S& shape)
noexcept -> reverse_broadcast_iterator<S, L>
757 return iterable_base::template rbegin<S, L>(shape);
761 template <
class S, layout_type L>
762 inline auto xscalar<CT>::rend(
const S& shape)
noexcept -> reverse_broadcast_iterator<S, L>
764 return iterable_base::template rend<S, L>(shape);
768 template <
class S, layout_type L>
769 inline auto xscalar<CT>::rbegin(
const S& shape)
const noexcept -> const_reverse_broadcast_iterator<S, L>
771 return iterable_base::template rbegin<S, L>(shape);
775 template <
class S, layout_type L>
776 inline auto xscalar<CT>::rend(
const S& shape)
const noexcept -> const_reverse_broadcast_iterator<S, L>
778 return iterable_base::template rend<S, L>(shape);
782 template <
class S, layout_type L>
783 inline auto xscalar<CT>::crbegin(
const S& shape)
const noexcept -> const_reverse_broadcast_iterator<S, L>
785 return iterable_base::template crbegin<S, L>(shape);
789 template <
class S, layout_type L>
790 inline auto xscalar<CT>::crend(
const S& shape)
const noexcept -> const_reverse_broadcast_iterator<S, L>
792 return iterable_base::template crend<S, L>(shape);
796 inline auto xscalar<CT>::linear_begin() noexcept -> iterator
798 return this->
template begin<XTENSOR_DEFAULT_LAYOUT>();
802 inline auto xscalar<CT>::linear_end() noexcept -> iterator
804 return this->
template end<XTENSOR_DEFAULT_LAYOUT>();
808 inline auto xscalar<CT>::linear_begin() const noexcept -> const_iterator
810 return this->
template begin<XTENSOR_DEFAULT_LAYOUT>();
814 inline auto xscalar<CT>::linear_end() const noexcept -> const_iterator
816 return this->
template end<XTENSOR_DEFAULT_LAYOUT>();
820 inline auto xscalar<CT>::linear_cbegin() const noexcept -> const_iterator
822 return this->
template cbegin<XTENSOR_DEFAULT_LAYOUT>();
826 inline auto xscalar<CT>::linear_cend() const noexcept -> const_iterator
828 return this->
template cend<XTENSOR_DEFAULT_LAYOUT>();
832 inline auto xscalar<CT>::linear_rbegin() noexcept -> reverse_iterator
834 return this->
template rbegin<XTENSOR_DEFAULT_LAYOUT>();
838 inline auto xscalar<CT>::linear_rend() noexcept -> reverse_iterator
840 return this->
template rend<XTENSOR_DEFAULT_LAYOUT>();
844 inline auto xscalar<CT>::linear_rbegin() const noexcept -> const_reverse_iterator
846 return this->
template rbegin<XTENSOR_DEFAULT_LAYOUT>();
850 inline auto xscalar<CT>::linear_rend() const noexcept -> const_reverse_iterator
852 return this->
template rend<XTENSOR_DEFAULT_LAYOUT>();
856 inline auto xscalar<CT>::linear_crbegin() const noexcept -> const_reverse_iterator
858 return this->
template crbegin<XTENSOR_DEFAULT_LAYOUT>();
862 inline auto xscalar<CT>::linear_crend() const noexcept -> const_reverse_iterator
864 return this->
template crend<XTENSOR_DEFAULT_LAYOUT>();
869 inline auto xscalar<CT>::stepper_begin(
const S&)
noexcept -> stepper
871 return stepper(
this,
false);
876 inline auto xscalar<CT>::stepper_end(
const S&,
layout_type)
noexcept -> stepper
878 return stepper(
this);
883 inline auto xscalar<CT>::stepper_begin(
const S&)
const noexcept -> const_stepper
885 return const_stepper(
this);
890 inline auto xscalar<CT>::stepper_end(
const S&,
layout_type)
const noexcept -> const_stepper
892 return const_stepper(
this);
896 inline auto xscalar<CT>::dummy_begin() noexcept -> dummy_iterator
898 return dummy_iterator(
this);
902 inline auto xscalar<CT>::dummy_end() noexcept -> dummy_iterator
904 return dummy_iterator(
this);
908 inline auto xscalar<CT>::dummy_begin() const noexcept -> const_dummy_iterator
910 return const_dummy_iterator(
this);
914 inline auto xscalar<CT>::dummy_end() const noexcept -> const_dummy_iterator
916 return const_dummy_iterator(
this);
920 inline auto xscalar<CT>::data_element(size_type)
noexcept -> reference
926 inline auto xscalar<CT>::data_element(size_type)
const noexcept -> const_reference
932 inline auto xscalar<CT>::flat(size_type)
noexcept -> reference
938 inline auto xscalar<CT>::flat(size_type)
const noexcept -> const_reference
944 template <
class align,
class simd>
945 inline void xscalar<CT>::store_simd(size_type,
const simd& e)
947 m_value =
static_cast<value_type
>(e[0]);
951 template <
class align,
class requested_type, std::
size_t N>
952 inline auto xscalar<CT>::load_simd(size_type)
const
953 -> xt_simd::simd_return_type<value_type, requested_type>
955 return xt_simd::broadcast_as<requested_type>(m_value);
974 template <
bool is_const,
class CT>
975 inline xscalar_stepper<is_const, CT>::xscalar_stepper(storage_type* c) noexcept
980 template <
bool is_const,
class CT>
981 inline auto xscalar_stepper<is_const, CT>::operator*() const noexcept -> reference
983 return p_c->operator()();
986 template <
bool is_const,
class CT>
987 inline void xscalar_stepper<is_const, CT>::step(size_type , size_type )
noexcept
991 template <
bool is_const,
class CT>
992 inline void xscalar_stepper<is_const, CT>::step_back(size_type , size_type )
noexcept
996 template <
bool is_const,
class CT>
997 inline void xscalar_stepper<is_const, CT>::reset(size_type )
noexcept
1001 template <
bool is_const,
class CT>
1002 inline void xscalar_stepper<is_const, CT>::reset_back(size_type )
noexcept
1006 template <
bool is_const,
class CT>
1007 inline void xscalar_stepper<is_const, CT>::to_begin() noexcept
1011 template <
bool is_const,
class CT>
1012 inline void xscalar_stepper<is_const, CT>::to_end(
layout_type )
noexcept
1016 template <
bool is_const,
class CT>
1018 inline auto xscalar_stepper<is_const, CT>::step_simd() -> simd_return_type<T>
1020 return simd_return_type<T>(p_c->operator()());
1023 template <
bool is_const,
class CT>
1024 inline void xscalar_stepper<is_const, CT>::step_leading()
1032 template <
bool is_const,
class CT>
1033 inline xdummy_iterator<is_const, CT>::xdummy_iterator(storage_type* c) noexcept
1038 template <
bool is_const,
class CT>
1039 inline auto xdummy_iterator<is_const, CT>::operator++() noexcept -> self_type&
1044 template <
bool is_const,
class CT>
1045 inline auto xdummy_iterator<is_const, CT>::operator--() noexcept -> self_type&
1050 template <
bool is_const,
class CT>
1051 inline auto xdummy_iterator<is_const, CT>::operator+=(difference_type)
noexcept -> self_type&
1056 template <
bool is_const,
class CT>
1057 inline auto xdummy_iterator<is_const, CT>::operator-=(difference_type)
noexcept -> self_type&
1062 template <
bool is_const,
class CT>
1063 inline auto xdummy_iterator<is_const, CT>::operator-(
const self_type&)
const noexcept -> difference_type
1068 template <
bool is_const,
class CT>
1069 inline auto xdummy_iterator<is_const, CT>::operator*() const noexcept -> reference
1071 return p_c->operator()();
1074 template <
bool is_const,
class CT>
1075 inline bool xdummy_iterator<is_const, CT>::equal(
const self_type& rhs)
const noexcept
1077 return p_c == rhs.p_c;
1080 template <
bool is_const,
class CT>
1081 inline bool xdummy_iterator<is_const, CT>::less_than(
const self_type& rhs)
const noexcept
1083 return p_c < rhs.p_c;
1086 template <
bool is_const,
class CT>
1090 return lhs.equal(rhs);
1093 template <
bool is_const,
class CT>
1097 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