CodePorting.Translator Cs2Cpp
CodePorting.Translator.Cs2Cpp.Framework
span.h
1
2#pragma once
3
4#include <algorithm>
5#include <type_traits>
6
7#include <system/array.h>
8#include <system/details/stack_array.h>
9#include <system/collections/ienumerator.h>
10#include <system/convert.h>
11#include <system/smart_ptr.h>
12#include <system/string.h>
13#include <system/exceptions.h>
14#include <system/make_const_ref.h>
15
16namespace System {
17
18namespace Details {
19
22template <typename T, typename Span, typename MutableSpan>
23class SpanCore
24{
25protected:
26 using MutableT = std::remove_const_t<T>;
27 using RefrerenceT = std::conditional_t<std::is_const<T>::value, MakeConstRef_t<MutableT>, T&>;
28 using ArrayPtrT = System::ArrayPtr<MutableT>;
29 using VoidPtrT = std::conditional_t<std::is_const<std::remove_pointer_t<T>>::value, const void*, void*>;
30
31public:
34 class Enumerator
35 {
36 friend SpanCore;
37
38 SpanCore m_span;
39 int32_t m_idx = -1;
40
43 explicit Enumerator(const SpanCore& span) : m_span(span)
44 {}
45
46 public:
50 RefrerenceT get_Current()
51 {
52 if (m_idx < 0 || m_idx >= m_span.get_Length())
53 {
54 throw IndexOutOfRangeException(u"index");
55 }
56
57 return m_span.get(m_idx);
58 }
59
62 bool MoveNext()
63 {
64 if (m_idx < m_span.get_Length())
65 {
66 m_idx++;
67 }
68
69 return m_idx < m_span.get_Length();
70 }
71
73 void Reset()
74 {
75 m_idx = -1;
76 }
77 };
78
79public:
81 SpanCore() : SpanCore(nullptr, nullptr, 0)
82 {}
83
86 SpanCore(const ArrayPtrT& array) : SpanCore(array, array == nullptr ? nullptr : array->data_ptr(), array == nullptr ? 0 : array->get_Length())
87 {}
88
92 template <int32_t Size>
93 SpanCore(Details::StackArray<MutableT, Size>& stack_array) : SpanCore(stack_array.data(), Size)
94 {}
95
100 SpanCore(VoidPtrT pointer, int32_t length) : SpanCore(nullptr, (T*)pointer, length)
101 {
102 if (length < 0)
103 {
104 throw ArgumentOutOfRangeException(u"length");
105 }
106 }
107
113 SpanCore(const ArrayPtrT& array, int32_t start, int32_t length) : SpanCore(array, array->data_ptr() + start, length)
114 {
115 if (array == nullptr)
116 {
117 if (start != 0)
118 {
119 throw ArgumentOutOfRangeException(u"start");
120 }
121 if (length != 0)
122 {
123 throw ArgumentOutOfRangeException(u"length");
124 }
125 }
126 else
127 {
128 if (start < 0 || (start > 0 && start >= array->get_Length()))
129 {
130 throw ArgumentOutOfRangeException(u"start");
131 }
132 if (start + length > array->get_Length())
133 {
134 throw ArgumentOutOfRangeException(u"length");
135 }
136 }
137 }
138
141 static Span get_Empty()
142 {
143 return Span(nullptr, nullptr, 0);
144 }
145
148 Enumerator GetEnumerator() const
149 {
150 return Enumerator(*this);
151 }
152
155 int32_t GetHashCode() const
156 {
157 throw NotSupportedException();
158 }
159
162 bool get_IsEmpty() const
163 {
164 return m_length == 0;
165 }
166
169 int32_t get_Length() const
170 {
171 return m_length;
172 }
173
178 Span Slice(int32_t start) const
179 {
180 return Slice(start, m_length - start);
181 }
182
188 Span Slice(int32_t start, int32_t length) const
189 {
190 if (start < 0)
191 {
192 throw ArgumentOutOfRangeException(u"start");
193 }
194 else if (length < 0 || start + length > m_length)
195 {
196 throw ArgumentOutOfRangeException(u"length");
197 }
198
199 return Span(m_array, m_pointer + start, length);
200 }
201
205 void CopyTo(MutableSpan destination) const
206 {
207 if (m_length > destination.get_Length())
208 {
209 throw ArgumentException(u"destination");
210 }
211
212 std::copy(cbegin(), cend(), destination.begin());
213 }
214
218 bool TryCopyTo(MutableSpan destination) const
219 {
220 if (m_length > destination.get_Length())
221 {
222 return false;
223 }
224
225 std::copy(cbegin(), cend(), destination.begin());
226
227 return true;
228 }
229
232 ArrayPtrT ToArray() const
233 {
234 auto result = System::MakeArray<MutableT>(m_length);
235
236 std::copy(cbegin(), cend(), result->begin());
237
238 return result;
239 }
240
244 template <typename T1 = MutableT>
245 typename std::enable_if<std::is_same<T1, char16_t>::value, String>::type ToString() const
246 {
247 return System::String(ToArray());
248 }
249
253 template <typename T1 = MutableT>
254 typename std::enable_if<!std::is_same<T1, char16_t>::value, String>::type ToString() const
255 {
256 return u"System::Span<T>[" + System::Convert::ToString(m_length) + u"]";
257 }
258
259public:
260 // Iterator support
261 T* begin() const noexcept
262 {
263 return m_pointer;
264 }
265
266 T* end() const noexcept
267 {
268 return m_pointer + m_length;
269 }
270
271 const T* cbegin() const noexcept
272 {
273 return m_pointer;
274 }
275
276 const T* cend() const noexcept
277 {
278 return m_pointer + m_length;
279 }
280
281 T* rbegin() const noexcept
282 {
283 return m_pointer + m_length;
284 }
285
286 T* rend() const noexcept
287 {
288 return m_pointer;
289 }
290
291 const T* crbegin() const noexcept
292 {
293 return m_pointer + m_length;
294 }
295
296 const T* crend() const noexcept
297 {
298 return m_pointer;
299 }
300
305 RefrerenceT operator[](int32_t index) const
306 {
307 if (index < 0 || index >= m_length)
308 {
309 throw IndexOutOfRangeException(u"index");
310 }
311
312 return *(m_pointer + index);
313 }
314
317 RefrerenceT get(int32_t index) const
318 {
319 return *(m_pointer + index);
320 }
321
325 bool operator==(const SpanCore& right) const
326 {
327 return m_pointer == right.m_pointer && m_length == right.m_length;
328 }
329
330protected:
335 SpanCore(const ArrayPtrT& array, T* pointer, int32_t length)
336 : m_array(array), m_pointer(pointer), m_length(length)
337 {}
338
339 T* m_pointer;
340 int32_t m_length;
341 ArrayPtrT m_array;
342};
343
344} // namespace Details
345
347template <typename T>
348class ReadOnlySpan;
349
355template <typename T>
356class Span : public Details::SpanCore<T, Span<T>, Span<T>>
357{
358 typedef Span<T> ThisType;
359 typedef typename Details::SpanCore<T, Span<T>, Span<T>> BaseType;
360
361 friend BaseType;
362 friend ReadOnlySpan<T>;
363
364public:
365 using Details::SpanCore<T, Span<T>, Span<T>>::SpanCore;
366
368 void Clear() const
369 {
370 std::fill(this->begin(), this->end(), System::Default<T>());
371 }
372
375 void Fill(const T& value) const
376 {
377 std::fill(this->begin(), this->end(), value);
378 }
379
383 static ThisType to_Span(const typename BaseType::ArrayPtrT& array)
384 {
385 return ThisType(array);
386 }
387};
388
394template <typename T>
395class ReadOnlySpan : public Details::SpanCore<const T, ReadOnlySpan<T>, Span<T>>
396{
398 typedef typename Details::SpanCore<const T, ReadOnlySpan<T>, Span<T>> BaseType;
399
400 friend BaseType;
401
402public:
403 using Details::SpanCore<const T, ReadOnlySpan<T>, Span<T>>::SpanCore;
404
407 ReadOnlySpan(const Span<T>& span) : BaseType(span.m_array, span.m_pointer, span.m_length)
408 {}
409
413 static ThisType to_ReadOnlySpan(const typename BaseType::ArrayPtrT& array)
414 {
415 return ThisType(array);
416 }
417};
418
419} // namespace System
Forward to use within Span class.
Definition: span.h:396
static ThisType to_ReadOnlySpan(const typename BaseType::ArrayPtrT &array)
Converts an array to a ReadOnlySpan.
Definition: span.h:413
ReadOnlySpan(const Span< T > &span)
Constructs a read-only span from a regular span.
Definition: span.h:407
Pointer class to wrap types being allocated on heap. Use it to manage memory for classes inheriting O...
Definition: smart_ptr.h:180
Represents a contiguous region of arbitrary memory similar to C++20's std::span.
Definition: span.h:357
void Clear() const
Clears the contents of the span by setting all elements to default value.
Definition: span.h:368
static ThisType to_Span(const typename BaseType::ArrayPtrT &array)
Converts an array to a Span.
Definition: span.h:383
void Fill(const T &value) const
Fills the span with the specified value.
Definition: span.h:375
String class used across the library. Is a substitute for C# System.String when translating code....
Definition: string.h:122
void CopyTo(const ArrayPtr< T > &source, Span< T > &destination)
Copies elements from an array to a span.
Definition: memory_extensions.h:953
Definition: db_command.h:9
std::enable_if< std::is_scalar< T >::value, int >::type GetHashCode(const T &obj)
Returns a hash code for the specified scalar value.
Definition: get_hash_code.h:21
bool operator==(ArraySegment< T > a, ArraySegment< T > b)
Definition: array_segment.h:150
static String ToString(int8_t value)
Converts the specified value to its string representation.