CodePorting.Translator Cs2Cpp
CodePorting.Translator.Cs2Cpp.Framework
memory_extensions.h
1
2#ifndef _aspose_system_memory_extensions_h_
3#define _aspose_system_memory_extensions_h_
4
5#include <type_traits>
6#include <array>
7#include <system/span.h>
8#include <system/object.h>
9#include <system/object_ext.h>
10#include <system/details/stack_array.h>
11#include <system/smart_ptr.h>
12#include <system/exceptions.h>
13#include <system/comparison.h>
14
15namespace System {
16
18namespace MemoryExtensions {
19namespace Details {
21extern ASPOSECPP_SHARED_API const std::array<char16_t, 22> DefaultWhitespaceChars;
22
24extern ASPOSECPP_SHARED_API const ReadOnlySpan<char16_t> DefaultWhitespaceSpan;
25
32template <typename T, typename U>
33int32_t Compare(const SharedPtr<T>& a, const SharedPtr<U>& b);
34
40template <typename T>
41int32_t // typename std::enable_if<std::is_arithmetic<T>::value, int32_t>::type
42 Compare(const T& a, const T& b);
43
50template <typename T, typename U>
51int32_t Compare(const SharedPtr<T>& a, const U& b);
52
53
60template <typename T>
61int32_t LastIndexOfImpl(const ReadOnlySpan<T>& searchSpace, int32_t length, const T& value);
62
63
71template <typename T>
72bool SequenceEqualImpl(const ReadOnlySpan<T>& first, const int32_t start, int32_t length, const ReadOnlySpan<T>& second);
73
81template <typename TKey, typename TValue>
82void IntroSort(Span<TKey>& keys, Span<TValue>& values, int32_t depthLimit,
83 std::function<int32_t(const TKey&, const TKey&)> comparer);
84
93template <typename TKey, typename TValue>
95 std::function<int32_t(const TKey&, const TKey&)> comparer, int32_t i, int32_t j);
96
103template <typename TKey, typename TValue>
104void InsertionSort(Span<TKey>& keys, Span<TValue>& values, std::function<int32_t(const TKey&, const TKey&)> comparer);
105
112template <typename TKey, typename TValue>
113void HeapSort(Span<TKey>& keys, Span<TValue>& values, std::function<int32_t(const TKey&, const TKey&)> comparer);
114
123template <typename TKey, typename TValue>
124void Heapify(Span<TKey>& keys, Span<TValue>& values, int32_t n, int32_t i,
125 std::function<int32_t(const TKey&, const TKey&)> comparer);
126
134template <typename TKey, typename TValue>
135int32_t PickPivotAndPartition(Span<TKey>& keys, Span<TValue>& values,
136 std::function<int32_t(const TKey&, const TKey&)> comparer);
137
146template <typename T, typename TValue, typename TCompareFunc>
147int32_t BinarySearchImpl(const ReadOnlySpan<T>& span, const TValue& value, TCompareFunc compareFunc);
148
149template <typename T, typename U>
150int32_t Compare(const SharedPtr<T>& a, const SharedPtr<U>& b)
151{
152 if (!a && !b)
153 {
154 return 0;
155 }
156 if (!a)
157 {
158 return -1;
159 }
160 if (!b)
161 {
162 return 1;
163 }
164 // assume T implements IComparable<Ptr<U>>
165 return (*a).CompareTo(b);
166}
167
168template <typename T>
169int32_t // typename std::enable_if<std::is_arithmetic<T>::value, int32_t>::type
170 Compare(const T& a, const T& b)
171{
172 return System::Compare(a, b);
173}
174
175template <typename T, typename U>
176int32_t Compare(const SharedPtr<T>& a, const U& b)
177{
178 // assume T implements IComparable<U>
179 return (*a).CompareTo(b);
180}
181
182template <typename T>
183int32_t LastIndexOfImpl(const ReadOnlySpan<T>& searchSpace, int32_t length, const T& value)
184{
185 // TODO if value is null find null
186 if (length < 0)
187 return -1;
188
189 while (length >= 8)
190 {
191 length -= 8;
192 if (System::ObjectExt::Equals(value, searchSpace.get(length + 7)))
193 return length + 7;
194 if (System::ObjectExt::Equals(value, searchSpace.get(length + 6)))
195 return length + 6;
196 if (System::ObjectExt::Equals(value, searchSpace.get(length + 5)))
197 return length + 5;
198 if (System::ObjectExt::Equals(value, searchSpace.get(length + 4)))
199 return length + 4;
200 if (System::ObjectExt::Equals(value, searchSpace.get(length + 3)))
201 return length + 3;
202 if (System::ObjectExt::Equals(value, searchSpace.get(length + 2)))
203 return length + 2;
204 if (System::ObjectExt::Equals(value, searchSpace.get(length + 1)))
205 return length + 1;
206 if (System::ObjectExt::Equals(value, searchSpace.get(length)))
207 return length;
208 }
209
210 while (length > 0)
211 {
212 length--;
213 if (System::ObjectExt::Equals(value, searchSpace.get(length)))
214 {
215 return length;
216 }
217 }
218
219 return -1;
220}
221
222template <typename T>
223bool SequenceEqualImpl(const ReadOnlySpan<T>& first, const int32_t start, int32_t length, const ReadOnlySpan<T>& second)
224{
225 int32_t index = 0;
226
227 // Process 8 elements at a time
228 while (length >= 8)
229 {
230 if (!(System::ObjectExt::Equals(first.get(index + start), second.get(index))) ||
231 !(System::ObjectExt::Equals(first.get(index + start + 1), second.get(index + 1))) ||
232 !(System::ObjectExt::Equals(first.get(index + start + 2), second.get(index + 2))) ||
233 !(System::ObjectExt::Equals(first.get(index + start + 3), second.get(index + 3))) ||
234 !(System::ObjectExt::Equals(first.get(index + start + 4), second.get(index + 4))) ||
235 !(System::ObjectExt::Equals(first.get(index + start + 5), second.get(index + 5))) ||
236 !(System::ObjectExt::Equals(first.get(index + start + 6), second.get(index + 6))) ||
237 !(System::ObjectExt::Equals(first.get(index + start + 7), second.get(index + 7))))
238 {
239 return false;
240 }
241
242 index += 8;
243 length -= 8;
244 }
245
246 // Process remaining elements one by one
247 while (length > 0)
248 {
249 if (!(System::ObjectExt::Equals(first.get(index + start), second.get(index))))
250 {
251 return false;
252 }
253 index++;
254 length--;
255 }
256 return true;
257}
258
259template <typename TKey, typename TValue>
260void IntroSort(Span<TKey>& keys, Span<TValue>& values, int32_t depthLimit,
261 std::function<int32_t(const TKey&, const TKey&)> comparer)
262{
263 int32_t partitionSize = keys.get_Length();
264 while (partitionSize > 1)
265 {
266 if (partitionSize <= 16)
267 { // IntrosortSizeThreshold = 16
268 if (partitionSize == 2)
269 {
270 SwapIfGreaterWithValues(keys, values, comparer, 0, 1);
271 return;
272 }
273
274 if (partitionSize == 3)
275 {
276 SwapIfGreaterWithValues(keys, values, comparer, 0, 1);
277 SwapIfGreaterWithValues(keys, values, comparer, 0, 2);
278 SwapIfGreaterWithValues(keys, values, comparer, 1, 2);
279 return;
280 }
281
282 InsertionSort(keys, values, comparer);
283 return;
284 }
285
286 if (depthLimit == 0)
287 {
288 HeapSort(keys, values, comparer);
289 return;
290 }
291 depthLimit--;
292
293 int32_t p = PickPivotAndPartition(keys, values, comparer);
294
295 // Handle the case where pivot is at the end
296 int32_t rightSize = partitionSize - p - 1;
297 if (rightSize > 0)
298 {
299 IntroSort(keys.Slice(p + 1, rightSize), values.Slice(p + 1, rightSize), depthLimit, comparer);
300 }
301
302 // Handle the case where pivot is at the beginning
303 partitionSize = p;
304 }
305}
306
307template <typename TKey, typename TValue>
309 std::function<int32_t(const TKey&, const TKey&)> comparer, int32_t i, int32_t j)
310{
311 if (comparer(keys.get(i), keys.get(j)) > 0)
312 {
313 std::swap(keys.get(i), keys.get(j));
314 std::swap(values.get(i), values.get(j));
315 }
316}
317
318template <typename TKey, typename TValue>
319void InsertionSort(Span<TKey>& keys, Span<TValue>& values, std::function<int32_t(const TKey&, const TKey&)> comparer)
320{
321 for (int32_t i = 0; i < keys.get_Length() - 1; i++)
322 {
323 TKey t = keys.get(i + 1);
324 TValue tValue = values.get(i + 1);
325
326 int32_t j = i;
327 while (j >= 0 && keys.get(j) != t && !comparer(t, keys.get(j)))
328 {
329 keys.get(j + 1) = keys.get(j);
330 values.get(j + 1) = values.get(j);
331 j--;
332 }
333
334 keys.get(j + 1) = t;
335 values.get(j + 1) = tValue;
336 }
337}
338
339template <typename TKey, typename TValue>
340void HeapSort(Span<TKey>& keys, Span<TValue>& values, std::function<int32_t(const TKey&, const TKey&)> comparer)
341{
342 // Build max heap
343 for (int32_t i = keys.get_Length() / 2 - 1; i >= 0; i--)
344 {
345 Heapify(keys, values, keys.get_Length(), i, comparer);
346 }
347
348 // Extract elements from heap one by one
349 for (int32_t i = keys.get_Length() - 1; i > 0; i--)
350 {
351 std::swap(keys.get(0), keys.get(i));
352 std::swap(values.get(0), values.get(i));
353 Heapify(keys, values, i, 0, comparer);
354 }
355}
356
357
358template <typename TKey, typename TValue>
359void Heapify(Span<TKey>& keys, Span<TValue>& values, int32_t n, int32_t i,
360 std::function<int32_t(const TKey&, const TKey&)> comparer)
361{
362 int32_t largest = i;
363 int32_t left = 2 * i + 1;
364 int32_t right = 2 * i + 2;
365
366 if (left < n && comparer(keys.get(left), keys.get(largest)) > 0)
367 {
368 largest = left;
369 }
370
371 if (right < n && comparer(keys.get(right), keys.get(largest)) > 0)
372 {
373 largest = right;
374 }
375
376 if (largest != i)
377 {
378 std::swap(keys.get(i), keys.get(largest));
379 std::swap(values.get(i), values.get(largest));
380 Heapify(keys, values, n, largest, comparer);
381 }
382}
383
384template <typename TKey, typename TValue>
386 std::function<int32_t(const TKey&, const TKey&)> comparer)
387{
388 // Use median-of-three pivot selection
389 int32_t middle = keys.get_Length() / 2;
390 int32_t last = keys.get_Length() - 1;
391
392 // Sort first, middle, last
393 if (comparer(keys.get(0), keys.get(middle)) > 0)
394 {
395 std::swap(keys.get(0), keys.get(middle));
396 std::swap(values.get(0), values.get(middle));
397 }
398 if (comparer(keys.get(0), keys.get(last)) > 0)
399 {
400 std::swap(keys.get(0), keys.get(last));
401 std::swap(values.get(0), values.get(last));
402 }
403 if (comparer(keys.get(middle), keys.get(last)) > 0)
404 {
405 std::swap(keys.get(middle), keys.get(last));
406 std::swap(values.get(middle), values.get(last));
407 }
408
409 // Place pivot at last position
410 std::swap(keys.get(middle), keys.get(last));
411 std::swap(values.get(middle), values.get(last));
412
413 TKey pivot = keys.get(last);
414 int32_t i = -1;
415
416 for (int32_t j = 0; j < last; j++)
417 {
418 if (comparer(keys.get(j), pivot) <= 0)
419 {
420 i++;
421 std::swap(keys.get(i), keys.get(j));
422 std::swap(values.get(i), values.get(j));
423 }
424 }
425
426 std::swap(keys.get(i + 1), keys.get(last));
427 std::swap(values.get(i + 1), values.get(last));
428 return i + 1;
429}
430
431template <typename T, typename TValue, typename TCompareFunc>
432int32_t BinarySearchImpl(const ReadOnlySpan<T>& span, const TValue& value, TCompareFunc compareFunc)
433{
434 int32_t lo = 0;
435 int32_t hi = span.get_Length() - 1;
436
437 while (lo <= hi)
438 {
439 // Safe unsigned arithmetic to avoid overflow
440 int32_t i = static_cast<int32_t>((static_cast<uint32_t>(hi) + static_cast<uint32_t>(lo)) >> 1);
441 int32_t c = compareFunc(value, span.get(i));
442 if (c == 0)
443 {
444 return i;
445 }
446 else if (c > 0)
447 {
448 lo = i + 1;
449 }
450 else
451 {
452 hi = i - 1;
453 }
454 }
455
456 return ~lo;
457}
458
459} // namespace Details
460
467template <typename T>
468Span<T> AsSpan(const ArrayPtr<T>& array, int32_t start = 0, int32_t length = -1);
469
470
477template <typename T, typename TComparable>
478int32_t BinarySearch(const ReadOnlySpan<T>& span, const TComparable& comparable);
479
480
488template <typename T, typename TComparer>
489int32_t BinarySearch(const ReadOnlySpan<T>& span, const T& value, const SharedPtr<TComparer>& comparerPtr);
490
491
498template <typename T, typename TComparable>
499int32_t BinarySearch(const Span<T>& span, const TComparable& comparable);
500
501
509template <typename T, typename TComparer>
510int32_t BinarySearch(const Span<T>& span, const T& value, const SharedPtr<TComparer>& comparer);
511
512
518template <typename T>
519int32_t CommonPrefixLength(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& other);
520
521
527template <typename T>
528int32_t CommonPrefixLength(const Span<T>& span, const ReadOnlySpan<T>& other);
529
530
536template <typename T>
537int32_t CommonPrefixLength(const Span<T>& span, const Span<T>& other);
538
539
547template <typename T, typename TEqualityComparer>
548int32_t CommonPrefixLength(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& other,
549 const SharedPtr<TEqualityComparer>& comparer);
550
551
560template <typename T, typename TEqualityComparer>
561int32_t CommonPrefixLength(const Span<T>& span, const ReadOnlySpan<T>& other,
562 const SharedPtr<TEqualityComparer>& comparer);
563
564
572template <typename T, typename TEqualityComparer>
573int32_t CommonPrefixLength(const Span<T>& span, const Span<T>& other, const SharedPtr<TEqualityComparer>& comparer);
574
575
581template <typename T>
582bool Contains(const ReadOnlySpan<T>& span, const T& value);
583
584
590template <typename T>
591bool Contains(const Span<T>& span, const T& value);
592
593
600template <typename T>
601bool ContainsAny(const ReadOnlySpan<T>& span, const T& value0, const T& value1);
602
603
611template <typename T>
612bool ContainsAny(const ReadOnlySpan<T>& span, const T& value0, const T& value1, const T& value2);
613
614
621template <typename T>
622bool ContainsAny(const Span<T>& span, const T& value0, const T& value1);
623
624
632template <typename T>
633bool ContainsAny(const Span<T>& span, const T& value0, const T& value1, const T& value2);
634
635
641template <typename T>
642bool ContainsAny(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& values);
643
644
650template <typename T>
651bool ContainsAny(const Span<T>& span, const ReadOnlySpan<T>& values);
652
653
661template <typename T>
662bool ContainsAnyExcept(const ReadOnlySpan<T>& span, const T& value0, const T& value1, const T& value2);
663
664
672template <typename T>
673bool ContainsAnyExcept(const Span<T>& span, const T& value0, const T& value1, const T& value2);
674
675
682template <typename T>
683bool ContainsAnyExcept(const ReadOnlySpan<T>& span, const T& value0, const T& value1);
684
685
692template <typename T>
693bool ContainsAnyExcept(const Span<T>& span, const T& value0, const T& value1);
694
695
701template <typename T>
702bool ContainsAnyExcept(const ReadOnlySpan<T>& span, const T& value);
703
704
710template <typename T>
711bool ContainsAnyExcept(const Span<T>& span, const T& value);
712
713
719template <typename T>
720bool ContainsAnyExcept(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& values);
721
722
728template <typename T>
729bool ContainsAnyExcept(const Span<T>& span, const ReadOnlySpan<T>& values);
730
731
738template <typename T>
739bool ContainsAnyExceptInRange(const ReadOnlySpan<T>& span, const T& lowInclusive, const T& highInclusive);
740
741
748template <typename T>
749bool ContainsAnyExceptInRange(const Span<T>& span, const T& lowInclusive, const T& highInclusive);
750
751
758template <typename T>
759bool ContainsAnyInRange(const ReadOnlySpan<T>& span, const T& lowInclusive, const T& highInclusive);
760
761
768template <typename T>
769bool ContainsAnyInRange(const Span<T>& span, const T& lowInclusive, const T& highInclusive);
770
771
776template <typename T>
777void CopyTo(const ArrayPtr<T>& source, Span<T>& destination);
778
779
785template <typename T>
786int32_t Count(const ReadOnlySpan<T>& span, const T& value);
787
788
794template <typename T>
795int32_t Count(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& value);
796
797
803template <typename T>
804int32_t Count(const Span<T>& span, const T& value);
805
806
812template <typename T>
813int32_t Count(const Span<T>& span, const ReadOnlySpan<T>& value);
814
815
821template <typename T>
822bool EndsWith(const ReadOnlySpan<T>& span, const T& value);
823
824
830template <typename T>
831bool EndsWith(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& value);
832
833
839template <typename T>
840bool EndsWith(const Span<T>& span, const ReadOnlySpan<T>& value);
841
842
848template <typename T>
849bool EndsWith(const ReadOnlySpan<T>& span, const Span<T>& value);
850
851
857template <typename T>
858bool EndsWith(const Span<T>& span, const Span<T>& value);
859
860
866template <typename T>
867int32_t IndexOf(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& value);
868
869
875template <typename T>
876int32_t IndexOf(const ReadOnlySpan<T>& span, const T& value);
877
878
884template <typename T>
885int32_t IndexOf(const Span<T>& span, const ReadOnlySpan<T>& value);
886
887
893template <typename T>
894int32_t IndexOf(const Span<T>& span, const T& value);
895
896
903template <typename T>
904int32_t IndexOfAny(const ReadOnlySpan<T>& span, const T& value0, const T& value1);
905
906
914template <typename T>
915int32_t IndexOfAny(const ReadOnlySpan<T>& span, const T& value0, const T& value1, const T& value2);
916
917
924template <typename T>
925int32_t IndexOfAny(const Span<T>& span, const T& value0, const T& value1);
926
927
935template <typename T>
936int32_t IndexOfAny(const Span<T>& span, const T& value0, const T& value1, const T& value2);
937
938
944template <typename T>
945int32_t IndexOfAny(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& values);
946
947
953template <typename T>
954int32_t IndexOfAny(const Span<T>& span, const ReadOnlySpan<T>& values);
955
956
962template <typename T>
963int32_t IndexOfAnyExcept(const ReadOnlySpan<T>& span, const T& value);
964
965
973template <typename T>
974int32_t IndexOfAnyExcept(const ReadOnlySpan<T>& span, const T& value0, const T& value1);
975
976
985template <typename T>
986int32_t IndexOfAnyExcept(const ReadOnlySpan<T>& span, const T& value0, const T& value1, const T& value2);
987
988
994template <typename T>
995int32_t IndexOfAnyExcept(const Span<T>& span, const T& value);
996
997
1004template <typename T>
1005int32_t IndexOfAnyExcept(const Span<T>& span, const T& value0, const T& value1);
1006
1007
1015template <typename T>
1016int32_t IndexOfAnyExcept(const Span<T>& span, const T& value0, const T& value1, const T& value2);
1017
1018
1024template <typename T>
1025int32_t IndexOfAnyExcept(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& values);
1026
1027
1033template <typename T>
1034int32_t IndexOfAnyExcept(const Span<T>& span, const ReadOnlySpan<T>& values);
1035
1036
1043template <typename T>
1044int32_t IndexOfAnyExceptInRange(const ReadOnlySpan<T>& span, const T& lowInclusive, const T& highInclusive);
1045
1046
1053template <typename T>
1054int32_t IndexOfAnyExceptInRange(const Span<T>& span, const T& lowInclusive, const T& highInclusive);
1055
1056
1063template <typename T>
1064int32_t IndexOfAnyInRange(const ReadOnlySpan<T>& span, const T& lowInclusive, const T& highInclusive);
1065
1066
1073template <typename T>
1074int32_t IndexOfAnyInRange(const Span<T>& span, const T& lowInclusive, const T& highInclusive);
1075
1076
1082template <typename T>
1083int32_t LastIndexOf(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& value);
1084
1085
1091template <typename T>
1092int32_t LastIndexOf(const ReadOnlySpan<T>& span, const T& value);
1093
1094
1100template <typename T>
1101int32_t LastIndexOf(const Span<T>& span, const ReadOnlySpan<T>& value);
1102
1103
1109template <typename T>
1110int32_t LastIndexOf(const Span<T>& span, const T& value);
1111
1112
1120template <typename T>
1121int32_t LastIndexOfAny(const ReadOnlySpan<T>& span, const T& value0, const T& value1, const T& value2);
1122
1123
1131template <typename T>
1132int32_t LastIndexOfAny(const Span<T>& span, const T& value0, const T& value1, const T& value2);
1133
1134
1141template <typename T>
1142int32_t LastIndexOfAny(const ReadOnlySpan<T>& span, const T& value0, const T& value1);
1143
1144
1151template <typename T>
1152int32_t LastIndexOfAny(const Span<T>& span, const T& value0, const T& value1);
1153
1154
1160template <typename T>
1161int32_t LastIndexOfAny(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& values);
1162
1163
1169template <typename T>
1170int32_t LastIndexOfAny(const Span<T>& span, const ReadOnlySpan<T>& values);
1171
1172
1178template <typename T>
1179int32_t LastIndexOfAny(const Span<T>& span, const Span<T>& values);
1180
1181
1189template <typename T>
1190int32_t LastIndexOfAnyExcept(const ReadOnlySpan<T>& span, const T& value0, const T& value1, const T& value2);
1191
1192
1200template <typename T>
1201int32_t LastIndexOfAnyExcept(const Span<T>& span, const T& value0, const T& value1, const T& value2);
1202
1203
1210template <typename T>
1211int32_t LastIndexOfAnyExcept(const ReadOnlySpan<T>& span, const T& value0, const T& value1);
1212
1213
1220template <typename T>
1221int32_t LastIndexOfAnyExcept(const Span<T>& span, const T& value0, const T& value1);
1222
1223
1229template <typename T>
1230int32_t LastIndexOfAnyExcept(const ReadOnlySpan<T>& span, const T& value);
1231
1232
1238template <typename T>
1239int32_t LastIndexOfAnyExcept(const Span<T>& span, const T& value);
1240
1241
1247template <typename T>
1248int32_t LastIndexOfAnyExcept(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& values);
1249
1250
1256template <typename T>
1257int32_t LastIndexOfAnyExcept(const Span<T>& span, const ReadOnlySpan<T>& values);
1258
1259
1265template <typename T>
1266int32_t LastIndexOfAnyExcept(const Span<T>& span, const Span<T>& values);
1267
1268
1275template <typename T>
1276int32_t LastIndexOfAnyExceptInRange(const ReadOnlySpan<T>& span, const T& lowInclusive, const T& highInclusive);
1277
1278
1285template <typename T>
1286int32_t LastIndexOfAnyExceptInRange(const Span<T>& span, const T& lowInclusive, const T& highInclusive);
1287
1288
1295template <typename T>
1296int32_t LastIndexOfAnyInRange(const ReadOnlySpan<T>& span, const T& lowInclusive, const T& highInclusive);
1297
1298
1305template <typename T>
1306int32_t LastIndexOfAnyInRange(const Span<T>& span, const T& lowInclusive, const T& highInclusive);
1307
1308
1314template <typename T>
1315bool Overlaps(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& other);
1316
1317
1323template <typename T>
1324bool Overlaps(const Span<T>& span, const ReadOnlySpan<T>& other);
1325
1326
1333template <typename T>
1334bool Overlaps(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& other, int32_t& elementOffset);
1335
1336
1343template <typename T>
1344bool Overlaps(const Span<T>& span, const ReadOnlySpan<T>& other, int32_t& elementOffset);
1345
1346
1352template <typename T>
1353void Replace(Span<T>& span, const T& oldValue, const T& newValue);
1354
1355
1363template <typename T>
1364void Replace(const ReadOnlySpan<T>& source, Span<T>& destination, const T& oldValue, const T& newValue);
1365
1369template <typename T>
1370void Reverse(Span<T>& span);
1371
1377template <typename T>
1378int32_t SequenceCompareTo(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& other);
1379
1385template <typename T>
1386int32_t SequenceCompareTo(const Span<T>& span, const ReadOnlySpan<T>& other);
1387
1388
1394template <typename T>
1395int32_t SequenceCompareTo(const ReadOnlySpan<T>& span, const Span<T>& other);
1396
1397
1403template <typename T>
1404bool SequenceEqual(const ReadOnlySpan<T>& first, const ReadOnlySpan<T>& second);
1405
1406
1412template <typename T>
1413bool SequenceEqual(const Span<T>& span, const ReadOnlySpan<T>& other);
1414
1415
1423template <typename T, typename TComparer>
1424bool SequenceEqual(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& other, SharedPtr<TComparer>& comparer);
1425
1426
1434template <typename T, typename TComparer>
1435bool SequenceEqual(const Span<T>& span, const ReadOnlySpan<T>& other, SharedPtr<TComparer>& comparer);
1436
1437
1443template <typename T, typename TComparer>
1444void Sort(const Span<T>& span, const SharedPtr<TComparer>& comparer);
1445
1446
1450template <typename T>
1451void Sort(Span<T>& span);
1452
1453
1462template <typename TKey, typename TValue, typename TComparer>
1463void Sort(Span<TKey>& keys, Span<TValue>& values, const SharedPtr<TComparer>& comparer);
1464
1465
1473template <typename TKey, typename TValue>
1474void Sort(Span<TKey>& keys, Span<TValue>& values, System::Comparison<TKey> comparer);
1475
1476
1483template <typename TKey, typename TValue>
1484void Sort(Span<TKey>& keys, Span<TValue>& values);
1485
1486
1492template <typename T>
1493bool StartsWith(const ReadOnlySpan<T>& span, const T& value);
1494
1495
1501template <typename T>
1502bool StartsWith(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& value);
1503
1504
1510template <typename T>
1511bool StartsWith(const Span<T>& span, const ReadOnlySpan<T>& value);
1512
1513
1519template <typename T>
1520bool StartsWith(const ReadOnlySpan<T>& span, const Span<T>& value);
1521
1522
1528template <typename T>
1529ReadOnlySpan<T> Trim(const ReadOnlySpan<T>& span, T trimElement);
1530
1531
1537template <typename T>
1538Span<T> Trim(Span<T>& span, T trimElement);
1539
1540
1546template <typename T>
1547ReadOnlySpan<T> Trim(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& trimElements);
1548
1549
1555template <typename T>
1556Span<T> Trim(Span<T>& span, const ReadOnlySpan<T>& trimElements);
1557
1558
1564template <typename T>
1565ReadOnlySpan<T> TrimEnd(const ReadOnlySpan<T>& span, const T& trimElement);
1566
1567
1573template <typename T>
1574Span<T> TrimEnd(Span<T>& span, const T& trimElement);
1575
1576
1582template <typename T>
1583ReadOnlySpan<T> TrimEnd(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& trimElements);
1584
1585
1591template <typename T>
1592Span<T> TrimEnd(Span<T>& span, const ReadOnlySpan<T>& trimElements);
1593
1594
1600template <typename T>
1601ReadOnlySpan<T> TrimStart(const ReadOnlySpan<T>& span, const T& trimElement);
1602
1603
1609template <typename T>
1610Span<T> TrimStart(Span<T>& span, const T& trimElement);
1611
1612
1618template <typename T>
1619ReadOnlySpan<T> TrimStart(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& trimElements);
1620
1621
1627template <typename T>
1628Span<T> TrimStart(Span<T>& span, const ReadOnlySpan<T>& trimElements);
1629
1630
1636template <typename T>
1637Span<T> TrimStart(Span<T>& span, const ReadOnlySpan<T>& trimElements);
1638
1639
1645template <typename T>
1646Span<T> TrimStart(Span<T>& span, const ReadOnlySpan<T>& trimElements);
1647
1648
1654template <typename T>
1655Span<T> TrimStart(Span<T>& span, const ReadOnlySpan<T>& trimElements);
1656
1657
1663template <typename T>
1664Span<T> TrimStart(Span<T>& span, const ReadOnlySpan<T>& trimElements);
1665
1666
1672template <typename T>
1673Span<T> TrimStart(Span<T>& span, const ReadOnlySpan<T>& trimElements);
1674
1680ASPOSECPP_SHARED_API ReadOnlySpan<char16_t> AsSpan(const String& text, int32_t start = 0, int32_t length = -1);
1681
1687ASPOSECPP_SHARED_API int32_t CompareTo(const ReadOnlySpan<char16_t>& span, const ReadOnlySpan<char16_t>& other,
1688 StringComparison comparisonType);
1689
1695ASPOSECPP_SHARED_API bool Contains(const ReadOnlySpan<char16_t>& span, const ReadOnlySpan<char16_t>& value,
1696 StringComparison comparisonType);
1697
1703ASPOSECPP_SHARED_API bool EndsWith(const ReadOnlySpan<char16_t>& span, const ReadOnlySpan<char16_t>& value,
1704 StringComparison comparisonType);
1705
1711ASPOSECPP_SHARED_API bool Equals(const ReadOnlySpan<char16_t>& span, const ReadOnlySpan<char16_t>& other,
1712 StringComparison comparisonType);
1713
1719ASPOSECPP_SHARED_API int32_t IndexOf(const ReadOnlySpan<char16_t>& span, const ReadOnlySpan<char16_t>& value,
1720 StringComparison comparisonType);
1721
1725ASPOSECPP_SHARED_API bool IsWhiteSpace(const ReadOnlySpan<char16_t>& span);
1726
1732ASPOSECPP_SHARED_API int32_t LastIndexOf(const ReadOnlySpan<char16_t>& span, const ReadOnlySpan<char16_t>& value,
1733 StringComparison comparisonType);
1734
1740ASPOSECPP_SHARED_API bool StartsWith(const ReadOnlySpan<char16_t>& span, const ReadOnlySpan<char16_t>& value,
1741 StringComparison comparisonType);
1742
1748ASPOSECPP_SHARED_API int32_t ToLower(const ReadOnlySpan<char16_t>& source, Span<char16_t>& destination,
1750
1755ASPOSECPP_SHARED_API int32_t ToLowerInvariant(const ReadOnlySpan<char16_t>& source, Span<char16_t>& destination);
1756
1762ASPOSECPP_SHARED_API int32_t ToUpper(const ReadOnlySpan<char16_t>& source, Span<char16_t>& destination,
1764
1769ASPOSECPP_SHARED_API int32_t ToUpperInvariant(const ReadOnlySpan<char16_t>& source, Span<char16_t>& destination);
1770
1775inline bool StartsWith(const ReadOnlySpan<String>& span, const char16_t* val)
1776{
1777 if (span.get_Length() == 0)
1778 {
1779 return false;
1780 }
1781 String value = String(val);
1782 return (span.get(0)).Equals(value);
1783}
1784
1789{
1791}
1792
1797{
1799}
1800
1805{
1807}
1808
1813{
1814 return TrimEnd<char16_t>(span, Details::DefaultWhitespaceSpan);
1815}
1816
1821inline ReadOnlySpan<char16_t> TrimEnd(const ReadOnlySpan<char16_t>& span, char16_t trimchar)
1822{
1823 int32_t endIndex = span.get_Length() - 1;
1824 while (endIndex >= 0 && span.get(endIndex) == trimchar)
1825 {
1826 --endIndex;
1827 }
1828 return span.Slice(0, endIndex + 1);
1829}
1830
1835inline Span<char16_t> TrimEnd(Span<char16_t>& span, char16_t trimchar)
1836{
1837 int32_t endIndex = span.get_Length() - 1;
1838 while (endIndex >= 0 && span.get(endIndex) == trimchar)
1839 {
1840 --endIndex;
1841 }
1842 return span.Slice(0, endIndex + 1);
1843}
1844
1850{
1851 int32_t endIndex = span.get_Length() - 1;
1852 while (endIndex >= 0 && Contains(trimChars, span.get(endIndex)))
1853 {
1854 --endIndex;
1855 }
1856 return span.Slice(0, endIndex + 1);
1857}
1858
1864{
1865 int32_t endIndex = span.get_Length() - 1;
1866 while (endIndex >= 0 && Contains(trimchars, span.get(endIndex)))
1867 {
1868 --endIndex;
1869 }
1870 return span.Slice(0, endIndex + 1);
1871}
1872
1877{
1879}
1880
1885{
1887}
1888
1893inline ReadOnlySpan<char16_t> TrimStart(const ReadOnlySpan<char16_t>& span, char16_t trimchar)
1894{
1895 int32_t startIndex = 0;
1896 while (startIndex < span.get_Length() && span.get(startIndex) == trimchar)
1897 {
1898 ++startIndex;
1899 }
1900 return span.Slice(startIndex);
1901}
1902
1907inline Span<char16_t> TrimStart(Span<char16_t>& span, char16_t trimchar)
1908{
1909 int32_t startIndex = 0;
1910 while (startIndex < span.get_Length() && span.get(startIndex) == trimchar)
1911 {
1912 ++startIndex;
1913 }
1914 return span.Slice(startIndex);
1915}
1916
1922{
1923 int32_t startIndex = 0;
1924 while (startIndex < span.get_Length() && Contains(trimchars, span.get(startIndex)))
1925 {
1926 ++startIndex;
1927 }
1928 return span.Slice(startIndex);
1929}
1930
1936{
1937 int32_t startIndex = 0;
1938 while (startIndex < span.get_Length() && Contains(trimchars, span.get(startIndex)))
1939 {
1940 ++startIndex;
1941 }
1942 return span.Slice(startIndex);
1943}
1944
1945template <typename T>
1946Span<T> AsSpan(const ArrayPtr<T>& array, int32_t start, int32_t length)
1947{
1948 if (array == nullptr)
1949 {
1950 throw ArgumentNullException(u"array is null");
1951 }
1952 if (start < 0 || (length < 0 && length != -1) ||
1953 (length == -1 ? start > array->get_Length() : start + length > array->get_Length()))
1954 {
1955 throw ArgumentOutOfRangeException(u"start or length is out of range");
1956 }
1957 if (length == -1)
1958 {
1959 length = array->get_Length() - start;
1960 }
1961 return Span<T>(array, start, length);
1962}
1963
1964template <typename T, typename TComparable>
1965int32_t BinarySearch(const ReadOnlySpan<T>& span, const TComparable& comparable)
1966{
1967 return Details::BinarySearchImpl(span, comparable,
1968 [](const TComparable& search_value, const T& container_value) -> int32_t {
1969 return Details::Compare(search_value, container_value);
1970 });
1971}
1972
1973template <typename T, typename TComparer>
1974int32_t BinarySearch(const ReadOnlySpan<T>& span, const T& value, const SharedPtr<TComparer>& comparerPtr)
1975{
1976 return Details::BinarySearchImpl(span, value,
1977 [&comparerPtr](const T& search_value, const T& container_value) -> int32_t {
1978 return comparerPtr->Compare(search_value, container_value);
1979 });
1980}
1981
1982template <typename T, typename TComparable>
1983int32_t BinarySearch(const Span<T>& span, const TComparable& comparable)
1984{
1985 return BinarySearch(static_cast<ReadOnlySpan<T>>(span), comparable);
1986}
1987
1988template <typename T, typename TComparer>
1989int32_t BinarySearch(const Span<T>& span, const T& value, const SharedPtr<TComparer>& comparer)
1990{
1991 return BinarySearch(static_cast<ReadOnlySpan<T>>(span), value, comparer);
1992}
1993
1994template <typename T>
1995int32_t CommonPrefixLength(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& other)
1996{
1997 int32_t commonLength = 0;
1998 int32_t minLength = std::min(span.get_Length(), other.get_Length());
1999
2000 // Compare elements until a mismatch is found
2001 for (int32_t i = 0; i < minLength; ++i)
2002 {
2003 if (System::ObjectExt::Equals(span.get(i), other.get(i)))
2004 {
2005 ++commonLength;
2006 }
2007 else
2008 {
2009 break; // Mismatch found, exit early
2010 }
2011 }
2012
2013 return commonLength;
2014}
2015
2016template <typename T>
2017int32_t CommonPrefixLength(const Span<T>& span, const ReadOnlySpan<T>& other)
2018{
2019 return CommonPrefixLength(static_cast<ReadOnlySpan<T>>(span), other);
2020}
2021
2022template <typename T>
2023int32_t CommonPrefixLength(const Span<T>& span, const Span<T>& other)
2024{
2025 return CommonPrefixLength(static_cast<ReadOnlySpan<T>>(span), static_cast<ReadOnlySpan<T>>(other));
2026}
2027
2028template <typename T, typename TEqualityComparer>
2029int32_t CommonPrefixLength(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& other,
2030 const SharedPtr<TEqualityComparer>& comparer)
2031{
2032 int32_t commonLength = 0;
2033 int32_t minLength = std::min(span.get_Length(), other.get_Length());
2034
2035 // Compare elements until a mismatch is found
2036 for (int32_t i = 0; i < minLength; ++i)
2037 {
2038 if ((comparer == nullptr && System::ObjectExt::Equals(span.get(i), other.get(i))) ||
2039 (comparer != nullptr && comparer->Equals(span.get(i), other.get(i))))
2040 {
2041 ++commonLength;
2042 }
2043 else
2044 {
2045 break; // Mismatch found, exit early
2046 }
2047 }
2048
2049 return commonLength;
2050}
2051
2052template <typename T, typename TEqualityComparer>
2053int32_t CommonPrefixLength(const Span<T>& span, const ReadOnlySpan<T>& other,
2054 const SharedPtr<TEqualityComparer>& comparer)
2055{
2056 return CommonPrefixLength(static_cast<ReadOnlySpan<T>>(span), other, comparer);
2057}
2058
2059template <typename T, typename TEqualityComparer>
2060int32_t CommonPrefixLength(const Span<T>& span, const Span<T>& other, const SharedPtr<TEqualityComparer>& comparer)
2061{
2062 return CommonPrefixLength(static_cast<ReadOnlySpan<T>>(span), static_cast<ReadOnlySpan<T>>(other), comparer);
2063}
2064
2065template <typename T>
2066bool Contains(const ReadOnlySpan<T>& span, const T& value)
2067{
2068 return std::find_if(span.begin(), span.end(), [&value](const T& item) { return System::ObjectExt::Equals(value, item); }) !=
2069 span.end();
2070}
2071
2072template <typename T>
2073bool Contains(const Span<T>& span, const T& value)
2074{
2075 return std::find(span.begin(), span.end(), value) != span.end();
2076}
2077
2078template <typename T>
2079bool ContainsAny(const ReadOnlySpan<T>& span, const T& value0, const T& value1)
2080{
2081 return Contains(span, value0) || Contains(span, value1);
2082}
2083
2084template <typename T>
2085bool ContainsAny(const ReadOnlySpan<T>& span, const T& value0, const T& value1, const T& value2)
2086{
2087 return Contains(span, value0) || Contains(span, value1) || Contains(span, value2);
2088}
2089
2090template <typename T>
2091bool ContainsAny(const Span<T>& span, const T& value0, const T& value1)
2092{
2093 return ContainsAny(static_cast<const ReadOnlySpan<T>&>(span), value0, value1);
2094}
2095
2096template <typename T>
2097bool ContainsAny(const Span<T>& span, const T& value0, const T& value1, const T& value2)
2098{
2099 return ContainsAny(static_cast<const ReadOnlySpan<T>&>(span), value0, value1, value2);
2100}
2101
2102template <typename T>
2103bool ContainsAny(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& values)
2104{
2105 for (const auto& value : values)
2106 {
2107 if (Contains(span, value))
2108 {
2109 return true; // Found at least one value
2110 }
2111 }
2112 return false; // Not found
2113}
2114
2115template <typename T>
2116bool ContainsAny(const Span<T>& span, const ReadOnlySpan<T>& values)
2117{
2118 return ContainsAny(static_cast<const ReadOnlySpan<T>&>(span), values);
2119}
2120
2121template <typename T>
2122bool ContainsAnyExcept(const ReadOnlySpan<T>& span, const T& value0, const T& value1, const T& value2)
2123{
2124 for (auto& member : span)
2125 {
2126 if (!System::ObjectExt::Equals(member, value0) && !System::ObjectExt::Equals(member, value1) &&
2127 !System::ObjectExt::Equals(member, value2))
2128 {
2129 return true;
2130 }
2131 }
2132 return false;
2133}
2134
2135template <typename T>
2136bool ContainsAnyExcept(const Span<T>& span, const T& value0, const T& value1, const T& value2)
2137{
2138 return ContainsAnyExcept(static_cast<const ReadOnlySpan<T>&>(span), value0, value1, value2);
2139}
2140
2141template <typename T>
2142bool ContainsAnyExcept(const ReadOnlySpan<T>& span, const T& value0, const T& value1)
2143{
2144 for (auto& member : span)
2145 {
2146 if (!System::ObjectExt::Equals(member, value0) && !System::ObjectExt::Equals(member, value1))
2147 {
2148 return true;
2149 }
2150 }
2151 return false;
2152}
2153
2154template <typename T>
2155bool ContainsAnyExcept(const Span<T>& span, const T& value0, const T& value1)
2156{
2157 return ContainsAnyExcept(static_cast<const ReadOnlySpan<T>&>(span), value0, value1);
2158}
2159
2160template <typename T>
2161bool ContainsAnyExcept(const ReadOnlySpan<T>& span, const T& value)
2162{
2163 for (auto& member : span)
2164 {
2165 if (!System::ObjectExt::Equals(member, value))
2166 {
2167 return true;
2168 }
2169 }
2170 return false;
2171}
2172
2173template <typename T>
2174bool ContainsAnyExcept(const Span<T>& span, const T& value)
2175{
2176 return ContainsAnyExcept(static_cast<const ReadOnlySpan<T>&>(span), value);
2177}
2178
2179template <typename T>
2180bool ContainsAnyExcept(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& values)
2181{
2182 switch (values.get_Length())
2183 {
2184 case 0:
2185 return span.get_IsEmpty() ? false : true;
2186
2187 case 1:
2188 return ContainsAnyExcept(span, values.get(0));
2189
2190 case 2:
2191 return ContainsAnyExcept(span, values.get(0), values.get(1));
2192
2193 case 3:
2194 return ContainsAnyExcept(span, values.get(0), values.get(1), values.get(2));
2195
2196 default:
2197 for (auto& member : span)
2198 {
2199 if (!Contains(values, member))
2200 {
2201 return true;
2202 }
2203 }
2204 return false;
2205 }
2206}
2207
2208template <typename T>
2209bool ContainsAnyExcept(const Span<T>& span, const ReadOnlySpan<T>& values)
2210{
2211 return ContainsAnyExcept(static_cast<const ReadOnlySpan<T>&>(span), values);
2212}
2213
2214template <typename T>
2215bool ContainsAnyExceptInRange(const ReadOnlySpan<T>& span, const T& lowInclusive, const T& highInclusive)
2216{
2217 for (const auto& value : span)
2218 {
2219 if (value < lowInclusive || value > highInclusive)
2220 {
2221 return true; // Found a value outside the range
2222 }
2223 }
2224 return false; // All values are within the range
2225}
2226
2227template <typename T>
2228bool ContainsAnyExceptInRange(const Span<T>& span, const T& lowInclusive, const T& highInclusive)
2229{
2230 for (const auto& value : span)
2231 {
2232 if (value < lowInclusive || value > highInclusive)
2233 {
2234 return true; // Found a value outside the range
2235 }
2236 }
2237 return false; // All values are within the range
2238}
2239
2240template <typename T>
2241bool ContainsAnyInRange(const ReadOnlySpan<T>& span, const T& lowInclusive, const T& highInclusive)
2242{
2243 for (const auto& value : span)
2244 {
2245 if (value >= lowInclusive && value <= highInclusive)
2246 {
2247 return true; // Found a value within the range
2248 }
2249 }
2250 return false; // No values found within the range
2251}
2252
2253template <typename T>
2254bool ContainsAnyInRange(const Span<T>& span, const T& lowInclusive, const T& highInclusive)
2255{
2256 for (const auto& value : span)
2257 {
2258 if (value >= lowInclusive && value <= highInclusive)
2259 {
2260 return true; // Found a value within the range
2261 }
2262 }
2263 return false; // No values found within the range
2264}
2265
2266template <typename T>
2267void CopyTo(const ArrayPtr<T>& source, Span<T>& destination)
2268{
2269 return ReadOnlySpan<T>(source).CopyTo(destination);
2270}
2271
2272template <typename T>
2273int32_t Count(const ReadOnlySpan<T>& span, const T& value)
2274{
2275 int32_t count = 0;
2276 for (const auto& item : span)
2277 {
2278 if (System::ObjectExt::Equals(item, value))
2279 {
2280 ++count;
2281 }
2282 }
2283 return count;
2284}
2285
2286template <typename T>
2287int32_t Count(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& value)
2288{
2289 switch (value.get_Length())
2290 {
2291 case 0:
2292 return 0;
2293
2294 case 1:
2295 return Count(span, value.get(0));
2296
2297 default:
2298 int32_t count = 0;
2299 int32_t pos = 0;
2300 ReadOnlySpan<T> currentSpan = span;
2301 while ((pos = IndexOf(currentSpan, value)) >= 0)
2302 {
2303 count++;
2304 currentSpan = currentSpan.Slice(pos + value.get_Length());
2305 }
2306 return count;
2307 }
2308}
2309
2310template <typename T>
2311int32_t Count(const Span<T>& span, const T& value)
2312{
2313 return Count(ReadOnlySpan<T>(span), value); // Delegate to ReadOnlySpan<T> method
2314}
2315
2316template <typename T>
2317int32_t Count(const Span<T>& span, const ReadOnlySpan<T>& value)
2318{
2319 return Count(ReadOnlySpan<T>(span), value); // Delegate to ReadOnlySpan<T> method
2320}
2321
2322template <typename T>
2323bool EndsWith(const ReadOnlySpan<T>& span, const T& value)
2324{
2325 if (span.get_Length() == 0)
2326 {
2327 return false; // Empty span does not end with any value
2328 }
2329 return System::ObjectExt::Equals(span.get(span.get_Length() - 1), value);
2330}
2331
2332template <typename T>
2333bool EndsWith(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& value)
2334{
2335 int32_t spanLength = span.get_Length();
2336 int32_t valueLength = value.get_Length();
2337
2338 if (valueLength > spanLength)
2339 {
2340 return false;
2341 }
2342
2343 if (valueLength == spanLength)
2344 {
2345 return SequenceEqual(span, value);
2346 }
2347
2348 return SequenceEqual(span.Slice(spanLength - valueLength), value);
2349}
2350
2351template <typename T>
2352bool EndsWith(const Span<T>& span, const ReadOnlySpan<T>& value)
2353{
2354 return EndsWith(ReadOnlySpan<T>(span), value);
2355}
2356
2357template <typename T>
2358bool EndsWith(const ReadOnlySpan<T>& span, const Span<T>& value)
2359{
2360 return EndsWith(span, ReadOnlySpan<T>(value));
2361}
2362
2363template <typename T>
2364bool EndsWith(const Span<T>& span, const Span<T>& value)
2365{
2366 return EndsWith(ReadOnlySpan<T>(span), ReadOnlySpan<T>(value));
2367}
2368
2369template <typename T>
2370int32_t IndexOf(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& value)
2371{
2372 if (value.get_Length() == 0)
2373 {
2374 return 0; // A zero-length sequence is always treated as "found" at the start of the search space.
2375 }
2376
2377 const T& valueHead = value.get(0);
2378 int32_t valueTailLength = value.get_Length() - 1;
2379
2380 int32_t index = 0;
2381 while (true)
2382 {
2383 if (index + valueTailLength > span.get_Length())
2384 {
2385 break; // The unsearched portion is now shorter than the sequence we're looking for.
2386 }
2387
2388 // Search for the first element of "value".
2389 int32_t remainingSearchSpaceLength = span.get_Length() - index - valueTailLength;
2390 int32_t relativeIndex = -1; // Default to not found
2391
2392 for (int32_t i = 0; i < remainingSearchSpaceLength; ++i)
2393 {
2394 if (System::ObjectExt::Equals(span.get(index + i), valueHead))
2395 {
2396 relativeIndex = i;
2397 break;
2398 }
2399 }
2400
2401 if (relativeIndex == -1)
2402 {
2403 break; // First element not found.
2404 }
2405
2406 index += relativeIndex;
2407
2408 // Found the first element of "value". Check if the tail matches.
2409 bool tailMatches = true;
2410 for (int32_t i = 0; i < valueTailLength; ++i)
2411 {
2412 if (span.get(index + 1 + i) != value.get(1 + i))
2413 {
2414 tailMatches = false;
2415 break;
2416 }
2417 }
2418
2419 if (tailMatches)
2420 {
2421 return index; // The tail matched. Return a successful find.
2422 }
2423
2424 ++index; // Move to the next position in the search space.
2425 }
2426
2427 return -1; // Not found.
2428}
2429
2430template <typename T>
2431int32_t IndexOf(const ReadOnlySpan<T>& span, const T& value)
2432{
2433 for (int32_t i = 0; i < span.get_Length(); ++i)
2434 {
2435 if (System::ObjectExt::Equals(span.get(i), value))
2436 {
2437 return i; // Found
2438 }
2439 }
2440 return -1; // Not found
2441}
2442
2443template <typename T>
2444int32_t IndexOf(const Span<T>& span, const ReadOnlySpan<T>& value)
2445{
2446 return IndexOf(static_cast<ReadOnlySpan<T>>(span), value);
2447}
2448
2449template <typename T>
2450int32_t IndexOf(const Span<T>& span, const T& value)
2451{
2452 return IndexOf(static_cast<ReadOnlySpan<T>>(span), value);
2453}
2454
2455template <typename T>
2456int32_t IndexOfAny(const ReadOnlySpan<T>& span, const T& value0, const T& value1)
2457{
2458 for (int32_t i = 0; i < span.get_Length(); ++i)
2459 {
2460 if (System::ObjectExt::Equals(span.get(i), value0) || System::ObjectExt::Equals(span.get(i), value1))
2461 {
2462 return i; // Found
2463 }
2464 }
2465 return -1; // Not found
2466}
2467
2468template <typename T>
2469int32_t IndexOfAny(const ReadOnlySpan<T>& span, const T& value0, const T& value1, const T& value2)
2470{
2471 for (int32_t i = 0; i < span.get_Length(); ++i)
2472 {
2473 if (System::ObjectExt::Equals(span.get(i), value0) || System::ObjectExt::Equals(span.get(i), value1) ||
2474 System::ObjectExt::Equals(span.get(i), value2))
2475 {
2476 return i; // Found
2477 }
2478 }
2479 return -1; // Not found
2480}
2481
2482template <typename T>
2483int32_t IndexOfAny(const Span<T>& span, const T& value0, const T& value1)
2484{
2485 return IndexOfAny(static_cast<ReadOnlySpan<T>>(span), value0, value1);
2486}
2487
2488template <typename T>
2489int32_t IndexOfAny(const Span<T>& span, const T& value0, const T& value1, const T& value2)
2490{
2491 return IndexOfAny(static_cast<ReadOnlySpan<T>>(span), value0, value1, value2);
2492}
2493
2494template <typename T>
2495int32_t IndexOfAny(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& values)
2496{
2497 for (int32_t i = 0; i < span.get_Length(); ++i)
2498 {
2499 for (int32_t j = 0; j < values.get_Length(); ++j)
2500 {
2501 if (System::ObjectExt::Equals(span.get(i), values.get(j)))
2502 {
2503 return i; // Found
2504 }
2505 }
2506 }
2507 return -1; // Not found
2508}
2509
2510template <typename T>
2511int32_t IndexOfAny(const Span<T>& span, const ReadOnlySpan<T>& values)
2512{
2513 return IndexOfAny(static_cast<ReadOnlySpan<T>>(span), values);
2514}
2515
2516template <typename T>
2517int32_t IndexOfAnyExcept(const ReadOnlySpan<T>& span, const T& value)
2518{
2519 for (int32_t i = 0; i < span.get_Length(); ++i)
2520 {
2521 if (!System::ObjectExt::Equals(span.get(i), value))
2522 {
2523 return i; // Found
2524 }
2525 }
2526 return -1; // Not found
2527}
2528
2529template <typename T>
2530int32_t IndexOfAnyExcept(const ReadOnlySpan<T>& span, const T& value0, const T& value1)
2531{
2532 for (int32_t i = 0; i < span.get_Length(); ++i)
2533 {
2534 if (!System::ObjectExt::Equals(span.get(i), value0) && !System::ObjectExt::Equals(span.get(i), value1))
2535 {
2536 return i; // Found
2537 }
2538 }
2539 return -1; // Not found
2540}
2541
2542template <typename T>
2543int32_t IndexOfAnyExcept(const ReadOnlySpan<T>& span, const T& value0, const T& value1, const T& value2)
2544{
2545 for (int32_t i = 0; i < span.get_Length(); ++i)
2546 {
2547 if (!System::ObjectExt::Equals(span.get(i), value0) && !System::ObjectExt::Equals(span.get(i), value1) &&
2548 !System::ObjectExt::Equals(span.get(i), value2))
2549 {
2550 return i; // Found
2551 }
2552 }
2553 return -1; // Not found
2554}
2555
2556template <typename T>
2557int32_t IndexOfAnyExcept(const Span<T>& span, const T& value)
2558{
2559 return IndexOfAnyExcept(static_cast<const ReadOnlySpan<T>&>(span), value);
2560}
2561
2562template <typename T>
2563int32_t IndexOfAnyExcept(const Span<T>& span, const T& value0, const T& value1)
2564{
2565 return IndexOfAnyExcept(static_cast<const ReadOnlySpan<T>&>(span), value0, value1);
2566}
2567
2568template <typename T>
2569int32_t IndexOfAnyExcept(const Span<T>& span, const T& value0, const T& value1, const T& value2)
2570{
2571 return IndexOfAnyExcept(static_cast<const ReadOnlySpan<T>&>(span), value0, value1, value2);
2572}
2573
2574template <typename T>
2575int32_t IndexOfAnyExcept(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& values)
2576{
2577 for (int32_t i = 0; i < span.get_Length(); ++i)
2578 {
2579 bool found = false;
2580 for (int32_t j = 0; j < values.get_Length(); ++j)
2581 {
2582 if (System::ObjectExt::Equals(span.get(i), values.get(j)))
2583 {
2584 found = true;
2585 break;
2586 }
2587 }
2588 if (!found)
2589 {
2590 return i; // Found
2591 }
2592 }
2593 return -1; // Not found
2594}
2595
2596template <typename T>
2597int32_t IndexOfAnyExcept(const Span<T>& span, const ReadOnlySpan<T>& values)
2598{
2599 return IndexOfAnyExcept(static_cast<ReadOnlySpan<T>>(span), values);
2600}
2601
2602template <typename T>
2603int32_t IndexOfAnyExceptInRange(const ReadOnlySpan<T>& span, const T& lowInclusive, const T& highInclusive)
2604{
2605 for (int32_t i = 0; i < span.get_Length(); ++i)
2606 {
2607 if (Details::Compare(span.get(i), lowInclusive) < 0 || Details::Compare(span.get(i), highInclusive) > 0)
2608 {
2609 return i; // Found an element outside the range
2610 }
2611 }
2612 return -1; // Not found
2613}
2614
2615template <typename T>
2616int32_t IndexOfAnyExceptInRange(const Span<T>& span, const T& lowInclusive, const T& highInclusive)
2617{
2618 return IndexOfAnyExceptInRange(static_cast<const ReadOnlySpan<T>&>(span), lowInclusive, highInclusive);
2619}
2620
2621template <typename T>
2622int32_t IndexOfAnyInRange(const ReadOnlySpan<T>& span, const T& lowInclusive, const T& highInclusive)
2623{
2624 for (int32_t i = 0; i < span.get_Length(); ++i)
2625 {
2626 // if (span.get(i).CompareTo(lowInclusive) >= 0 && span.get(i).CompareTo(highInclusive) <= 0) {
2627 if (Details::Compare(span.get(i), lowInclusive) >= 0 && Details::Compare(span.get(i), highInclusive) <= 0)
2628 {
2629 return i; // Found an element within the range
2630 }
2631 }
2632 return -1; // Not found
2633}
2634
2635template <typename T>
2636int32_t IndexOfAnyInRange(const Span<T>& span, const T& lowInclusive, const T& highInclusive)
2637{
2638 return IndexOfAnyInRange(static_cast<const ReadOnlySpan<T>&>(span), lowInclusive, highInclusive);
2639}
2640
2641template <typename T>
2642int32_t LastIndexOf(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& value)
2643{
2644 if (value.get_Length() == 0)
2645 return span.get_Length(); // A zero-length sequence is always treated as "found" at the end of the search space.
2646
2647 int32_t valueTailLength = value.get_Length() - 1;
2648 if (valueTailLength == 0)
2649 {
2650 return LastIndexOf<T>(span, value.get(0));
2651 }
2652
2653 int32_t index = 0;
2654
2655 T valueHead = value.get(0);
2656 ReadOnlySpan<T> valueTail = value.Slice(1);
2657
2658 while (true)
2659 {
2660 int32_t remainingSearchSpaceLength = span.get_Length() - index - valueTail.get_Length(); // отступ
2661 if (remainingSearchSpaceLength <= 0)
2662 break;
2663
2664 // Do a quick search for the first element of "value".
2665 int32_t relativeIndex = Details::LastIndexOfImpl<T>(span, remainingSearchSpaceLength, valueHead);
2666 if (relativeIndex < 0)
2667 break;
2668
2669 // Found the first element of "value". See if the tail matches.
2670 if (Details::SequenceEqualImpl<T>(span, relativeIndex + 1, valueTail.get_Length(), valueTail))
2671 return relativeIndex;
2672
2673 index += remainingSearchSpaceLength - relativeIndex;
2674 }
2675 return -1;
2676}
2677
2678template <typename T>
2679int32_t LastIndexOf(const ReadOnlySpan<T>& span, const T& value)
2680{
2681 for (int32_t i = span.get_Length() - 1; i >= 0; --i)
2682 {
2683 if (System::ObjectExt::Equals(span.get(i), value))
2684 {
2685 return i; // Found
2686 }
2687 }
2688 return -1; // Not found
2689}
2690
2691template <typename T>
2692int32_t LastIndexOf(const Span<T>& span, const ReadOnlySpan<T>& value)
2693{
2694 return LastIndexOf(static_cast<const ReadOnlySpan<T>&>(span), value); // Cast for use with ReadOnlySpan
2695}
2696
2697template <typename T>
2698int32_t LastIndexOf(const Span<T>& span, const T& value)
2699{
2700 return LastIndexOf(static_cast<const ReadOnlySpan<T>&>(span), value); // Cast for use with ReadOnlySpan
2701}
2702
2703template <typename T>
2704int32_t LastIndexOfAny(const ReadOnlySpan<T>& span, const T& value0, const T& value1, const T& value2)
2705{
2706 for (int32_t i = span.get_Length() - 1; i >= 0; --i)
2707 {
2708 if (System::ObjectExt::Equals(span.get(i), value0) || System::ObjectExt::Equals(span.get(i), value1) ||
2709 System::ObjectExt::Equals(span.get(i), value2))
2710 {
2711 return i; // Found
2712 }
2713 }
2714 return -1; // Not found
2715}
2716
2717template <typename T>
2718int32_t LastIndexOfAny(const Span<T>& span, const T& value0, const T& value1, const T& value2)
2719{
2720 return LastIndexOfAny(static_cast<const ReadOnlySpan<T>&>(span), value0, value1, value2);
2721}
2722
2723template <typename T>
2724int32_t LastIndexOfAny(const ReadOnlySpan<T>& span, const T& value0, const T& value1)
2725{
2726 for (int32_t i = span.get_Length() - 1; i >= 0; --i)
2727 {
2728 if (System::ObjectExt::Equals(span.get(i), value0) || System::ObjectExt::Equals(span.get(i), value1))
2729 {
2730 return i; // Found
2731 }
2732 }
2733 return -1; // Not found
2734}
2735
2736template <typename T>
2737int32_t LastIndexOfAny(const Span<T>& span, const T& value0, const T& value1)
2738{
2739 return LastIndexOfAny(static_cast<const ReadOnlySpan<T>&>(span), value0, value1);
2740}
2741
2742template <typename T>
2743int32_t LastIndexOfAny(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& values)
2744{
2745 for (int32_t i = span.get_Length() - 1; i >= 0; --i)
2746 {
2747 for (int32_t j = 0; j < values.get_Length(); ++j)
2748 {
2749 if (System::ObjectExt::Equals(span.get(i), values.get(j)))
2750 {
2751 return i; // Found
2752 }
2753 }
2754 }
2755 return -1; // Not found
2756}
2757
2758template <typename T>
2759int32_t LastIndexOfAny(const Span<T>& span, const ReadOnlySpan<T>& values)
2760{
2761 return LastIndexOfAny(static_cast<const ReadOnlySpan<T>&>(span), values);
2762}
2763
2764template <typename T>
2765int32_t LastIndexOfAny(const Span<T>& span, const Span<T>& values)
2766{
2767 return LastIndexOfAny(static_cast<const ReadOnlySpan<T>&>(span), static_cast<const ReadOnlySpan<T>&>(values));
2768}
2769
2770template <typename T>
2771int32_t LastIndexOfAnyExcept(const ReadOnlySpan<T>& span, const T& value0, const T& value1, const T& value2)
2772{
2773 for (int32_t i = span.get_Length() - 1; i >= 0; --i)
2774 {
2775 const T& current = span.get(i);
2776 if (!(System::ObjectExt::Equals(current, value0) || System::ObjectExt::Equals(current, value1) ||
2777 System::ObjectExt::Equals(current, value2)))
2778 {
2779 return i;
2780 }
2781 }
2782 return -1; // Not found
2783}
2784
2785template <typename T>
2786int32_t LastIndexOfAnyExcept(const Span<T>& span, const T& value0, const T& value1, const T& value2)
2787{
2788 return LastIndexOfAnyExcept(static_cast<ReadOnlySpan<T>>(span), value0, value1, value2);
2789}
2790
2791template <typename T>
2792int32_t LastIndexOfAnyExcept(const ReadOnlySpan<T>& span, const T& value0, const T& value1)
2793{
2794 for (int32_t i = span.get_Length() - 1; i >= 0; --i)
2795 {
2796 const T& current = span.get(i);
2797 if (!(System::ObjectExt::Equals(current, value0) || System::ObjectExt::Equals(current, value1)))
2798 {
2799 return i;
2800 }
2801 }
2802 return -1; // Not found
2803}
2804
2805template <typename T>
2806int32_t LastIndexOfAnyExcept(const Span<T>& span, const T& value0, const T& value1)
2807{
2808 return LastIndexOfAnyExcept(static_cast<ReadOnlySpan<T>>(span), value0, value1);
2809}
2810
2811template <typename T>
2812int32_t LastIndexOfAnyExcept(const ReadOnlySpan<T>& span, const T& value)
2813{
2814 for (int32_t i = span.get_Length() - 1; i >= 0; --i)
2815 {
2816 T current = span.get(i);
2817 if (!(System::ObjectExt::Equals(current, value)))
2818 {
2819 return i;
2820 }
2821 }
2822 return -1; // Not found
2823}
2824
2825template <typename T>
2826int32_t LastIndexOfAnyExcept(const Span<T>& span, const T& value)
2827{
2828 return LastIndexOfAnyExcept(static_cast<ReadOnlySpan<T>>(span), value);
2829}
2830
2831template <typename T>
2832int32_t LastIndexOfAnyExcept(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& values)
2833{
2834 for (int32_t i = span.get_Length() - 1; i >= 0; --i)
2835 {
2836 const T& current = span.get(i);
2837 bool found = false;
2838 for (auto& value : values)
2839 {
2840 if (System::ObjectExt::Equals(current, value))
2841 {
2842 found = true;
2843 break;
2844 }
2845 }
2846 if (!found)
2847 {
2848 return i;
2849 }
2850 }
2851 return -1; // Not found
2852}
2853
2854template <typename T>
2855int32_t LastIndexOfAnyExcept(const Span<T>& span, const ReadOnlySpan<T>& values)
2856{
2857 return LastIndexOfAnyExcept(static_cast<ReadOnlySpan<T>>(span), values);
2858}
2859
2860template <typename T>
2861int32_t LastIndexOfAnyExcept(const Span<T>& span, const Span<T>& values)
2862{
2863 return LastIndexOfAnyExcept(static_cast<ReadOnlySpan<T>>(span), static_cast<ReadOnlySpan<T>>(values));
2864}
2865
2866template <typename T>
2867int32_t LastIndexOfAnyExceptInRange(const ReadOnlySpan<T>& span, const T& lowInclusive, const T& highInclusive)
2868{
2869 for (int32_t i = span.get_Length() - 1; i >= 0; --i)
2870 {
2871 if (Details::Compare(span.get(i), lowInclusive) < 0 || Details::Compare(span.get(i), highInclusive) > 0)
2872 {
2873 return i; // Found an element outside the range
2874 }
2875 }
2876 return -1; // Not found
2877}
2878
2879template <typename T>
2880int32_t LastIndexOfAnyExceptInRange(const Span<T>& span, const T& lowInclusive, const T& highInclusive)
2881{
2882 return LastIndexOfAnyExceptInRange(static_cast<ReadOnlySpan<T>>(span), lowInclusive, highInclusive);
2883}
2884
2885template <typename T>
2886int32_t LastIndexOfAnyInRange(const ReadOnlySpan<T>& span, const T& lowInclusive, const T& highInclusive)
2887{
2888 for (int32_t i = span.get_Length() - 1; i >= 0; --i)
2889 {
2890 if (Details::Compare(span.get(i), lowInclusive) >= 0 && Details::Compare(span.get(i), highInclusive) <= 0)
2891 {
2892 return i; // Found an element outside the range
2893 }
2894 }
2895 return -1; // Not found
2896}
2897
2898template <typename T>
2899int32_t LastIndexOfAnyInRange(const Span<T>& span, const T& lowInclusive, const T& highInclusive)
2900{
2901 return LastIndexOfAnyInRange(static_cast<ReadOnlySpan<T>>(span), lowInclusive, highInclusive);
2902}
2903
2904template <typename T>
2905bool Overlaps(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& other)
2906{
2907 int32_t offset;
2908 return Overlaps(span, other, offset);
2909}
2910
2911template <typename T>
2912bool Overlaps(const Span<T>& span, const ReadOnlySpan<T>& other)
2913{
2914 return Overlaps(static_cast<ReadOnlySpan<T>>(span), other);
2915}
2916
2917template <typename T>
2918bool Overlaps(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& other, int32_t& elementOffset)
2919{
2920 if (span.get_IsEmpty() || other.get_IsEmpty())
2921 {
2922 elementOffset = 0;
2923 return false;
2924 }
2925 ptrdiff_t Offset = other.begin() - span.begin();
2926 bool isOverlap = (Offset >= 0 && Offset < span.get_Length()) || (Offset < 0 && -Offset < other.get_Length());
2927
2928 if (isOverlap)
2929 {
2930 elementOffset = static_cast<int32_t>(Offset);
2931 }
2932 else
2933 {
2934 elementOffset = 0;
2935 }
2936 return isOverlap;
2937}
2938
2939template <typename T>
2940bool Overlaps(const Span<T>& span, const ReadOnlySpan<T>& other, int32_t& elementOffset)
2941{
2942 return Overlaps(static_cast<ReadOnlySpan<T>>(span), other, elementOffset);
2943}
2944
2945template <typename T>
2946void Replace(Span<T>& span, const T& oldValue, const T& newValue)
2947{
2948 for (int32_t i = 0; i < span.get_Length(); ++i)
2949 {
2950 if (System::ObjectExt::Equals(span.get(i), oldValue))
2951 {
2952 span.get(i) = newValue; // Replace oldValue with newValue
2953 }
2954 }
2955}
2956
2957template <typename T>
2958void Replace(const ReadOnlySpan<T>& source, Span<T>& destination, const T& oldValue, const T& newValue)
2959{
2960 if (destination.get_Length() < source.get_Length())
2961 {
2962 throw ArgumentException(u"Destination span is smaller than source span.");
2963 }
2964
2965 for (int32_t i = 0; i < source.get_Length(); ++i)
2966 {
2967 if (System::ObjectExt::Equals(source.get(i), oldValue))
2968 {
2969 destination.get(i) = newValue; // Replace oldValue with newValue
2970 }
2971 else
2972 {
2973 destination.get(i) = source.get(i); // Copy the original value
2974 }
2975 }
2976}
2977
2978template <typename T>
2979void Reverse(Span<T>& span)
2980{
2981 int32_t left = 0;
2982 int32_t right = span.get_Length() - 1;
2983 while (left < right)
2984 {
2985 std::swap(span.get(left), span.get(right));
2986 ++left;
2987 --right;
2988 }
2989}
2990
2991template <typename T>
2992int32_t SequenceCompareTo(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& other)//span.begin() ++
2993{
2994 auto spanIt = span.begin();
2995 auto otherIt = other.begin();
2996 auto spanEnd = span.end();
2997 auto otherEnd = other.end();
2998
2999 while (spanIt != spanEnd && otherIt != otherEnd)
3000 {
3001 if (*spanIt < *otherIt)
3002 {
3003 return -1; // span is less than other
3004 }
3005 if (*spanIt > *otherIt)
3006 {
3007 return 1; // span is greater than other
3008 }
3009
3010 ++spanIt;
3011 ++otherIt;
3012 }
3013
3014 // If all elements are equal up to the length of the shorter span
3015 if (span.get_Length() < other.get_Length())
3016 {
3017 return -1; // span is shorter
3018 }
3019 if (span.get_Length() > other.get_Length())
3020 {
3021 return 1; // span is longer
3022 }
3023
3024 return 0; // spans are equal
3025}
3026
3027template <typename T>
3028int32_t SequenceCompareTo(const Span<T>& span, const ReadOnlySpan<T>& other)
3029{
3030 return SequenceCompareTo(static_cast<ReadOnlySpan<T>>(span), other);
3031}
3032
3033template <typename T>
3034int32_t SequenceCompareTo(const ReadOnlySpan<T>& span, const Span<T>& other)
3035{
3036 return SequenceCompareTo(span, static_cast<ReadOnlySpan<T>>(other));
3037}
3038
3039template <typename T>
3040bool SequenceEqual(const ReadOnlySpan<T>& first, const ReadOnlySpan<T>& second)
3041{
3042 if (first == second)
3043 return true;
3044
3045 if (first.get_Length() != second.get_Length())
3046 {
3047 return false;
3048 }
3049
3050 int32_t length = second.get_Length();
3051
3052 return Details::SequenceEqualImpl(first, 0, first.get_Length(), second);
3053}
3054
3055template <typename T>
3056bool SequenceEqual(const Span<T>& span, const ReadOnlySpan<T>& other)
3057{
3058 return SequenceEqual(static_cast<ReadOnlySpan<T>>(span), other);
3059}
3060
3061template <typename T, typename TComparer>
3062bool SequenceEqual(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& other, SharedPtr<TComparer>& comparer)
3063{
3064 if (comparer == nullptr)
3065 {
3066 return SequenceEqual(span, other);
3067 }
3068
3069 if (span.get_Length() != other.get_Length())
3070 {
3071 return false; // Lengths are not equal
3072 }
3073
3074 for (int32_t i = 0; i < span.get_Length(); ++i)
3075 {
3076 if (!comparer->Equals(span.get(i), other.get(i)))
3077 {
3078 return false; // Elements are not equal
3079 }
3080 }
3081 return true; // All elements are equal
3082}
3083
3084template <typename T, typename TComparer>
3085bool SequenceEqual(const Span<T>& span, const ReadOnlySpan<T>& other, SharedPtr<TComparer>& comparer)
3086{
3087 return SequenceEqual(static_cast<ReadOnlySpan<T>>(span), other, comparer);
3088}
3089
3090template <typename T, typename TComparer>
3091void Sort(const Span<T>& span, const SharedPtr<TComparer>& comparer)
3092{
3093 std::sort(span.begin(), span.end(), [&comparer](const T& a, const T& b) -> bool { return comparer->Compare(a, b) < 0; });
3094}
3095
3096template <typename T>
3097void Sort(Span<T>& span)
3098{
3099 std::sort(span.begin(), span.end());
3100}
3101
3102template <typename TKey, typename TValue, typename TComparer>
3103void Sort(Span<TKey>& keys, Span<TValue>& values, const SharedPtr<TComparer>& comparer)
3104{
3105 if (keys.get_Length() != values.get_Length())
3106 {
3107 throw ArgumentException(u"Keys and items must have the same length.");
3108 }
3109 if (keys.get_Length() > 1)
3110 {
3111 int32_t depthLimit = 2 * (static_cast<int32_t>(std::log2(keys.get_Length())) + 1);
3112 Details::IntroSort<TKey, TValue>(keys, values, depthLimit,
3113 [&comparer](TKey a, TKey b) -> bool { return comparer->Compare(a, b) > 0; });
3114 }
3115}
3116
3117template <typename TKey, typename TValue>
3119{
3120 if (keys.get_Length() != values.get_Length())
3121 {
3122 throw ArgumentException(u"Keys and items must have the same length.");
3123 }
3124 if (keys.get_Length() > 1)
3125 {
3126 int32_t depthLimit = 2 * (static_cast<int32_t>(std::log2(keys.get_Length())) + 1);
3127 Details::IntroSort<TKey, TValue>(keys, values, depthLimit,
3128 [&](const TKey& a, const TKey& b) { return !comparer(a, b); });
3129 }
3130}
3131
3132template <typename TKey, typename TValue>
3133void Sort(Span<TKey>& keys, Span<TValue>& values)
3134{
3135 if (keys.get_Length() != values.get_Length())
3136 {
3137 throw ArgumentException(u"Keys and items must have the same length.");
3138 }
3139 if (keys.get_Length() > 1)
3140 {
3141 int32_t depthLimit = 2 * (static_cast<int32_t>(std::log2(keys.get_Length())) + 1);
3142 Details::IntroSort<TKey, TValue>(keys, values, depthLimit, [&](const TKey& a, const TKey& b) { return a > b; });
3143 }
3144}
3145
3146template <typename T>
3147bool StartsWith(const ReadOnlySpan<T>& span, const T& value)
3148{
3149 if (span.get_Length() == 0)
3150 {
3151 return false; // Empty span cannot start with a value
3152 }
3153 return System::ObjectExt::Equals<T>(span.get(0), value);
3154}
3155
3156template <typename T>
3157bool StartsWith(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& value)
3158{
3159 if (value.get_Length() > span.get_Length())
3160 {
3161 return false;
3162 }
3163
3164 for (int32_t i = 0; i < value.get_Length(); ++i)
3165 {
3166 if (!System::ObjectExt::Equals(span.get(i), value.get(i)))
3167 {
3168 return false;
3169 }
3170 }
3171
3172 return true;
3173}
3174
3175template <typename T>
3176bool StartsWith(const Span<T>& span, const ReadOnlySpan<T>& value)
3177{
3178 return StartsWith(static_cast<ReadOnlySpan<T>>(span), value);
3179}
3180
3181template <typename T>
3182bool StartsWith(const ReadOnlySpan<T>& span, const Span<T>& value)
3183{
3184 return StartsWith(span, static_cast<ReadOnlySpan<T>>(value));
3185}
3186
3187template <typename T>
3188ReadOnlySpan<T> Trim(const ReadOnlySpan<T>& span, T trimElement)
3189{
3190 return Trim(span, ReadOnlySpan<T>(&trimElement, 1));
3191}
3192
3193template <typename T>
3194Span<T> Trim(Span<T>& span, T trimElement)
3195{
3196 return Trim(span, ReadOnlySpan<T>(&trimElement, 1));
3197}
3198
3199template <typename T>
3200ReadOnlySpan<T> Trim(const ReadOnlySpan<T>& span, const ReadOnlySpan<T>& trimElements)
3201{
3202 if (span.get_IsEmpty())
3203 {
3204 return span;
3205 }
3206
3207 int32_t start = 0;
3208 int32_t end = span.get_Length() - 1;
3209
3210 // Trim from the start
3211 while (start <= end && Contains(trimElements, span.get(start)))
3212 {
3213 start++;
3214 }
3215
3216 // Trim from the end
3217 while (end >= start && Contains(trimElements, span.get(end)))
3218 {
3219 end--;
3220 }
3221
3222 return span.Slice(start, end - start + 1);
3223}
3224
3225template <typename T>
3226Span<T> Trim(Span<T>& span, const ReadOnlySpan<T>& trimElements)
3227{
3228 if (span.get_IsEmpty())
3229 {
3230 return span;
3231 }
3232
3233 int32_t start = 0;
3234 int32_t end = span.get_Length() - 1;
3235
3236 // Trim from the start
3237 while (start <= end && Contains(trimElements, span.get(start)))
3238 {
3239 start++;
3240 }
3241
3242 // Trim from the end
3243 while (end >= start && Contains(trimElements, span.get(end)))
3244 {
3245 end--;
3246 }
3247
3248 return span.Slice(start, end - start + 1);
3249}
3250
3251template <typename T>
3252ReadOnlySpan<T> TrimEnd(const ReadOnlySpan<T>& span, const T& trimElement)
3253{
3254 int32_t endIndex = span.get_Length() - 1;
3255 while (endIndex >= 0 && System::ObjectExt::Equals(span.get(endIndex), trimElement))
3256 {
3257 --endIndex;
3258 }
3259 return span.Slice(0, endIndex + 1);
3260}
3261
3262template <typename T>
3263Span<T> TrimEnd(Span<T>& span, const T& trimElement)
3264{
3265 int32_t endIndex = span.get_Length() - 1;
3266 while (endIndex >= 0 && System::ObjectExt::Equals(span.get(endIndex), trimElement)) // equals
3267 {
3268 --endIndex;
3269 }
3270 return span.Slice(0, endIndex + 1);
3271}
3272
3273template <typename T>
3275{
3276 int32_t endIndex = span.get_Length() - 1;
3277 while (endIndex >= 0 && Contains(trimElements, span.get(endIndex)))
3278 {
3279 --endIndex;
3280 }
3281 return span.Slice(0, endIndex + 1);
3282}
3283
3284template <typename T>
3285Span<T> TrimEnd(Span<T>& span, const ReadOnlySpan<T>& trimElements)
3286{
3287 int32_t endIndex = span.get_Length() - 1;
3288 while (endIndex >= 0 && Contains(trimElements, span.get(endIndex)))
3289 {
3290 --endIndex;
3291 }
3292 return span.Slice(0, endIndex + 1);
3293}
3294
3295template <typename T>
3296ReadOnlySpan<T> TrimStart(const ReadOnlySpan<T>& span, const T& trimElement)
3297{
3298 int32_t startIndex = 0;
3299 while (startIndex < span.get_Length() && System::ObjectExt::Equals(span.get(startIndex), trimElement))
3300 {
3301 ++startIndex;
3302 }
3303 return span.Slice(startIndex);
3304}
3305
3306template <typename T>
3307Span<T> TrimStart(Span<T>& span, const T& trimElement)
3308{
3309 int32_t startIndex = 0;
3310 while (startIndex < span.get_Length() && System::ObjectExt::Equals(span.get(startIndex), trimElement))
3311 {
3312 ++startIndex;
3313 }
3314 return span.Slice(startIndex);
3315}
3316
3317template <typename T>
3319{
3320 int32_t startIndex = 0;
3321 while (startIndex < span.get_Length() && Contains(trimElements, span.get(startIndex)))
3322 {
3323 ++startIndex;
3324 }
3325 return span.Slice(startIndex);
3326}
3327
3328template <typename T>
3329Span<T> TrimStart(Span<T>& span, const ReadOnlySpan<T>& trimElements)
3330{
3331 int32_t startIndex = 0;
3332 while (startIndex < span.get_Length() && Contains(trimElements, span.get(startIndex)))
3333 {
3334 ++startIndex;
3335 }
3336 return span.Slice(startIndex);
3337}
3338} // namespace MemoryExtensions
3339} // namespace System
3340#endif // _aspose_system_memory_extensions_
3341
Represents a pointer to the method that compares two objects of the same type. This type should be al...
Definition: comparison.h:93
static std::enable_if< IsExceptionWrapper< T >::value, bool >::type Equals(const T &obj, const T2 &another)
Definition: object_ext.h:34
Forward to use within Span class.
Definition: span.h:411
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:371
String class used across the library. Is a substitute for C# System.String when translating code....
Definition: string.h:122
bool SequenceEqualImpl(const ReadOnlySpan< T > &first, const int32_t start, int32_t length, const ReadOnlySpan< T > &second)
Checks if two spans are equal starting from specified positions.
Definition: memory_extensions.h:223
void SwapIfGreaterWithValues(Span< TKey > &keys, Span< TValue > &values, std::function< int32_t(const TKey &, const TKey &)> comparer, int32_t i, int32_t j)
Swaps key-value pairs if comparison condition is met.
Definition: memory_extensions.h:308
int32_t PickPivotAndPartition(Span< TKey > &keys, Span< TValue > &values, std::function< int32_t(const TKey &, const TKey &)> comparer)
Selects pivot and partitions key-value pairs for quicksort.
Definition: memory_extensions.h:385
void HeapSort(Span< TKey > &keys, Span< TValue > &values, std::function< int32_t(const TKey &, const TKey &)> comparer)
Performs heap sort on key-value pairs.
Definition: memory_extensions.h:340
const std::array< char16_t, 22 > DefaultWhitespaceChars
Default whitespace characters used for trimming operations.
void InsertionSort(Span< TKey > &keys, Span< TValue > &values, std::function< int32_t(const TKey &, const TKey &)> comparer)
Performs insertion sort on key-value pairs.
Definition: memory_extensions.h:319
const ReadOnlySpan< char16_t > DefaultWhitespaceSpan
Static ReadOnlySpan for default whitespace characters to avoid array creation.
int32_t LastIndexOfImpl(const ReadOnlySpan< T > &searchSpace, int32_t length, const T &value)
Finds the last index of a value in a span.
Definition: memory_extensions.h:183
int32_t Compare(const SharedPtr< T > &a, const SharedPtr< U > &b)
Compares two smart pointers.
Definition: memory_extensions.h:150
int32_t BinarySearchImpl(const ReadOnlySpan< T > &span, const TValue &value, TCompareFunc compareFunc)
Common binary search implementation.
Definition: memory_extensions.h:432
void Heapify(Span< TKey > &keys, Span< TValue > &values, int32_t n, int32_t i, std::function< int32_t(const TKey &, const TKey &)> comparer)
Maintains heap property for key-value pairs.
Definition: memory_extensions.h:359
void IntroSort(Span< TKey > &keys, Span< TValue > &values, int32_t depthLimit, std::function< int32_t(const TKey &, const TKey &)> comparer)
Internal implementation of introsort algorithm for key-value pairs.
Definition: memory_extensions.h:260
int32_t BinarySearch(const ReadOnlySpan< T > &span, const TComparable &comparable)
Performs binary search on a sorted span.
Definition: memory_extensions.h:1965
int32_t SequenceCompareTo(const ReadOnlySpan< T > &span, const ReadOnlySpan< T > &other)
Compares two ReadOnlySpans lexicographically.
Definition: memory_extensions.h:2992
int32_t IndexOfAny(const ReadOnlySpan< T > &span, const T &value0, const T &value1)
Finds the index of the first occurrence of any of two specified values in a ReadOnlySpan<T>
Definition: memory_extensions.h:2456
bool Overlaps(const ReadOnlySpan< T > &span, const ReadOnlySpan< T > &other)
Determines if two ReadOnlySpans overlap in memory without calculating offset.
Definition: memory_extensions.h:2905
int32_t LastIndexOfAnyExceptInRange(const ReadOnlySpan< T > &span, const T &lowInclusive, const T &highInclusive)
Finds the last occurrence of any element outside the specified range within a span.
Definition: memory_extensions.h:2867
ReadOnlySpan< T > TrimEnd(const ReadOnlySpan< T > &span, const T &trimElement)
Trims specified element from the end of a typed span.
Definition: memory_extensions.h:3252
int32_t LastIndexOfAnyInRange(const ReadOnlySpan< T > &span, const T &lowInclusive, const T &highInclusive)
Finds the last occurrence of any element within the specified range within a span.
Definition: memory_extensions.h:2886
int32_t ToUpperInvariant(const ReadOnlySpan< char16_t > &source, Span< char16_t > &destination)
Converts characters to uppercase using invariant culture.
Span< T > AsSpan(const ArrayPtr< T > &array, int32_t start=0, int32_t length=-1)
Creates a span from an array.
Definition: memory_extensions.h:1946
int32_t IndexOf(const ReadOnlySpan< T > &span, const ReadOnlySpan< T > &value)
Finds the index of a ReadOnlySpan<T> value in another ReadOnlySpan<T>
Definition: memory_extensions.h:2370
void Reverse(Span< T > &span)
Reverses the order of elements in a Span in-place.
Definition: memory_extensions.h:2979
bool ContainsAnyInRange(const ReadOnlySpan< T > &span, const T &lowInclusive, const T &highInclusive)
Checks if a read-only span contains any element within the specified range.
Definition: memory_extensions.h:2241
void CopyTo(const ArrayPtr< T > &source, Span< T > &destination)
Copies elements from an array to a span.
Definition: memory_extensions.h:2267
bool StartsWith(const ReadOnlySpan< T > &span, const T &value)
Checks if the span starts with the specified value.
Definition: memory_extensions.h:3147
void Replace(Span< T > &span, const T &oldValue, const T &newValue)
Replaces all occurrences of a value with a new value in a Span.
Definition: memory_extensions.h:2946
bool ContainsAnyExceptInRange(const ReadOnlySpan< T > &span, const T &lowInclusive, const T &highInclusive)
Checks if a read-only span contains any element outside the specified range.
Definition: memory_extensions.h:2215
bool Equals(const ReadOnlySpan< char16_t > &span, const ReadOnlySpan< char16_t > &other, StringComparison comparisonType)
Compares two ReadOnlySpan<char16_t> for equality using StringComparison.
int32_t ToLower(const ReadOnlySpan< char16_t > &source, Span< char16_t > &destination, const SharedPtr< Globalization::CultureInfo > &culture)
Converts characters to lowercase using specified culture.
int32_t LastIndexOfAnyExcept(const ReadOnlySpan< T > &span, const T &value0, const T &value1, const T &value2)
Finds the last occurrence of any element except three specified values within a span.
Definition: memory_extensions.h:2771
int32_t IndexOfAnyExcept(const ReadOnlySpan< T > &span, const T &value)
Finds the index of the first element that is not equal to the specified value in a ReadOnlySpan<T>
Definition: memory_extensions.h:2517
int32_t CommonPrefixLength(const ReadOnlySpan< T > &span, const ReadOnlySpan< T > &other)
Finds the length of the common prefix between two spans.
Definition: memory_extensions.h:1995
bool SequenceEqual(const ReadOnlySpan< T > &first, const ReadOnlySpan< T > &second)
Determines if two ReadOnlySpans contain identical elements in the same order.
Definition: memory_extensions.h:3040
int32_t LastIndexOfAny(const ReadOnlySpan< T > &span, const T &value0, const T &value1, const T &value2)
Finds the last occurrence of any of three specified values within a span.
Definition: memory_extensions.h:2704
int32_t IndexOfAnyExceptInRange(const ReadOnlySpan< T > &span, const T &lowInclusive, const T &highInclusive)
Finds the index of the first element that is outside the specified range in a ReadOnlySpan<T>
Definition: memory_extensions.h:2603
bool ContainsAny(const ReadOnlySpan< T > &span, const T &value0, const T &value1)
Checks if a read-only span contains any of two values.
Definition: memory_extensions.h:2079
bool EndsWith(const ReadOnlySpan< T > &span, const T &value)
Determines if a ReadOnlySpan<T> ends with a single value.
Definition: memory_extensions.h:2323
ReadOnlySpan< T > Trim(const ReadOnlySpan< T > &span, T trimElement)
Trims specified element from both ends of a typed span.
Definition: memory_extensions.h:3188
void Sort(const Span< T > &span, const SharedPtr< TComparer > &comparer)
Sorts a Span using a custom comparer.
Definition: memory_extensions.h:3091
int32_t CompareTo(const ReadOnlySpan< char16_t > &span, const ReadOnlySpan< char16_t > &other, StringComparison comparisonType)
Compares two character spans with specified string comparison rules.
bool ContainsAnyExcept(const ReadOnlySpan< T > &span, const T &value0, const T &value1, const T &value2)
Checks if a read-only span contains any element except three specified values.
Definition: memory_extensions.h:2122
int32_t Count(const ReadOnlySpan< T > &span, const T &value)
Counts occurrences of a value in a read-only span.
Definition: memory_extensions.h:2273
int32_t ToUpper(const ReadOnlySpan< char16_t > &source, Span< char16_t > &destination, const SharedPtr< Globalization::CultureInfo > &culture)
Converts characters to uppercase using specified culture.
int32_t LastIndexOf(const ReadOnlySpan< T > &span, const ReadOnlySpan< T > &value)
Finds the last occurrence of a sequence within a span.
Definition: memory_extensions.h:2642
ReadOnlySpan< T > TrimStart(const ReadOnlySpan< T > &span, const T &trimElement)
Trims specified element from the start of a typed span.
Definition: memory_extensions.h:3296
bool Contains(const ReadOnlySpan< T > &span, const T &value)
Checks if a read-only span contains a specific value.
Definition: memory_extensions.h:2066
int32_t IndexOfAnyInRange(const ReadOnlySpan< T > &span, const T &lowInclusive, const T &highInclusive)
Finds the index of the first element that is within the specified range in a ReadOnlySpan<T>
Definition: memory_extensions.h:2622
bool IsWhiteSpace(const ReadOnlySpan< char16_t > &span)
Checks if the entire span consists only of whitespace characters.
int32_t ToLowerInvariant(const ReadOnlySpan< char16_t > &source, Span< char16_t > &destination)
Converts characters to lowercase using invariant culture.
Definition: db_command.h:9
std::enable_if_t<!std::is_floating_point< TA >::value &&!std::is_floating_point< TB >::value, int > Compare(const TA &a, const TB &b)
Compares two values.
Definition: primitive_types.h:113
StringComparison
Defines string comparison style.
Definition: string_comparison.h:13