xtensor
 
Loading...
Searching...
No Matches
xdynamic_view.hpp
1/***************************************************************************
2 * Copyright (c) 2016, Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
3 * *
4 * Distributed under the terms of the BSD 3-Clause License. *
5 * *
6 * The full license is in the file LICENSE, distributed with this software. *
7 ****************************************************************************/
8
9#ifndef XTENSOR_DYNAMIC_VIEW_HPP
10#define XTENSOR_DYNAMIC_VIEW_HPP
11
12#include <variant>
13
14#include <xtl/xsequence.hpp>
15
16#include "../core/xexpression.hpp"
17#include "../core/xiterable.hpp"
18#include "../core/xlayout.hpp"
19#include "../core/xsemantic.hpp"
20#include "../views/xstrided_view_base.hpp"
21
22namespace xt
23{
24
25 template <class CT, class S, layout_type L, class FST>
26 class xdynamic_view;
27
28 template <class CT, class S, layout_type L, class FST>
30 {
31 using xexpression_type = std::decay_t<CT>;
32 using undecay_expression = CT;
33 using reference = inner_reference_t<undecay_expression>;
34 using const_reference = typename xexpression_type::const_reference;
35 using size_type = typename xexpression_type::size_type;
36 using shape_type = std::decay_t<S>;
37 using undecay_shape = S;
38 using storage_getter = FST;
39 using inner_storage_type = typename storage_getter::type;
40 using temporary_type = xarray<std::decay_t<typename xexpression_type::value_type>, xexpression_type::static_layout>;
41 static constexpr layout_type layout = L;
42 };
43
44 template <class CT, class S, layout_type L, class FST>
45 struct xiterable_inner_types<xdynamic_view<CT, S, L, FST>>
46 {
47 using inner_shape_type = S;
48 using inner_strides_type = inner_shape_type;
49 using inner_backstrides_type = inner_shape_type;
50
51#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 8
52 static constexpr auto
53 random_instantiation_var_for_gcc8_data_iface = has_data_interface<xdynamic_view<CT, S, L, FST>>::value;
54 static constexpr auto
55 random_instantiation_var_for_gcc8_has_strides = has_strides<xdynamic_view<CT, S, L, FST>>::value;
56#endif
57
58 // TODO: implement efficient stepper specific to the dynamic_view
59 using const_stepper = xindexed_stepper<const xdynamic_view<CT, S, L, FST>, true>;
61 };
62
63 /****************************
64 * xdynamic_view extensions *
65 ****************************/
66
67 namespace extension
68 {
69 template <class Tag, class CT, class S, layout_type L, class FST>
71
72 template <class CT, class S, layout_type L, class FST>
74 {
75 using type = xtensor_empty_base;
76 };
77
78 template <class CT, class S, layout_type L, class FST>
79 struct xdynamic_view_base : xdynamic_view_base_impl<xexpression_tag_t<CT>, CT, S, L, FST>
80 {
81 };
82
83 template <class CT, class S, layout_type L, class FST>
84 using xdynamic_view_base_t = typename xdynamic_view_base<CT, S, L, FST>::type;
85 }
86
87 /*****************
88 * xdynamic_view *
89 *****************/
90
91 namespace detail
92 {
93 template <class T>
94 class xfake_slice;
95 }
96
97 template <class CT, class S, layout_type L = layout_type::dynamic, class FST = detail::flat_storage_getter<CT, XTENSOR_DEFAULT_TRAVERSAL>>
98 class xdynamic_view : public xview_semantic<xdynamic_view<CT, S, L, FST>>,
99 public xiterable<xdynamic_view<CT, S, L, FST>>,
100 public extension::xdynamic_view_base_t<CT, S, L, FST>,
101 private xstrided_view_base<xdynamic_view<CT, S, L, FST>>
102 {
103 public:
104
105 using self_type = xdynamic_view<CT, S, L, FST>;
106 using base_type = xstrided_view_base<self_type>;
107 using semantic_base = xview_semantic<self_type>;
108 using extension_base = extension::xdynamic_view_base_t<CT, S, L, FST>;
109 using expression_tag = typename extension_base::expression_tag;
110
111 using xexpression_type = typename base_type::xexpression_type;
112 using base_type::is_const;
113
114 using value_type = typename base_type::value_type;
115 using reference = typename base_type::reference;
116 using const_reference = typename base_type::const_reference;
117 using pointer = typename base_type::pointer;
118 using const_pointer = typename base_type::const_pointer;
119 using size_type = typename base_type::size_type;
120 using difference_type = typename base_type::difference_type;
121
122 using inner_storage_type = typename base_type::inner_storage_type;
123 using storage_type = typename base_type::storage_type;
124
125 using iterable_base = xiterable<self_type>;
126 using inner_shape_type = typename iterable_base::inner_shape_type;
127 using inner_strides_type = typename base_type::inner_strides_type;
128 using inner_backstrides_type = typename base_type::inner_backstrides_type;
129
130 using shape_type = typename base_type::shape_type;
131 using strides_type = typename base_type::strides_type;
132 using backstrides_type = typename base_type::backstrides_type;
133
134 using stepper = typename iterable_base::stepper;
135 using const_stepper = typename iterable_base::const_stepper;
136
137 using base_type::contiguous_layout;
138 using base_type::static_layout;
139
140 using temporary_type = typename xcontainer_inner_types<self_type>::temporary_type;
141 using base_index_type = xindex_type_t<shape_type>;
142
143 using simd_value_type = typename base_type::simd_value_type;
144 using bool_load_type = typename base_type::bool_load_type;
145
146 using strides_vt = typename strides_type::value_type;
147 using slice_type = std::variant<detail::xfake_slice<strides_vt>, xkeep_slice<strides_vt>, xdrop_slice<strides_vt>>;
148 using slice_vector_type = std::vector<slice_type>;
149
150 template <class CTA, class SA>
151 xdynamic_view(
152 CTA&& e,
153 SA&& shape,
154 get_strides_t<S>&& strides,
155 std::size_t offset,
157 slice_vector_type&& slices,
158 get_strides_t<S>&& adj_strides
159 ) noexcept;
160
161 template <class E>
162 self_type& operator=(const xexpression<E>& e);
163
164 template <class E>
165 disable_xexpression<E, self_type>& operator=(const E& e);
166
168 using base_type::is_contiguous;
169 using base_type::layout;
170 using base_type::shape;
171 using base_type::size;
172
173 // Explicitly deleting strides method to avoid compilers complaining
174 // about not being able to call the strides method from xstrided_view_base
175 // private base
176 const inner_strides_type& strides() const noexcept = delete;
177
178 reference operator()();
179 const_reference operator()() const;
180
181 template <class... Args>
182 reference operator()(Args... args);
183
184 template <class... Args>
185 const_reference operator()(Args... args) const;
186
187 template <class... Args>
188 reference unchecked(Args... args);
189
190 template <class... Args>
191 const_reference unchecked(Args... args) const;
192
193 reference flat(size_type index);
194 const_reference flat(size_type index) const;
195
196 using base_type::operator[];
197 using base_type::at;
198 using base_type::back;
199 using base_type::front;
201 using base_type::periodic;
202
203 template <class It>
204 reference element(It first, It last);
205
206 template <class It>
207 const_reference element(It first, It last) const;
208
209 size_type data_offset() const noexcept;
210
211 // Explicitly deleting data methods so has_data_interface results
212 // to false instead of having compilers complaining about not being
213 // able to call the methods from the private base
214 value_type* data() noexcept = delete;
215 const value_type* data() const noexcept = delete;
216
219 using base_type::storage;
220
221 template <class O>
222 bool has_linear_assign(const O& str) const noexcept;
223
224 template <class T>
225 void fill(const T& value);
226
227 template <class ST>
228 stepper stepper_begin(const ST& shape);
229 template <class ST>
230 stepper stepper_end(const ST& shape, layout_type l);
231
232 template <class ST>
233 const_stepper stepper_begin(const ST& shape) const;
234 template <class ST>
235 const_stepper stepper_end(const ST& shape, layout_type l) const;
236
237 using container_iterator = std::
238 conditional_t<is_const, typename storage_type::const_iterator, typename storage_type::iterator>;
239 using const_container_iterator = typename storage_type::const_iterator;
240
241 template <class E>
242 using rebind_t = xdynamic_view<E, S, L, typename FST::template rebind_t<E>>;
243
244 template <class E>
245 rebind_t<E> build_view(E&& e) const;
246
247 private:
248
249 using offset_type = typename base_type::offset_type;
250
251 slice_vector_type m_slices;
252 inner_strides_type m_adj_strides;
253
254 container_iterator data_xbegin() noexcept;
255 const_container_iterator data_xbegin() const noexcept;
256 container_iterator data_xend(layout_type l, size_type offset) noexcept;
257 const_container_iterator data_xend(layout_type l, size_type offset) const noexcept;
258
259 template <class It>
260 It data_xbegin_impl(It begin) const noexcept;
261
262 template <class It>
263 It data_xend_impl(It end, layout_type l, size_type offset) const noexcept;
264
265 void assign_temporary_impl(temporary_type&& tmp);
266
267 template <class T, class... Args>
268 offset_type adjust_offset(offset_type offset, T idx, Args... args) const noexcept;
269 offset_type adjust_offset(offset_type offset) const noexcept;
270
271 template <class T, class... Args>
272 offset_type
273 adjust_offset_impl(offset_type offset, size_type idx_offset, T idx, Args... args) const noexcept;
274 offset_type adjust_offset_impl(offset_type offset, size_type idx_offset) const noexcept;
275
276 template <class It>
277 offset_type adjust_element_offset(offset_type offset, It first, It last) const noexcept;
278
279 template <class C>
280 friend class xstepper;
281 friend class xview_semantic<self_type>;
282 friend class xaccessible<self_type>;
283 friend class xconst_accessible<self_type>;
284 };
285
286 /**************************
287 * xdynamic_view builders *
288 **************************/
289
290 template <class T>
291 using xdynamic_slice = std::variant<
292 T,
293
297
301
304
305 xrange<T>,
307
310
311 xall_tag,
314
315 using xdynamic_slice_vector = std::vector<xdynamic_slice<std::ptrdiff_t>>;
316
317 template <class E>
318 auto dynamic_view(E&& e, const xdynamic_slice_vector& slices);
319
320 /******************************
321 * xfake_slice implementation *
322 ******************************/
323
324 namespace detail
325 {
326 template <class T>
327 class xfake_slice : public xslice<xfake_slice<T>>
328 {
329 public:
330
331 using size_type = T;
332 using self_type = xfake_slice<T>;
333
334 xfake_slice() = default;
335
336 size_type operator()(size_type /*i*/) const noexcept
337 {
338 return size_type(0);
339 }
340
341 size_type size() const noexcept
342 {
343 return size_type(1);
344 }
345
346 size_type step_size() const noexcept
347 {
348 return size_type(0);
349 }
350
351 size_type step_size(std::size_t /*i*/, std::size_t /*n*/ = 1) const noexcept
352 {
353 return size_type(0);
354 }
355
356 size_type revert_index(std::size_t i) const noexcept
357 {
358 return i;
359 }
360
361 bool contains(size_type /*i*/) const noexcept
362 {
363 return true;
364 }
365
366 bool operator==(const self_type& /*rhs*/) const noexcept
367 {
368 return true;
369 }
370
371 bool operator!=(const self_type& /*rhs*/) const noexcept
372 {
373 return false;
374 }
375 };
376 }
377
378 /********************************
379 * xdynamic_view implementation *
380 ********************************/
381
382 template <class CT, class S, layout_type L, class FST>
383 template <class CTA, class SA>
384 inline xdynamic_view<CT, S, L, FST>::xdynamic_view(
385 CTA&& e,
386 SA&& shape,
387 get_strides_t<S>&& strides,
388 std::size_t offset,
389 layout_type layout,
390 slice_vector_type&& slices,
391 get_strides_t<S>&& adj_strides
392 ) noexcept
393 : base_type(std::forward<CTA>(e), std::forward<SA>(shape), std::move(strides), offset, layout)
394 , m_slices(std::move(slices))
395 , m_adj_strides(std::move(adj_strides))
396 {
397 }
398
399 template <class CT, class S, layout_type L, class FST>
400 template <class E>
401 inline auto xdynamic_view<CT, S, L, FST>::operator=(const xexpression<E>& e) -> self_type&
402 {
403 return semantic_base::operator=(e);
404 }
405
406 template <class CT, class S, layout_type L, class FST>
407 template <class E>
408 inline auto xdynamic_view<CT, S, L, FST>::operator=(const E& e) -> disable_xexpression<E, self_type>&
409 {
410 std::fill(this->begin(), this->end(), e);
411 return *this;
412 }
413
414 template <class CT, class S, layout_type L, class FST>
415 inline auto xdynamic_view<CT, S, L, FST>::operator()() -> reference
416 {
417 return base_type::storage()[data_offset()];
418 }
419
420 template <class CT, class S, layout_type L, class FST>
421 inline auto xdynamic_view<CT, S, L, FST>::operator()() const -> const_reference
422 {
423 return base_type::storage()[data_offset()];
424 }
425
426 template <class CT, class S, layout_type L, class FST>
427 template <class... Args>
428 inline auto xdynamic_view<CT, S, L, FST>::operator()(Args... args) -> reference
429 {
430 XTENSOR_TRY(check_index(base_type::shape(), args...));
431 XTENSOR_CHECK_DIMENSION(base_type::shape(), args...);
432 offset_type offset = base_type::compute_index(args...);
433 offset = adjust_offset(offset, args...);
434 return base_type::storage()[static_cast<size_type>(offset)];
435 }
436
437 template <class CT, class S, layout_type L, class FST>
438 template <class... Args>
439 inline auto xdynamic_view<CT, S, L, FST>::operator()(Args... args) const -> const_reference
440 {
441 XTENSOR_TRY(check_index(base_type::shape(), args...));
442 XTENSOR_CHECK_DIMENSION(base_type::shape(), args...);
443 offset_type offset = base_type::compute_index(args...);
444 offset = adjust_offset(offset, args...);
445 return base_type::storage()[static_cast<size_type>(offset)];
446 }
447
448 template <class CT, class S, layout_type L, class FST>
449 template <class O>
450 inline bool xdynamic_view<CT, S, L, FST>::has_linear_assign(const O&) const noexcept
451 {
452 return false;
453 }
454
455 template <class CT, class S, layout_type L, class FST>
456 template <class... Args>
457 inline auto xdynamic_view<CT, S, L, FST>::unchecked(Args... args) -> reference
458 {
459 offset_type offset = base_type::compute_unchecked_index(args...);
460 offset = adjust_offset(args...);
461 return base_type::storage()[static_cast<size_type>(offset)];
462 }
463
464 template <class CT, class S, layout_type L, class FST>
465 template <class... Args>
466 inline auto xdynamic_view<CT, S, L, FST>::unchecked(Args... args) const -> const_reference
467 {
468 offset_type offset = base_type::compute_unchecked_index(args...);
469 offset = adjust_offset(args...);
470 return base_type::storage()[static_cast<size_type>(offset)];
471 }
472
473 template <class CT, class S, layout_type L, class FST>
474 inline auto xdynamic_view<CT, S, L, FST>::flat(size_type i) -> reference
475 {
476 return base_type::storage()[data_offset() + i];
477 }
478
479 template <class CT, class S, layout_type L, class FST>
480 inline auto xdynamic_view<CT, S, L, FST>::flat(size_type i) const -> const_reference
481 {
482 return base_type::storage()[data_offset() + i];
483 }
484
485 template <class CT, class S, layout_type L, class FST>
486 template <class It>
487 inline auto xdynamic_view<CT, S, L, FST>::element(It first, It last) -> reference
488 {
489 XTENSOR_TRY(check_element_index(base_type::shape(), first, last));
490 offset_type offset = base_type::compute_element_index(first, last);
491 offset = adjust_element_offset(offset, first, last);
492 return base_type::storage()[static_cast<size_type>(offset)];
493 }
494
495 template <class CT, class S, layout_type L, class FST>
496 template <class It>
497 inline auto xdynamic_view<CT, S, L, FST>::element(It first, It last) const -> const_reference
498 {
499 XTENSOR_TRY(check_element_index(base_type::shape(), first, last));
500 offset_type offset = base_type::compute_element_index(first, last);
501 offset = adjust_element_offset(offset, first, last);
502 return base_type::storage()[static_cast<size_type>(offset)];
503 }
504
505 template <class CT, class S, layout_type L, class FST>
506 inline auto xdynamic_view<CT, S, L, FST>::data_offset() const noexcept -> size_type
507 {
508 size_type offset = base_type::data_offset();
509 size_type sl_offset = std::visit(
510 [](const auto& sl)
511 {
512 return sl(size_type(0));
513 },
514 m_slices[0]
515 );
516 return offset + sl_offset * m_adj_strides[0];
517 }
518
519 template <class CT, class S, layout_type L, class FST>
520 template <class T>
521 inline void xdynamic_view<CT, S, L, FST>::fill(const T& value)
522 {
523 return std::fill(this->linear_begin(), this->linear_end(), value);
524 }
525
526 template <class CT, class S, layout_type L, class FST>
527 template <class ST>
528 inline auto xdynamic_view<CT, S, L, FST>::stepper_begin(const ST& shape) -> stepper
529 {
530 size_type offset = shape.size() - dimension();
531 return stepper(this, offset);
532 }
533
534 template <class CT, class S, layout_type L, class FST>
535 template <class ST>
536 inline auto xdynamic_view<CT, S, L, FST>::stepper_end(const ST& shape, layout_type /*l*/) -> stepper
537 {
538 size_type offset = shape.size() - dimension();
539 return stepper(this, offset, true);
540 }
541
542 template <class CT, class S, layout_type L, class FST>
543 template <class ST>
544 inline auto xdynamic_view<CT, S, L, FST>::stepper_begin(const ST& shape) const -> const_stepper
545 {
546 size_type offset = shape.size() - dimension();
547 return const_stepper(this, offset);
548 }
549
550 template <class CT, class S, layout_type L, class FST>
551 template <class ST>
552 inline auto xdynamic_view<CT, S, L, FST>::stepper_end(const ST& shape, layout_type /*l*/) const
553 -> const_stepper
554 {
555 size_type offset = shape.size() - dimension();
556 return const_stepper(this, offset, true);
557 }
558
559 template <class CT, class S, layout_type L, class FST>
560 template <class E>
561 inline auto xdynamic_view<CT, S, L, FST>::build_view(E&& e) const -> rebind_t<E>
562 {
563 inner_shape_type sh(this->shape());
564 inner_strides_type str(base_type::strides());
565 slice_vector_type svt(m_slices);
566 inner_strides_type adj_str(m_adj_strides);
567 return rebind_t<E>(
568 std::forward<E>(e),
569 std::move(sh),
570 std::move(str),
571 base_type::data_offset(),
572 this->layout(),
573 std::move(svt),
574 std::move(adj_str)
575 );
576 }
577
578 template <class CT, class S, layout_type L, class FST>
579 inline auto xdynamic_view<CT, S, L, FST>::data_xbegin() noexcept -> container_iterator
580 {
581 return data_xbegin_impl(this->storage().begin());
582 }
583
584 template <class CT, class S, layout_type L, class FST>
585 inline auto xdynamic_view<CT, S, L, FST>::data_xbegin() const noexcept -> const_container_iterator
586 {
587 return data_xbegin_impl(this->storage().cbegin());
588 }
589
590 template <class CT, class S, layout_type L, class FST>
591 inline auto xdynamic_view<CT, S, L, FST>::data_xend(layout_type l, size_type offset) noexcept
592 -> container_iterator
593 {
594 return data_xend_impl(this->storage().begin(), l, offset);
595 }
596
597 template <class CT, class S, layout_type L, class FST>
598 inline auto xdynamic_view<CT, S, L, FST>::data_xend(layout_type l, size_type offset) const noexcept
599 -> const_container_iterator
600 {
601 return data_xend_impl(this->storage().cbegin(), l, offset);
602 }
603
604 template <class CT, class S, layout_type L, class FST>
605 template <class It>
606 inline It xdynamic_view<CT, S, L, FST>::data_xbegin_impl(It begin) const noexcept
607 {
608 return begin + static_cast<std::ptrdiff_t>(data_offset());
609 }
610
611 // TODO: fix the data_xend implementation and assign_temporary_impl
612
613 template <class CT, class S, layout_type L, class FST>
614 template <class It>
615 inline It
616 xdynamic_view<CT, S, L, FST>::data_xend_impl(It begin, layout_type l, size_type offset) const noexcept
617 {
618 return strided_data_end(*this, begin + std::ptrdiff_t(data_offset()), l, offset);
619 }
620
621 template <class CT, class S, layout_type L, class FST>
622 inline void xdynamic_view<CT, S, L, FST>::assign_temporary_impl(temporary_type&& tmp)
623 {
624 std::copy(tmp.cbegin(), tmp.cend(), this->begin());
625 }
626
627 template <class CT, class S, layout_type L, class FST>
628 template <class T, class... Args>
629 inline auto
630 xdynamic_view<CT, S, L, FST>::adjust_offset(offset_type offset, T idx, Args... args) const noexcept
631 -> offset_type
632 {
633 constexpr size_type nb_args = sizeof...(Args) + 1;
634 size_type dim = base_type::dimension();
635 offset_type res = nb_args > dim ? adjust_offset(offset, args...)
636 : adjust_offset_impl(offset, dim - nb_args, idx, args...);
637 return res;
638 }
639
640 template <class CT, class S, layout_type L, class FST>
641 inline auto xdynamic_view<CT, S, L, FST>::adjust_offset(offset_type offset) const noexcept -> offset_type
642 {
643 return offset;
644 }
645
646 template <class CT, class S, layout_type L, class FST>
647 template <class T, class... Args>
648 inline auto
649 xdynamic_view<CT, S, L, FST>::adjust_offset_impl(offset_type offset, size_type idx_offset, T idx, Args... args)
650 const noexcept -> offset_type
651 {
652 offset_type sl_offset = std::visit(
653 [idx](const auto& sl)
654 {
655 using type = typename std::decay_t<decltype(sl)>::size_type;
656 return sl(type(idx));
657 },
658 m_slices[idx_offset]
659 );
660 offset_type res = offset + sl_offset * m_adj_strides[idx_offset];
661 return adjust_offset_impl(res, idx_offset + 1, args...);
662 }
663
664 template <class CT, class S, layout_type L, class FST>
665 inline auto xdynamic_view<CT, S, L, FST>::adjust_offset_impl(offset_type offset, size_type) const noexcept
666 -> offset_type
667 {
668 return offset;
669 }
670
671 template <class CT, class S, layout_type L, class FST>
672 template <class It>
673 inline auto
674 xdynamic_view<CT, S, L, FST>::adjust_element_offset(offset_type offset, It first, It last) const noexcept
675 -> offset_type
676 {
677 auto dst = std::distance(first, last);
678 offset_type dim = static_cast<offset_type>(dimension());
679 offset_type loop_offset = dst < dim ? dim - dst : offset_type(0);
680 offset_type idx_offset = dim < dst ? dst - dim : offset_type(0);
681 offset_type res = offset;
682 for (offset_type i = loop_offset; i < dim; ++i, ++first)
683 {
684 offset_type j = static_cast<offset_type>(first[idx_offset]);
685 offset_type sl_offset = std::visit(
686 [j](const auto& sl)
687 {
688 return static_cast<offset_type>(sl(j));
689 },
690 m_slices[static_cast<std::size_t>(i)]
691 );
692 res += sl_offset * m_adj_strides[static_cast<std::size_t>(i)];
693 }
694 return res;
695 }
696
697 /*****************************************
698 * xdynamic_view builders implementation *
699 *****************************************/
700
701 namespace detail
702 {
703 template <class V>
704 struct adj_strides_policy
705 {
706 using slice_vector = V;
707 using strides_type = dynamic_shape<std::ptrdiff_t>;
708
709 slice_vector new_slices;
710 strides_type new_adj_strides;
711
712 protected:
713
714 inline void resize(std::size_t size)
715 {
716 new_slices.resize(size);
717 new_adj_strides.resize(size);
718 }
719
720 inline void set_fake_slice(std::size_t idx)
721 {
722 new_slices[idx] = xfake_slice<std::ptrdiff_t>();
723 new_adj_strides[idx] = std::ptrdiff_t(0);
724 }
725
726 template <class ST, class S>
727 bool fill_args(
728 const xdynamic_slice_vector& slices,
729 std::size_t sl_idx,
730 std::size_t i,
731 std::size_t old_shape,
732 const ST& old_stride,
733 S& shape,
734 get_strides_t<S>& strides
735 )
736 {
737 return fill_args_impl<xkeep_slice<std::ptrdiff_t>>(
738 slices,
739 sl_idx,
740 i,
741 old_shape,
742 old_stride,
743 shape,
744 strides
745 )
746 || fill_args_impl<xdrop_slice<std::ptrdiff_t>>(
747 slices,
748 sl_idx,
749 i,
750 old_shape,
751 old_stride,
752 shape,
753 strides
754 );
755 }
756
757 template <class SL, class ST, class S>
758 bool fill_args_impl(
759 const xdynamic_slice_vector& slices,
760 std::size_t sl_idx,
761 std::size_t i,
762 std::size_t old_shape,
763 const ST& old_stride,
764 S& shape,
765 get_strides_t<S>& strides
766 )
767 {
768 auto* sl = std::get_if<SL>(&slices[sl_idx]);
769 if (sl != nullptr)
770 {
771 new_slices[i] = *sl;
772 auto& ns = std::get<SL>(new_slices[i]);
773 ns.normalize(old_shape);
774 shape[i] = static_cast<std::size_t>(ns.size());
775 strides[i] = std::ptrdiff_t(0);
776 new_adj_strides[i] = static_cast<std::ptrdiff_t>(old_stride);
777 }
778 return sl != nullptr;
779 }
780 };
781 }
782
783 template <class E>
784 inline auto dynamic_view(E&& e, const xdynamic_slice_vector& slices)
785 {
786 using view_type = xdynamic_view<xclosure_t<E>, dynamic_shape<std::size_t>>;
787 using slice_vector = typename view_type::slice_vector_type;
788 using policy = detail::adj_strides_policy<slice_vector>;
789 detail::strided_view_args<policy> args;
790 args.fill_args(
791 e.shape(),
792 detail::get_strides<XTENSOR_DEFAULT_TRAVERSAL>(e),
793 detail::get_offset<XTENSOR_DEFAULT_TRAVERSAL>(e),
794 e.layout(),
795 slices
796 );
797 return view_type(
798 std::forward<E>(e),
799 std::move(args.new_shape),
800 std::move(args.new_strides),
801 args.new_offset,
802 args.new_layout,
803 std::move(args.new_slices),
804 std::move(args.new_adj_strides)
805 );
806 }
807}
808
809#endif
Base class for implementation of common expression access methods.
Base class for implementation of common expression constant access methods.
const_reference front() const
size_type size() const noexcept
size_type dimension() const noexcept
bool in_bounds(Args... args) const
const_reference back() const
const inner_shape_type & shape() const noexcept
Returns the shape of the xtrided_view_base.
layout_type layout() const noexcept
Returns the layout of the xtrided_view_base.
Base class for xexpressions.
Base class for multidimensional iterable expressions.
layout_type layout() const noexcept
xstrided_view_base(CTA &&e, SA &&shape, strides_type &&strides, size_type offset, layout_type layout) noexcept
Constructs an xstrided_view_base.
bool broadcast_shape(O &shape, bool reuse_cache=false) const
const inner_shape_type & shape() const noexcept
storage_type & storage() noexcept
xexpression_type & expression() noexcept
auto strides(const E &e, stride_type type=stride_type::normal) noexcept
Get strides of an object.
Definition xstrides.hpp:248
standard mathematical functions for xexpressions
xarray_container< uvector< T, A >, L, xt::svector< typename uvector< T, A >::size_type, 4, SA, true > > xarray
Alias template on xarray_container with default parameters for data container type and shape / stride...
layout_type
Definition xlayout.hpp:24