xtensor
Loading...
Searching...
No Matches
xmultiindex_iterator.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 XTENSOR_XMULTIINDEX_ITERATOR
11#define XTENSOR_XMULTIINDEX_ITERATOR
12
13#include "xstrided_view.hpp"
14#include "xtl/xsequence.hpp"
15
16namespace xt
17{
18
19 template <class S>
21 {
22 public:
23
25 using shape_type = S;
26
27 using value_type = shape_type;
28 using reference = value_type&;
29 using pointer = value_type*;
30 using difference_type = std::size_t;
31 using iterator_category = std::forward_iterator_tag;
32
33 xmultiindex_iterator() = default;
34
35 template <class B, class E, class C>
36 xmultiindex_iterator(B&& begin, E&& end, C&& current, const std::size_t linear_index)
37 : m_begin(std::forward<B>(begin))
38 , m_end(std::forward<E>(end))
39 , m_current(std::forward<C>(current))
40 , m_linear_index(linear_index)
41 {
42 }
43
44 self_type& operator++()
45 {
46 std::size_t i = m_begin.size();
47 while (i != 0)
48 {
49 --i;
50 if (m_current[i] + 1u == m_end[i])
51 {
52 m_current[i] = m_begin[i];
53 }
54 else
55 {
56 m_current[i] += 1;
57 break;
58 }
59 }
60 m_linear_index++;
61 return *this;
62 }
63
64 self_type operator++(int)
65 {
66 self_type it = *this;
67 ++(*this);
68 return it;
69 }
70
71 shape_type& operator*()
72 {
73 return m_current;
74 }
75
76 const shape_type& operator*() const
77 {
78 return m_current;
79 }
80
81 bool operator==(const self_type& rhs) const
82 {
83 return m_linear_index == rhs.m_linear_index;
84 }
85
86 bool operator!=(const self_type& rhs) const
87 {
88 return !this->operator==(rhs);
89 }
90
91 private:
92
93 shape_type m_begin;
94 shape_type m_end;
95 shape_type m_current;
96 std::size_t m_linear_index{0};
97 };
98
99 template <class S, class B, class E>
100 auto multiindex_iterator_begin(B&& roi_begin, E&& roi_end)
101 {
102 S current;
103 resize_container(current, roi_begin.size());
104 std::copy(roi_begin.begin(), roi_begin.end(), current.begin());
105 return xmultiindex_iterator<S>(std::forward<B>(roi_begin), std::forward<E>(roi_end), std::move(current), 0);
106 }
107
108 template <class S, class B, class E>
109 auto multiindex_iterator_end(B&& roi_begin, E&& roi_end)
110 {
111 S current;
112 resize_container(current, roi_begin.size());
113 std::copy(roi_end.begin(), roi_end.end(), current.begin());
114
115 std::size_t linear_index = 1;
116 for (std::size_t i = 0; i < roi_begin.size(); ++i)
117 {
118 linear_index *= roi_end[i] - roi_begin[i];
119 }
120
121 return xmultiindex_iterator<S>(
122 std::forward<B>(roi_begin),
123 std::forward<E>(roi_end),
124 std::move(current),
125 linear_index
126 );
127 }
128
129}
130
131#endif
standard mathematical functions for xexpressions