annotate parallel-libs/acxxel/span.h @ 180:680fa57a2f20

fix compile errors.
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 30 May 2020 17:44:06 +0900
parents 1d019706d866
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===--- span- The span class -----------------------------------*- C++ -*-===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #ifndef ACXXEL_SPAN_H
anatofuz
parents:
diff changeset
10 #define ACXXEL_SPAN_H
anatofuz
parents:
diff changeset
11
anatofuz
parents:
diff changeset
12 #include <array>
anatofuz
parents:
diff changeset
13 #include <cstddef>
anatofuz
parents:
diff changeset
14 #include <exception>
anatofuz
parents:
diff changeset
15 #include <iterator>
anatofuz
parents:
diff changeset
16 #include <type_traits>
anatofuz
parents:
diff changeset
17
anatofuz
parents:
diff changeset
18 namespace acxxel {
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 /// Value used to indicate slicing to the end of the span.
anatofuz
parents:
diff changeset
21 static constexpr std::ptrdiff_t dynamic_extent = -1; // NOLINT
anatofuz
parents:
diff changeset
22
anatofuz
parents:
diff changeset
23 class SpanBase {};
anatofuz
parents:
diff changeset
24
anatofuz
parents:
diff changeset
25 /// Implementation of the proposed C++17 std::span class.
anatofuz
parents:
diff changeset
26 ///
anatofuz
parents:
diff changeset
27 /// Based on the paper:
anatofuz
parents:
diff changeset
28 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0122r1.pdf
anatofuz
parents:
diff changeset
29 template <typename ElementType> class Span : public SpanBase {
anatofuz
parents:
diff changeset
30 public:
anatofuz
parents:
diff changeset
31 /// \name constants and types
anatofuz
parents:
diff changeset
32 /// \{
anatofuz
parents:
diff changeset
33
anatofuz
parents:
diff changeset
34 using element_type = ElementType;
anatofuz
parents:
diff changeset
35 using index_type = std::ptrdiff_t;
anatofuz
parents:
diff changeset
36 using pointer = element_type *;
anatofuz
parents:
diff changeset
37 using reference = element_type &;
anatofuz
parents:
diff changeset
38 using iterator = element_type *;
anatofuz
parents:
diff changeset
39 using const_iterator = const element_type *;
anatofuz
parents:
diff changeset
40 using value_type = typename std::remove_const<element_type>::type;
anatofuz
parents:
diff changeset
41
anatofuz
parents:
diff changeset
42 /// \}
anatofuz
parents:
diff changeset
43
anatofuz
parents:
diff changeset
44 /// \name constructors, copy, assignment, and destructor.
anatofuz
parents:
diff changeset
45 /// \{
anatofuz
parents:
diff changeset
46
anatofuz
parents:
diff changeset
47 /// Constructs an empty span with null pointer data.
anatofuz
parents:
diff changeset
48 Span() : Data(nullptr), Size(0) {}
anatofuz
parents:
diff changeset
49
anatofuz
parents:
diff changeset
50 /// Constructs an empty span with null pointer data.
anatofuz
parents:
diff changeset
51 // Intentionally implicit.
anatofuz
parents:
diff changeset
52 Span(std::nullptr_t) : Data(nullptr), Size(0) {}
anatofuz
parents:
diff changeset
53
anatofuz
parents:
diff changeset
54 /// Constructs a span from a pointer and element count.
anatofuz
parents:
diff changeset
55 Span(pointer Ptr, index_type Count) : Data(Ptr), Size(Count) {
anatofuz
parents:
diff changeset
56 if (Count < 0 || (!Ptr && Count))
anatofuz
parents:
diff changeset
57 std::terminate();
anatofuz
parents:
diff changeset
58 }
anatofuz
parents:
diff changeset
59
anatofuz
parents:
diff changeset
60 /// Constructs a span from a pointer to the fist element in the range and a
anatofuz
parents:
diff changeset
61 /// pointer to one past the last element in the range.
anatofuz
parents:
diff changeset
62 Span(pointer FirstElem, pointer LastElem)
anatofuz
parents:
diff changeset
63 : Data(FirstElem), Size(std::distance(FirstElem, LastElem)) {
anatofuz
parents:
diff changeset
64 if (Size < 0)
anatofuz
parents:
diff changeset
65 std::terminate();
anatofuz
parents:
diff changeset
66 }
anatofuz
parents:
diff changeset
67
anatofuz
parents:
diff changeset
68 /// Constructs a span from an array.
anatofuz
parents:
diff changeset
69 // Intentionally implicit.
anatofuz
parents:
diff changeset
70 template <typename T, size_t N> Span(T (&Arr)[N]) : Data(Arr), Size(N) {}
anatofuz
parents:
diff changeset
71
anatofuz
parents:
diff changeset
72 /// Constructs a span from a std::array.
anatofuz
parents:
diff changeset
73 // Intentionally implicit.
anatofuz
parents:
diff changeset
74 template <size_t N>
anatofuz
parents:
diff changeset
75 Span(const std::array<typename std::remove_const<element_type>::type, N> &Arr)
anatofuz
parents:
diff changeset
76 : Data(Arr.data()), Size(N) {}
anatofuz
parents:
diff changeset
77
anatofuz
parents:
diff changeset
78 /// Constructs a span from a container such as a std::vector.
anatofuz
parents:
diff changeset
79 // TODO(jhen): Put in a check to make sure this constructor does not
anatofuz
parents:
diff changeset
80 // participate in overload resolution unless Container meets the following
anatofuz
parents:
diff changeset
81 // requirements:
anatofuz
parents:
diff changeset
82 // * Container is a contiguous container and a sequence container.
anatofuz
parents:
diff changeset
83 // Intentionally implicit.
anatofuz
parents:
diff changeset
84 template <typename Container>
anatofuz
parents:
diff changeset
85 Span(Container &Cont,
anatofuz
parents:
diff changeset
86 typename std::enable_if<
anatofuz
parents:
diff changeset
87 std::is_same<
anatofuz
parents:
diff changeset
88 typename std::remove_const<typename Container::value_type>::type,
anatofuz
parents:
diff changeset
89 typename std::remove_const<element_type>::type>::value &&
anatofuz
parents:
diff changeset
90 !std::is_array<Container>::value &&
anatofuz
parents:
diff changeset
91 !std::is_base_of<SpanBase, Container>::value &&
anatofuz
parents:
diff changeset
92 std::is_convertible<decltype(&Cont[0]), pointer>::value>::type * =
anatofuz
parents:
diff changeset
93 nullptr)
anatofuz
parents:
diff changeset
94 : Data(Cont.data()), Size(Cont.size()) {}
anatofuz
parents:
diff changeset
95
anatofuz
parents:
diff changeset
96 /// Avoids creating spans from expiring temporary objects.
anatofuz
parents:
diff changeset
97 // TODO(jhen): Put in a check to make sure this constructor does not
anatofuz
parents:
diff changeset
98 // participate in overload resolution unless Container meets the following
anatofuz
parents:
diff changeset
99 // requirements:
anatofuz
parents:
diff changeset
100 // * Container is a contiguous container and a sequence container.
anatofuz
parents:
diff changeset
101 template <typename Container>
anatofuz
parents:
diff changeset
102 Span(Container &&Cont,
anatofuz
parents:
diff changeset
103 typename std::enable_if<
anatofuz
parents:
diff changeset
104 std::is_same<
anatofuz
parents:
diff changeset
105 typename std::remove_const<typename Container::value_type>::type,
anatofuz
parents:
diff changeset
106 typename std::remove_const<element_type>::type>::value &&
anatofuz
parents:
diff changeset
107 !std::is_array<Container>::value &&
anatofuz
parents:
diff changeset
108 !std::is_base_of<SpanBase, Container>::value &&
anatofuz
parents:
diff changeset
109 std::is_convertible<decltype(&Cont[0]), pointer>::value>::type * =
anatofuz
parents:
diff changeset
110 nullptr) = delete;
anatofuz
parents:
diff changeset
111
anatofuz
parents:
diff changeset
112 Span(const Span &) noexcept = default;
anatofuz
parents:
diff changeset
113 Span(Span &&) noexcept;
anatofuz
parents:
diff changeset
114
anatofuz
parents:
diff changeset
115 /// Constructs a span from copying a span of another type that can be
anatofuz
parents:
diff changeset
116 /// implicitly converted to the type stored by the constructed span.
anatofuz
parents:
diff changeset
117 // Intentionally implicit.
anatofuz
parents:
diff changeset
118 template <typename OtherElementType>
anatofuz
parents:
diff changeset
119 Span(const Span<OtherElementType> &Other)
anatofuz
parents:
diff changeset
120 : Data(Other.Data), Size(Other.Size) {}
anatofuz
parents:
diff changeset
121
anatofuz
parents:
diff changeset
122 /// Constructs a span from moving a span of another type that can be
anatofuz
parents:
diff changeset
123 /// implicitly converted to the type stored by the constructed span.
anatofuz
parents:
diff changeset
124 // Intentionally implicit.
anatofuz
parents:
diff changeset
125 template <typename OtherElementType>
anatofuz
parents:
diff changeset
126 Span(Span<OtherElementType> &&Other) : Data(Other.Data), Size(Other.Size) {}
anatofuz
parents:
diff changeset
127
anatofuz
parents:
diff changeset
128 ~Span() = default;
anatofuz
parents:
diff changeset
129
anatofuz
parents:
diff changeset
130 Span &operator=(const Span &) noexcept = default;
anatofuz
parents:
diff changeset
131 Span &operator=(Span &&) noexcept;
anatofuz
parents:
diff changeset
132
anatofuz
parents:
diff changeset
133 /// \}
anatofuz
parents:
diff changeset
134
anatofuz
parents:
diff changeset
135 /// \name subviews
anatofuz
parents:
diff changeset
136 /// \{
anatofuz
parents:
diff changeset
137
anatofuz
parents:
diff changeset
138 /// Creates a span out of the first Count elements of this span.
anatofuz
parents:
diff changeset
139 Span<element_type> first(index_type Count) const {
anatofuz
parents:
diff changeset
140 bool Valid = Count >= 0 && Count <= size();
anatofuz
parents:
diff changeset
141 if (!Valid)
anatofuz
parents:
diff changeset
142 std::terminate();
anatofuz
parents:
diff changeset
143 return Span<element_type>(data(), Count);
anatofuz
parents:
diff changeset
144 }
anatofuz
parents:
diff changeset
145
anatofuz
parents:
diff changeset
146 /// Creates a span out of the last Count elements of this span.
anatofuz
parents:
diff changeset
147 Span<element_type> last(index_type Count) const {
anatofuz
parents:
diff changeset
148 bool Valid = Count >= 0 && Count <= size();
anatofuz
parents:
diff changeset
149 if (!Valid)
anatofuz
parents:
diff changeset
150 std::terminate();
anatofuz
parents:
diff changeset
151 return Span<element_type>(Count == 0 ? data() : data() + (size() - Count),
anatofuz
parents:
diff changeset
152 Count);
anatofuz
parents:
diff changeset
153 }
anatofuz
parents:
diff changeset
154
anatofuz
parents:
diff changeset
155 /// Creates a span out of the Count elements of this span beginning at Offset.
anatofuz
parents:
diff changeset
156 ///
anatofuz
parents:
diff changeset
157 /// If no arguments is provided for Count, the new span will extend to the end
anatofuz
parents:
diff changeset
158 /// of the current span.
anatofuz
parents:
diff changeset
159 Span<element_type> subspan(index_type Offset,
anatofuz
parents:
diff changeset
160 index_type Count = dynamic_extent) const {
anatofuz
parents:
diff changeset
161 bool Valid =
anatofuz
parents:
diff changeset
162 (Offset == 0 || (Offset > 0 && Offset <= size())) &&
anatofuz
parents:
diff changeset
163 (Count == dynamic_extent || (Count >= 0 && Offset + Count <= size()));
anatofuz
parents:
diff changeset
164 if (!Valid)
anatofuz
parents:
diff changeset
165 std::terminate();
anatofuz
parents:
diff changeset
166 return Span<element_type>(
anatofuz
parents:
diff changeset
167 data() + Offset, Count == dynamic_extent ? size() - Offset : Count);
anatofuz
parents:
diff changeset
168 }
anatofuz
parents:
diff changeset
169
anatofuz
parents:
diff changeset
170 /// \}
anatofuz
parents:
diff changeset
171
anatofuz
parents:
diff changeset
172 /// \name observers
anatofuz
parents:
diff changeset
173 /// \{
anatofuz
parents:
diff changeset
174
anatofuz
parents:
diff changeset
175 index_type length() const { return Size; }
anatofuz
parents:
diff changeset
176 index_type size() const { return Size; }
anatofuz
parents:
diff changeset
177 bool empty() const { return size() == 0; }
anatofuz
parents:
diff changeset
178
anatofuz
parents:
diff changeset
179 /// \}
anatofuz
parents:
diff changeset
180
anatofuz
parents:
diff changeset
181 /// \name element access
anatofuz
parents:
diff changeset
182 /// \{
anatofuz
parents:
diff changeset
183
anatofuz
parents:
diff changeset
184 reference operator[](index_type Idx) const {
anatofuz
parents:
diff changeset
185 bool Valid = Idx >= 0 && Idx < size();
anatofuz
parents:
diff changeset
186 if (!Valid)
anatofuz
parents:
diff changeset
187 std::terminate();
anatofuz
parents:
diff changeset
188 return Data[Idx];
anatofuz
parents:
diff changeset
189 }
anatofuz
parents:
diff changeset
190
anatofuz
parents:
diff changeset
191 reference operator()(index_type Idx) const { return operator[](Idx); }
anatofuz
parents:
diff changeset
192
anatofuz
parents:
diff changeset
193 pointer data() const noexcept { return Data; }
anatofuz
parents:
diff changeset
194
anatofuz
parents:
diff changeset
195 /// \}
anatofuz
parents:
diff changeset
196
anatofuz
parents:
diff changeset
197 /// \name iterator support
anatofuz
parents:
diff changeset
198 /// \{
anatofuz
parents:
diff changeset
199
anatofuz
parents:
diff changeset
200 iterator begin() const noexcept { return Data; }
anatofuz
parents:
diff changeset
201 iterator end() const noexcept { return Data + Size; }
anatofuz
parents:
diff changeset
202 const_iterator cbegin() const noexcept { return Data; }
anatofuz
parents:
diff changeset
203 const_iterator cend() const noexcept { return Data + Size; }
anatofuz
parents:
diff changeset
204
anatofuz
parents:
diff changeset
205 /// \}
anatofuz
parents:
diff changeset
206
anatofuz
parents:
diff changeset
207 private:
anatofuz
parents:
diff changeset
208 template <typename OtherElementType> friend class Span;
anatofuz
parents:
diff changeset
209
anatofuz
parents:
diff changeset
210 pointer Data;
anatofuz
parents:
diff changeset
211 index_type Size;
anatofuz
parents:
diff changeset
212 };
anatofuz
parents:
diff changeset
213
anatofuz
parents:
diff changeset
214 template <typename ElementType>
anatofuz
parents:
diff changeset
215 Span<ElementType>::Span(Span &&) noexcept = default;
anatofuz
parents:
diff changeset
216 template <typename ElementType>
anatofuz
parents:
diff changeset
217 Span<ElementType> &Span<ElementType>::operator=(Span &&) noexcept = default;
anatofuz
parents:
diff changeset
218
anatofuz
parents:
diff changeset
219 } // namespace acxxel
anatofuz
parents:
diff changeset
220
anatofuz
parents:
diff changeset
221 #endif // ACXXEL_SPAN_H