xtensor
Loading...
Searching...
No Matches
xoptional_assembly_base.hpp
1/***************************************************************************
2 * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
3 * Copyright (c) QuantStack *
4 * *
5 * Distributed under the terms of the BSD 3-Clause License. *
6 * *
7 * The full license is in the file LICENSE, distributed with this software. *
8 ****************************************************************************/
9
10#ifndef XOPTIONAL_ASSEMBLY_BASE_HPP
11#define XOPTIONAL_ASSEMBLY_BASE_HPP
12
13#include "xiterable.hpp"
14#include "xoptional_assembly_storage.hpp"
15#include "xtensor_forward.hpp"
16
17namespace xt
18{
19 template <class D, bool is_const>
20 class xoptional_assembly_stepper;
21
22 /***************************
23 * xoptional_assembly_base *
24 ***************************/
25
38 template <class D>
40 {
41 public:
42
44 using derived_type = D;
46
47 using raw_value_expression = typename inner_types::raw_value_expression;
48 using base_value_type = typename raw_value_expression::value_type;
49 using base_reference = typename raw_value_expression::reference;
50 using base_const_reference = typename raw_value_expression::const_reference;
51
52 using raw_flag_expression = typename inner_types::raw_flag_expression;
53 using flag_type = typename raw_flag_expression::value_type;
54 using flag_reference = typename raw_flag_expression::reference;
55 using flag_const_reference = typename raw_flag_expression::const_reference;
56
57 using storage_type = typename inner_types::storage_type;
58
59 using value_type = typename storage_type::value_type;
60 using reference = typename storage_type::reference;
61 using const_reference = typename storage_type::const_reference;
62 using pointer = typename storage_type::pointer;
63 using const_pointer = typename storage_type::const_pointer;
64 using size_type = typename raw_value_expression::size_type;
65 using difference_type = typename raw_value_expression::difference_type;
66 using simd_value_type = xt_simd::simd_type<value_type>;
68
69 using shape_type = typename raw_value_expression::shape_type;
70 using strides_type = typename raw_value_expression::strides_type;
71 using backstrides_type = typename raw_value_expression::backstrides_type;
72
73 using inner_shape_type = typename raw_value_expression::inner_shape_type;
74 using inner_strides_type = typename raw_value_expression::inner_strides_type;
75 using inner_backstrides_type = typename raw_value_expression::inner_backstrides_type;
76
78 using stepper = typename iterable_base::stepper;
79 using const_stepper = typename iterable_base::const_stepper;
80
81 static constexpr layout_type static_layout = raw_value_expression::static_layout;
82 static constexpr bool contiguous_layout = raw_value_expression::contiguous_layout;
83
85 using value_expression = raw_value_expression&;
86 using flag_expression = raw_flag_expression&;
87 using const_value_expression = const raw_value_expression&;
88 using const_flag_expression = const raw_flag_expression&;
89
90 template <layout_type L>
91 using layout_iterator = typename iterable_base::template layout_iterator<L>;
92 template <layout_type L>
93 using const_layout_iterator = typename iterable_base::template const_layout_iterator<L>;
94 template <layout_type L>
95 using reverse_layout_iterator = typename iterable_base::template reverse_layout_iterator<L>;
96 template <layout_type L>
97 using const_reverse_layout_iterator = typename iterable_base::template const_reverse_layout_iterator<L>;
98
99 template <class S, layout_type L>
100 using broadcast_iterator = typename iterable_base::template broadcast_iterator<S, L>;
101 template <class S, layout_type L>
102 using const_broadcast_iterator = typename iterable_base::template const_broadcast_iterator<S, L>;
103 template <class S, layout_type L>
104 using reverse_broadcast_iterator = typename iterable_base::template reverse_broadcast_iterator<S, L>;
105 template <class S, layout_type L>
106 using const_reverse_broadcast_iterator = typename iterable_base::template const_reverse_broadcast_iterator<S, L>;
107
108 using linear_iterator = typename storage_type::iterator;
109 using const_linear_iterator = typename storage_type::const_iterator;
110 using reverse_linear_iterator = typename storage_type::reverse_iterator;
111 using const_reverse_linear_iterator = typename storage_type::const_reverse_iterator;
112
113 using iterator = typename iterable_base::iterator;
114 using const_iterator = typename iterable_base::const_iterator;
115 using reverse_iterator = typename iterable_base::reverse_iterator;
116 using const_reverse_iterator = typename iterable_base::const_reverse_iterator;
117
118 size_type size() const noexcept;
120 const inner_shape_type& shape() const noexcept;
121 size_type shape(size_type index) const;
122 const inner_strides_type& strides() const noexcept;
123 const inner_backstrides_type& backstrides() const noexcept;
124
125 template <class S = shape_type>
126 void resize(const S& shape, bool force = false);
127 template <class S = shape_type>
129 template <class S = shape_type>
130 void resize(const S& shape, const strides_type& strides);
131
132 template <class S = shape_type>
133 auto& reshape(const S& shape, layout_type layout = static_layout) &;
134
135 template <class T>
136 auto& reshape(std::initializer_list<T> shape, layout_type layout = static_layout) &;
137
139 bool is_contiguous() const noexcept;
140
141 template <class T>
142 void fill(const T& value);
143
144 template <class... Args>
145 reference operator()(Args... args);
146
147 template <class... Args>
148 const_reference operator()(Args... args) const;
149
150 template <class... Args>
151 reference at(Args... args);
152
153 template <class... Args>
154 const_reference at(Args... args) const;
155
156 template <class... Args>
157 reference unchecked(Args... args);
158
159 template <class... Args>
160 const_reference unchecked(Args... args) const;
161
163 disable_integral_t<S, reference> operator[](const S& index);
164 template <class I>
165 reference operator[](std::initializer_list<I> index);
166 reference operator[](size_type i);
167
169 disable_integral_t<S, const_reference> operator[](const S& index) const;
170 template <class I>
171 const_reference operator[](std::initializer_list<I> index) const;
172 const_reference operator[](size_type i) const;
173
174 template <class... Args>
175 reference periodic(Args... args);
176
177 template <class... Args>
178 const_reference periodic(Args... args) const;
179
180 reference front();
181 const_reference front() const;
182
183 reference back();
184 const_reference back() const;
185
186 reference flat(size_type args);
187 const_reference flat(size_type args) const;
188
190 reference element(It first, It last);
192 const_reference element(It first, It last) const;
193
194 template <class... Args>
196
197 storage_type& storage() noexcept;
198 const storage_type& storage() const noexcept;
199
200 value_type* data() noexcept;
201 const value_type* data() const noexcept;
202 const size_type data_offset() const noexcept;
203
206
209
210 using iterable_base::begin;
211 using iterable_base::cbegin;
212 using iterable_base::cend;
213 using iterable_base::crbegin;
214 using iterable_base::crend;
215 using iterable_base::end;
216 using iterable_base::rbegin;
217 using iterable_base::rend;
218
219 linear_iterator linear_begin() noexcept;
220 linear_iterator linear_end() noexcept;
221
222 const_linear_iterator linear_begin() const noexcept;
223 const_linear_iterator linear_end() const noexcept;
224 const_linear_iterator linear_cbegin() const noexcept;
225 const_linear_iterator linear_cend() const noexcept;
226
227 reverse_linear_iterator linear_rbegin() noexcept;
228 reverse_linear_iterator linear_rend() noexcept;
229
230 const_reverse_linear_iterator linear_rbegin() const noexcept;
231 const_reverse_linear_iterator linear_rend() const noexcept;
232 const_reverse_linear_iterator linear_crbegin() const noexcept;
233 const_reverse_linear_iterator linear_crend() const noexcept;
234
236 stepper stepper_begin(const S& shape) noexcept;
238 stepper stepper_end(const S& shape, layout_type l) noexcept;
239
241 const_stepper stepper_begin(const S& shape) const noexcept;
243 const_stepper stepper_end(const S& shape, layout_type l) const noexcept;
244
245 value_expression value() noexcept;
246 const_value_expression value() const noexcept;
247
248 flag_expression has_value() noexcept;
249 const_flag_expression has_value() const noexcept;
250
251 protected:
252
255
258
261
262 private:
263
264 derived_type& derived_cast() noexcept;
265 const derived_type& derived_cast() const noexcept;
266
269 };
270
271 /******************************
272 * xoptional_assembly_stepper *
273 ******************************/
274
275 template <class D, bool is_const>
277 {
278 public:
279
281 using assembly_type = typename D::assembly_type;
282 using value_type = typename assembly_type::value_type;
283 using reference = std::
284 conditional_t<is_const, typename assembly_type::const_reference, typename assembly_type::reference>;
285 using pointer = std::conditional_t<is_const, typename assembly_type::const_pointer, typename assembly_type::pointer>;
286 using size_type = typename assembly_type::size_type;
287 using difference_type = typename assembly_type::difference_type;
288 using raw_value_expression = typename assembly_type::raw_value_expression;
289 using raw_flag_expression = typename assembly_type::raw_flag_expression;
290 using value_stepper = std::
291 conditional_t<is_const, typename raw_value_expression::const_stepper, typename raw_value_expression::stepper>;
292 using flag_stepper = std::
293 conditional_t<is_const, typename raw_flag_expression::const_stepper, typename raw_flag_expression::stepper>;
294
295 xoptional_assembly_stepper(value_stepper vs, flag_stepper fs) noexcept;
296
297
298 void step(size_type dim);
299 void step_back(size_type dim);
300 void step(size_type dim, size_type n);
301 void step_back(size_type dim, size_type n);
302 void reset(size_type dim);
303 void reset_back(size_type dim);
304
305 void to_begin();
306 void to_end(layout_type l);
307
308 reference operator*() const;
309
310 private:
311
312 value_stepper m_vs;
313 flag_stepper m_fs;
314 };
315
316 /******************************************
317 * xoptional_assembly_base implementation *
318 ******************************************/
319
327 template <class D>
329 {
330 return value().size();
331 }
332
336 template <class D>
337 inline constexpr auto xoptional_assembly_base<D>::dimension() const noexcept -> size_type
338 {
339 return value().dimension();
340 }
341
345 template <class D>
346 inline auto xoptional_assembly_base<D>::shape() const noexcept -> const inner_shape_type&
347 {
348 return value().shape();
349 }
350
354 template <class D>
355 inline auto xoptional_assembly_base<D>::shape(size_type i) const -> size_type
356 {
357 return value().shape(i);
358 }
359
363 template <class D>
364 inline auto xoptional_assembly_base<D>::strides() const noexcept -> const inner_strides_type&
365 {
366 return value().strides();
367 }
368
372 template <class D>
373 inline auto xoptional_assembly_base<D>::backstrides() const noexcept -> const inner_backstrides_type&
374 {
375 return value().backstrides();
376 }
377
379
385 template <class D>
386 template <class S>
388 {
389 value().resize(shape, force);
390 has_value().resize(shape, force);
391 }
392
398 template <class D>
399 template <class S>
401 {
402 value().resize(shape, l);
403 has_value().resize(shape, l);
404 }
405
411 template <class D>
412 template <class S>
413 inline void xoptional_assembly_base<D>::resize(const S& shape, const strides_type& strides)
414 {
415 value().resize(shape, strides);
416 has_value().resize(shape, strides);
417 }
418
424 template <class D>
425 template <class S>
427 {
428 value().reshape(shape, layout);
429 has_value().reshape(shape, layout);
430 return *this;
431 }
432
433 template <class D>
434 template <class T>
435 inline auto& xoptional_assembly_base<D>::reshape(std::initializer_list<T> shape, layout_type layout) &
436 {
437 value().reshape(shape, layout);
438 has_value().reshape(shape, layout);
439 return *this;
440 }
441
446 template <class D>
448 {
449 return value().layout();
450 }
451
452 template <class D>
454 {
455 return value().is_contiguous();
456 }
457
462 template <class D>
463 template <class T>
465 {
466 std::fill(this->linear_begin(), this->linear_end(), value);
467 }
468
479 template <class D>
480 template <class... Args>
482 {
483 return reference(value()(args...), has_value()(args...));
484 }
485
492 template <class D>
493 template <class... Args>
494 inline auto xoptional_assembly_base<D>::operator()(Args... args) const -> const_reference
495 {
496 return const_reference(value()(args...), has_value()(args...));
497 }
498
508 template <class D>
509 template <class... Args>
510 inline auto xoptional_assembly_base<D>::at(Args... args) -> reference
511 {
512 return reference(value().at(args...), has_value().at(args...));
513 }
514
524 template <class D>
525 template <class... Args>
526 inline auto xoptional_assembly_base<D>::at(Args... args) const -> const_reference
527 {
528 return const_reference(value().at(args...), has_value().at(args...));
529 }
530
550 template <class D>
551 template <class... Args>
553 {
554 return reference(value().unchecked(args...), has_value().unchecked(args...));
555 }
556
576 template <class D>
577 template <class... Args>
578 inline auto xoptional_assembly_base<D>::unchecked(Args... args) const -> const_reference
579 {
580 return const_reference(value().unchecked(args...), has_value().unchecked(args...));
581 }
582
589 template <class D>
590 template <class S>
592 {
593 return reference(value()[index], has_value()[index]);
594 }
595
596 template <class D>
597 template <class I>
598 inline auto xoptional_assembly_base<D>::operator[](std::initializer_list<I> index) -> reference
599 {
600 return reference(value()[index], has_value()[index]);
601 }
602
603 template <class D>
604 inline auto xoptional_assembly_base<D>::operator[](size_type i) -> reference
605 {
606 return reference(value()[i], has_value()[i]);
607 }
608
615 template <class D>
616 template <class S>
617 inline auto xoptional_assembly_base<D>::operator[](const S& index) const
619 {
620 return const_reference(value()[index], has_value()[index]);
621 }
622
623 template <class D>
624 template <class I>
625 inline auto xoptional_assembly_base<D>::operator[](std::initializer_list<I> index) const -> const_reference
626 {
627 return const_reference(value()[index], has_value()[index]);
628 }
629
630 template <class D>
631 inline auto xoptional_assembly_base<D>::operator[](size_type i) const -> const_reference
632 {
633 return const_reference(value()[i], has_value()[i]);
634 }
635
643 template <class D>
644 template <class... Args>
645 inline auto xoptional_assembly_base<D>::periodic(Args... args) -> reference
646 {
647 return reference(value().periodic(args...), has_value().periodic(args...));
648 }
649
657 template <class D>
658 template <class... Args>
659 inline auto xoptional_assembly_base<D>::periodic(Args... args) const -> const_reference
660 {
661 return const_reference(value().periodic(args...), has_value().periodic(args...));
662 }
663
667 template <class D>
668 inline auto xoptional_assembly_base<D>::front() -> reference
669 {
670 return reference(value().front(), has_value().front());
671 }
672
676 template <class D>
677 inline auto xoptional_assembly_base<D>::front() const -> const_reference
678 {
679 return const_reference(value().front(), has_value().front());
680 }
681
685 template <class D>
686 inline auto xoptional_assembly_base<D>::back() -> reference
687 {
688 return reference(value().back(), has_value().back());
689 }
690
694 template <class D>
695 inline auto xoptional_assembly_base<D>::back() const -> const_reference
696 {
697 return const_reference(value().back(), has_value().back());
698 }
699
705 template <class D>
706 inline auto xoptional_assembly_base<D>::flat(size_type i) -> reference
707 {
708 return reference(value().flat(i), has_value().flat(i));
709 }
710
716 template <class D>
717 inline auto xoptional_assembly_base<D>::flat(size_type i) const -> const_reference
718 {
719 return const_reference(value().flat(i), has_value().flat(i));
720 }
721
729 template <class D>
730 template <class It>
732 {
733 return reference(value().element(first, last), has_value().element(first, last));
734 }
735
743 template <class D>
744 template <class It>
745 inline auto xoptional_assembly_base<D>::element(It first, It last) const -> const_reference
746 {
747 return const_reference(value().element(first, last), has_value().element(first, last));
748 }
749
755 template <class D>
756 template <class... Args>
758 {
759 return value().in_bounds(args...) && has_value().in_bounds(args...);
760 }
761
763
764 template <class D>
765 inline auto xoptional_assembly_base<D>::storage() noexcept -> storage_type&
766 {
767 return derived_cast().storage_impl();
768 }
769
770 template <class D>
771 inline auto xoptional_assembly_base<D>::storage() const noexcept -> const storage_type&
772 {
773 return derived_cast().storage_impl();
774 }
775
776 template <class D>
777 inline auto xoptional_assembly_base<D>::data() noexcept -> value_type*
778 {
779 return storage().data();
780 }
781
782 template <class D>
783 inline auto xoptional_assembly_base<D>::data() const noexcept -> const value_type*
784 {
785 return storage().data();
786 }
787
788 template <class D>
789 inline auto xoptional_assembly_base<D>::data_offset() const noexcept -> const size_type
790 {
791 return size_type(0);
792 }
793
804 template <class D>
805 template <class S>
807 {
808 bool res = value().broadcast_shape(shape, reuse_cache);
809 return res && has_value().broadcast_shape(shape, reuse_cache);
810 }
811
817 template <class D>
818 template <class S>
819 inline bool xoptional_assembly_base<D>::has_linear_assign(const S& strides) const noexcept
820 {
821 return value().has_linear_assign(strides) && has_value().has_linear_assign(strides);
822 }
823
825
826 template <class D>
827 inline auto xoptional_assembly_base<D>::linear_begin() noexcept -> linear_iterator
828 {
829 return linear_iterator(value().linear_begin(), has_value().linear_begin());
830 }
831
832 template <class D>
833 inline auto xoptional_assembly_base<D>::linear_end() noexcept -> linear_iterator
834 {
835 return linear_iterator(value().linear_end(), has_value().linear_end());
836 }
837
838 template <class D>
839 inline auto xoptional_assembly_base<D>::linear_begin() const noexcept -> const_linear_iterator
840 {
841 return linear_cbegin();
842 }
843
844 template <class D>
845 inline auto xoptional_assembly_base<D>::linear_end() const noexcept -> const_linear_iterator
846 {
847 return linear_cend();
848 }
849
850 template <class D>
851 inline auto xoptional_assembly_base<D>::linear_cbegin() const noexcept -> const_linear_iterator
852 {
853 return const_linear_iterator(value().linear_cbegin(), has_value().linear_cbegin());
854 }
855
856 template <class D>
857 inline auto xoptional_assembly_base<D>::linear_cend() const noexcept -> const_linear_iterator
858 {
859 return const_linear_iterator(value().linear_cend(), has_value().linear_cend());
860 }
861
862 template <class D>
863 inline auto xoptional_assembly_base<D>::linear_rbegin() noexcept -> reverse_linear_iterator
864 {
865 return reverse_linear_iterator(linear_end());
866 }
867
868 template <class D>
869 inline auto xoptional_assembly_base<D>::linear_rend() noexcept -> reverse_linear_iterator
870 {
871 return reverse_linear_iterator(linear_begin());
872 }
873
874 template <class D>
875 inline auto xoptional_assembly_base<D>::linear_rbegin() const noexcept -> const_reverse_linear_iterator
876 {
877 return linear_crbegin();
878 }
879
880 template <class D>
881 inline auto xoptional_assembly_base<D>::linear_rend() const noexcept -> const_reverse_linear_iterator
882 {
883 return linear_crend();
884 }
885
886 template <class D>
887 inline auto xoptional_assembly_base<D>::linear_crbegin() const noexcept -> const_reverse_linear_iterator
888 {
889 return const_reverse_linear_iterator(linear_cend());
890 }
891
892 template <class D>
893 inline auto xoptional_assembly_base<D>::linear_crend() const noexcept -> const_reverse_linear_iterator
894 {
895 return const_reverse_linear_iterator(linear_cbegin());
896 }
897
898 template <class D>
899 template <class S>
900 inline auto xoptional_assembly_base<D>::stepper_begin(const S& shape) noexcept -> stepper
901 {
902 return stepper(value().stepper_begin(shape), has_value().stepper_begin(shape));
903 }
904
905 template <class D>
906 template <class S>
907 inline auto xoptional_assembly_base<D>::stepper_end(const S& shape, layout_type l) noexcept -> stepper
908 {
909 return stepper(value().stepper_end(shape, l), has_value().stepper_end(shape, l));
910 }
911
912 template <class D>
913 template <class S>
914 inline auto xoptional_assembly_base<D>::stepper_begin(const S& shape) const noexcept -> const_stepper
915 {
916 return const_stepper(value().stepper_begin(shape), has_value().stepper_begin(shape));
917 }
918
919 template <class D>
920 template <class S>
921 inline auto xoptional_assembly_base<D>::stepper_end(const S& shape, layout_type l) const noexcept
922 -> const_stepper
923 {
924 return const_stepper(value().stepper_end(shape, l), has_value().stepper_end(shape, l));
925 }
926
930 template <class D>
931 inline auto xoptional_assembly_base<D>::value() noexcept -> value_expression
932 {
933 return derived_cast().value_impl();
934 }
935
939 template <class D>
940 inline auto xoptional_assembly_base<D>::value() const noexcept -> const_value_expression
941 {
942 return derived_cast().value_impl();
943 }
944
948 template <class D>
949 inline auto xoptional_assembly_base<D>::has_value() noexcept -> flag_expression
950 {
951 return derived_cast().has_value_impl();
952 }
953
957 template <class D>
958 inline auto xoptional_assembly_base<D>::has_value() const noexcept -> const_flag_expression
959 {
960 return derived_cast().has_value_impl();
961 }
962
963 template <class D>
964 inline auto xoptional_assembly_base<D>::derived_cast() noexcept -> derived_type&
965 {
966 return *static_cast<derived_type*>(this);
967 }
968
969 template <class D>
970 inline auto xoptional_assembly_base<D>::derived_cast() const noexcept -> const derived_type&
971 {
972 return *static_cast<const derived_type*>(this);
973 }
974
975 /*********************************************
976 * xoptional_assembly_stepper implementation *
977 *********************************************/
978
979 template <class D, bool C>
980 inline xoptional_assembly_stepper<D, C>::xoptional_assembly_stepper(value_stepper vs, flag_stepper fs) noexcept
981 : m_vs(vs)
982 , m_fs(fs)
983 {
984 }
985
986 template <class D, bool C>
987 inline void xoptional_assembly_stepper<D, C>::step(size_type dim)
988 {
989 m_vs.step(dim);
990 m_fs.step(dim);
991 }
992
993 template <class D, bool C>
994 inline void xoptional_assembly_stepper<D, C>::step_back(size_type dim)
995 {
996 m_vs.step_back(dim);
997 m_fs.step_back(dim);
998 }
999
1000 template <class D, bool C>
1001 inline void xoptional_assembly_stepper<D, C>::step(size_type dim, size_type n)
1002 {
1003 m_vs.step(dim, n);
1004 m_fs.step(dim, n);
1005 }
1006
1007 template <class D, bool C>
1008 inline void xoptional_assembly_stepper<D, C>::step_back(size_type dim, size_type n)
1009 {
1010 m_vs.step_back(dim, n);
1011 m_fs.step_back(dim, n);
1012 }
1013
1014 template <class D, bool C>
1015 inline void xoptional_assembly_stepper<D, C>::reset(size_type dim)
1016 {
1017 m_vs.reset(dim);
1018 m_fs.reset(dim);
1019 }
1020
1021 template <class D, bool C>
1022 inline void xoptional_assembly_stepper<D, C>::reset_back(size_type dim)
1023 {
1024 m_vs.reset_back(dim);
1025 m_fs.reset_back(dim);
1026 }
1027
1028 template <class D, bool C>
1029 inline void xoptional_assembly_stepper<D, C>::to_begin()
1030 {
1031 m_vs.to_begin();
1032 m_fs.to_begin();
1033 }
1034
1035 template <class D, bool C>
1036 inline void xoptional_assembly_stepper<D, C>::to_end(layout_type l)
1037 {
1038 m_vs.to_end(l);
1039 m_fs.to_end(l);
1040 }
1041
1042 template <class D, bool C>
1043 inline auto xoptional_assembly_stepper<D, C>::operator*() const -> reference
1044 {
1045 return reference(*m_vs, *m_fs);
1046 }
1047}
1048
1049#endif
Base class for multidimensional iterable constant expressions.
Definition xiterable.hpp:37
Base class for multidimensional iterable expressions.
Base class for dense multidimensional optional assemblies.
const inner_backstrides_type & backstrides() const noexcept
Returns the backstrides of the optional assembly.
reference front()
Returns a reference to the first element of the optional assembly.
bool in_bounds(Args... args) const
Returns true only if the the specified position is a valid entry in the expression.
size_type size() const noexcept
Returns the number of element in the optional assembly.
reference back()
Returns a reference to the last element of the optional assembly.
const inner_shape_type & shape() const noexcept
Returns the shape of the optional assembly.
value_expression value() noexcept
Return an expression for the values of the optional assembly.
void fill(const T &value)
Fills the data with the given value.
bool has_linear_assign(const S &strides) const noexcept
Checks whether the xoptional_assembly_base can be linearly assigned to an expression with the specifi...
layout_type layout() const noexcept
Return the layout_type of the container.
constexpr size_type dimension() const noexcept
Returns the number of dimensions of the optional assembly.
bool broadcast_shape(S &shape, bool reuse_cache=false) const
Broadcast the shape of the optional assembly to the specified parameter.
const inner_strides_type & strides() const noexcept
Returns the strides of the optional assembly.
reference flat(size_type args)
Returns a reference to the element at the specified position of the underlying storage in the optiona...
void resize(const S &shape, bool force=false)
Resizes the optional assembly.
auto & reshape(const S &shape, layout_type layout=static_layout) &
Reshapes the optional assembly.
flag_expression has_value() noexcept
Return an expression for the missing mask of the optional assembly.
auto operator*(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< detail::multiplies, E1, E2 >
Multiplication.
standard mathematical functions for xexpressions
layout_type
Definition xlayout.hpp:24