stringzillas-cuda 4.2.2__tar.gz → 4.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {stringzillas_cuda-4.2.2/stringzillas_cuda.egg-info → stringzillas_cuda-4.2.3}/PKG-INFO +6 -6
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/README.md +4 -4
- stringzillas_cuda-4.2.3/VERSION +1 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzilla/find.h +24 -26
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzilla/intersect.h +2 -2
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzilla/memory.h +2 -3
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzilla/stringzilla.h +1 -1
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzilla/stringzilla.hpp +222 -150
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzilla/types.h +3 -2
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3/stringzillas_cuda.egg-info}/PKG-INFO +6 -6
- stringzillas_cuda-4.2.3/stringzillas_cuda.egg-info/requires.txt +1 -0
- stringzillas_cuda-4.2.2/VERSION +0 -1
- stringzillas_cuda-4.2.2/stringzillas_cuda.egg-info/requires.txt +0 -1
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/LICENSE +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/MANIFEST.in +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/SZ_TARGET.env +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/build_backend.py +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/c/stringzilla.c +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/c/stringzillas.cpp +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/c/stringzillas.cu +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/c/stringzillas.cuh +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/cli/__init__.py +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/cli/split.py +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/cli/wc.py +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/fork_union/include/fork_union.h +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/fork_union/include/fork_union.hpp +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzilla/compare.h +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzilla/hash.h +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzilla/module.modulemap +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzilla/small_string.h +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzilla/sort.h +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzilla/types.hpp +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzillas/fingerprints.cuh +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzillas/fingerprints.hpp +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzillas/similarities.cuh +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzillas/similarities.hpp +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzillas/stringzillas.h +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzillas/types.cuh +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/include/stringzillas/types.hpp +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/pyproject.toml +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/python/stringzilla.c +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/python/stringzillas.c +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/scripts/test_stringzilla.py +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/scripts/test_stringzillas.py +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/setup.cfg +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/setup.py +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/stringzillas_cuda.egg-info/SOURCES.txt +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/stringzillas_cuda.egg-info/dependency_links.txt +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/stringzillas_cuda.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stringzillas-cuda
|
|
3
|
-
Version: 4.2.
|
|
3
|
+
Version: 4.2.3
|
|
4
4
|
Summary: Search, hash, sort, fingerprint, and fuzzy-match strings faster via SWAR, SIMD, and CUDA on Nvidia GPUs
|
|
5
5
|
Home-page: https://github.com/ashvardanian/StringZilla
|
|
6
6
|
Author: Ash Vardanian
|
|
@@ -30,7 +30,7 @@ Classifier: Topic :: Text Processing :: Indexing
|
|
|
30
30
|
Requires-Python: >=3.8
|
|
31
31
|
Description-Content-Type: text/markdown
|
|
32
32
|
License-File: LICENSE
|
|
33
|
-
Requires-Dist: stringzilla==4.2.
|
|
33
|
+
Requires-Dist: stringzilla==4.2.3
|
|
34
34
|
Dynamic: author
|
|
35
35
|
Dynamic: author-email
|
|
36
36
|
Dynamic: classifier
|
|
@@ -1134,10 +1134,10 @@ Similar to GCC, StringZilla is 32 bytes in size, and similar to Clang it can fit
|
|
|
1134
1134
|
Our layout might be preferential, if you want to avoid branches.
|
|
1135
1135
|
If you use a different compiler, you may want to check its SSO buffer size with a [simple Gist](https://gist.github.com/ashvardanian/c197f15732d9855c4e070797adf17b21).
|
|
1136
1136
|
|
|
1137
|
-
|
|
|
1138
|
-
|
|
|
1139
|
-
| `sizeof
|
|
1140
|
-
|
|
|
1137
|
+
| | `libstdc++` in GCC 13 | `libc++` in Clang 17 | StringZilla |
|
|
1138
|
+
| :-------------- | ---------------------: | -------------------: | ----------: |
|
|
1139
|
+
| String `sizeof` | 32 | 24 | 32 |
|
|
1140
|
+
| Inner Capacity | 15 | __22__ | __22__ |
|
|
1141
1141
|
|
|
1142
1142
|
This design has been since ported to many high-level programming languages.
|
|
1143
1143
|
Swift, for example, [can store 15 bytes](https://developer.apple.com/documentation/swift/substring/withutf8(_:)#discussion) in the `String` instance itself.
|
|
@@ -1089,10 +1089,10 @@ Similar to GCC, StringZilla is 32 bytes in size, and similar to Clang it can fit
|
|
|
1089
1089
|
Our layout might be preferential, if you want to avoid branches.
|
|
1090
1090
|
If you use a different compiler, you may want to check its SSO buffer size with a [simple Gist](https://gist.github.com/ashvardanian/c197f15732d9855c4e070797adf17b21).
|
|
1091
1091
|
|
|
1092
|
-
|
|
|
1093
|
-
|
|
|
1094
|
-
| `sizeof
|
|
1095
|
-
|
|
|
1092
|
+
| | `libstdc++` in GCC 13 | `libc++` in Clang 17 | StringZilla |
|
|
1093
|
+
| :-------------- | ---------------------: | -------------------: | ----------: |
|
|
1094
|
+
| String `sizeof` | 32 | 24 | 32 |
|
|
1095
|
+
| Inner Capacity | 15 | __22__ | __22__ |
|
|
1096
1096
|
|
|
1097
1097
|
This design has been since ported to many high-level programming languages.
|
|
1098
1098
|
Swift, for example, [can store 15 bytes](https://developer.apple.com/documentation/swift/substring/withutf8(_:)#discussion) in the `String` instance itself.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4.2.3
|
|
@@ -905,7 +905,7 @@ SZ_PUBLIC sz_cptr_t sz_find_westmere(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
905
905
|
sz_locate_needle_anomalies_(n, n_length, &offset_first, &offset_mid, &offset_last);
|
|
906
906
|
|
|
907
907
|
// Broadcast those characters into XMM registers.
|
|
908
|
-
|
|
908
|
+
sz_u32_vec_t matches_vec;
|
|
909
909
|
sz_u128_vec_t h_first_vec, h_mid_vec, h_last_vec, n_first_vec, n_mid_vec, n_last_vec;
|
|
910
910
|
n_first_vec.xmm = _mm_set1_epi8(n[offset_first]);
|
|
911
911
|
n_mid_vec.xmm = _mm_set1_epi8(n[offset_mid]);
|
|
@@ -916,14 +916,14 @@ SZ_PUBLIC sz_cptr_t sz_find_westmere(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
916
916
|
h_first_vec.xmm = _mm_lddqu_si128((__m128i const *)(h + offset_first));
|
|
917
917
|
h_mid_vec.xmm = _mm_lddqu_si128((__m128i const *)(h + offset_mid));
|
|
918
918
|
h_last_vec.xmm = _mm_lddqu_si128((__m128i const *)(h + offset_last));
|
|
919
|
-
|
|
919
|
+
matches_vec.i32 = //
|
|
920
920
|
_mm_movemask_epi8(_mm_cmpeq_epi8(h_first_vec.xmm, n_first_vec.xmm)) &
|
|
921
921
|
_mm_movemask_epi8(_mm_cmpeq_epi8(h_mid_vec.xmm, n_mid_vec.xmm)) &
|
|
922
922
|
_mm_movemask_epi8(_mm_cmpeq_epi8(h_last_vec.xmm, n_last_vec.xmm));
|
|
923
|
-
while (
|
|
924
|
-
int potential_offset = sz_u32_ctz(
|
|
923
|
+
while (matches_vec.u32) {
|
|
924
|
+
int potential_offset = sz_u32_ctz(matches_vec.u32);
|
|
925
925
|
if (sz_equal_westmere(h + potential_offset, n, n_length)) return h + potential_offset;
|
|
926
|
-
|
|
926
|
+
matches_vec.u32 &= matches_vec.u32 - 1;
|
|
927
927
|
}
|
|
928
928
|
}
|
|
929
929
|
|
|
@@ -940,7 +940,7 @@ SZ_PUBLIC sz_cptr_t sz_rfind_westmere(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
940
940
|
sz_locate_needle_anomalies_(n, n_length, &offset_first, &offset_mid, &offset_last);
|
|
941
941
|
|
|
942
942
|
// Broadcast those characters into XMM registers.
|
|
943
|
-
|
|
943
|
+
sz_u32_vec_t matches_vec;
|
|
944
944
|
sz_u128_vec_t h_first_vec, h_mid_vec, h_last_vec, n_first_vec, n_mid_vec, n_last_vec;
|
|
945
945
|
n_first_vec.xmm = _mm_set1_epi8(n[offset_first]);
|
|
946
946
|
n_mid_vec.xmm = _mm_set1_epi8(n[offset_mid]);
|
|
@@ -953,15 +953,15 @@ SZ_PUBLIC sz_cptr_t sz_rfind_westmere(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
953
953
|
h_first_vec.xmm = _mm_lddqu_si128((__m128i const *)(h_reversed + offset_first));
|
|
954
954
|
h_mid_vec.xmm = _mm_lddqu_si128((__m128i const *)(h_reversed + offset_mid));
|
|
955
955
|
h_last_vec.xmm = _mm_lddqu_si128((__m128i const *)(h_reversed + offset_last));
|
|
956
|
-
|
|
956
|
+
matches_vec.i32 = //
|
|
957
957
|
_mm_movemask_epi8(_mm_cmpeq_epi8(h_first_vec.xmm, n_first_vec.xmm)) &
|
|
958
958
|
_mm_movemask_epi8(_mm_cmpeq_epi8(h_mid_vec.xmm, n_mid_vec.xmm)) &
|
|
959
959
|
_mm_movemask_epi8(_mm_cmpeq_epi8(h_last_vec.xmm, n_last_vec.xmm));
|
|
960
|
-
while (
|
|
961
|
-
int potential_offset = sz_u32_clz(
|
|
960
|
+
while (matches_vec.u32) {
|
|
961
|
+
int potential_offset = sz_u32_clz(matches_vec.u32) - 16;
|
|
962
962
|
if (sz_equal_westmere(h + h_length - n_length - potential_offset, n, n_length))
|
|
963
963
|
return h + h_length - n_length - potential_offset;
|
|
964
|
-
|
|
964
|
+
matches_vec.u32 &= ~(1u << (15 - potential_offset));
|
|
965
965
|
}
|
|
966
966
|
}
|
|
967
967
|
|
|
@@ -1029,7 +1029,7 @@ SZ_PUBLIC sz_cptr_t sz_find_haswell(sz_cptr_t h, sz_size_t h_length, sz_cptr_t n
|
|
|
1029
1029
|
sz_locate_needle_anomalies_(n, n_length, &offset_first, &offset_mid, &offset_last);
|
|
1030
1030
|
|
|
1031
1031
|
// Broadcast those characters into YMM registers.
|
|
1032
|
-
|
|
1032
|
+
sz_u32_vec_t matches_vec;
|
|
1033
1033
|
sz_u256_vec_t h_first_vec, h_mid_vec, h_last_vec, n_first_vec, n_mid_vec, n_last_vec;
|
|
1034
1034
|
n_first_vec.ymm = _mm256_set1_epi8(n[offset_first]);
|
|
1035
1035
|
n_mid_vec.ymm = _mm256_set1_epi8(n[offset_mid]);
|
|
@@ -1040,14 +1040,14 @@ SZ_PUBLIC sz_cptr_t sz_find_haswell(sz_cptr_t h, sz_size_t h_length, sz_cptr_t n
|
|
|
1040
1040
|
h_first_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h + offset_first));
|
|
1041
1041
|
h_mid_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h + offset_mid));
|
|
1042
1042
|
h_last_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h + offset_last));
|
|
1043
|
-
|
|
1043
|
+
matches_vec.i32 = //
|
|
1044
1044
|
_mm256_movemask_epi8(_mm256_cmpeq_epi8(h_first_vec.ymm, n_first_vec.ymm)) &
|
|
1045
1045
|
_mm256_movemask_epi8(_mm256_cmpeq_epi8(h_mid_vec.ymm, n_mid_vec.ymm)) &
|
|
1046
1046
|
_mm256_movemask_epi8(_mm256_cmpeq_epi8(h_last_vec.ymm, n_last_vec.ymm));
|
|
1047
|
-
while (
|
|
1048
|
-
int potential_offset = sz_u32_ctz(
|
|
1047
|
+
while (matches_vec.u32) {
|
|
1048
|
+
int potential_offset = sz_u32_ctz(matches_vec.u32);
|
|
1049
1049
|
if (sz_equal_haswell(h + potential_offset, n, n_length)) return h + potential_offset;
|
|
1050
|
-
|
|
1050
|
+
matches_vec.u32 &= matches_vec.u32 - 1;
|
|
1051
1051
|
}
|
|
1052
1052
|
}
|
|
1053
1053
|
|
|
@@ -1065,7 +1065,7 @@ SZ_PUBLIC sz_cptr_t sz_rfind_haswell(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
1065
1065
|
sz_locate_needle_anomalies_(n, n_length, &offset_first, &offset_mid, &offset_last);
|
|
1066
1066
|
|
|
1067
1067
|
// Broadcast those characters into YMM registers.
|
|
1068
|
-
|
|
1068
|
+
sz_u32_vec_t matches_vec;
|
|
1069
1069
|
sz_u256_vec_t h_first_vec, h_mid_vec, h_last_vec, n_first_vec, n_mid_vec, n_last_vec;
|
|
1070
1070
|
n_first_vec.ymm = _mm256_set1_epi8(n[offset_first]);
|
|
1071
1071
|
n_mid_vec.ymm = _mm256_set1_epi8(n[offset_mid]);
|
|
@@ -1078,15 +1078,15 @@ SZ_PUBLIC sz_cptr_t sz_rfind_haswell(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
1078
1078
|
h_first_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h_reversed + offset_first));
|
|
1079
1079
|
h_mid_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h_reversed + offset_mid));
|
|
1080
1080
|
h_last_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h_reversed + offset_last));
|
|
1081
|
-
|
|
1081
|
+
matches_vec.i32 = //
|
|
1082
1082
|
_mm256_movemask_epi8(_mm256_cmpeq_epi8(h_first_vec.ymm, n_first_vec.ymm)) &
|
|
1083
1083
|
_mm256_movemask_epi8(_mm256_cmpeq_epi8(h_mid_vec.ymm, n_mid_vec.ymm)) &
|
|
1084
1084
|
_mm256_movemask_epi8(_mm256_cmpeq_epi8(h_last_vec.ymm, n_last_vec.ymm));
|
|
1085
|
-
while (
|
|
1086
|
-
int potential_offset = sz_u32_clz(
|
|
1085
|
+
while (matches_vec.u32) {
|
|
1086
|
+
int potential_offset = sz_u32_clz(matches_vec.u32);
|
|
1087
1087
|
if (sz_equal_haswell(h + h_length - n_length - potential_offset, n, n_length))
|
|
1088
1088
|
return h + h_length - n_length - potential_offset;
|
|
1089
|
-
|
|
1089
|
+
matches_vec.u32 &= ~(1u << (31 - potential_offset));
|
|
1090
1090
|
}
|
|
1091
1091
|
}
|
|
1092
1092
|
|
|
@@ -1388,9 +1388,8 @@ SZ_PUBLIC sz_cptr_t sz_rfind_skylake(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
1388
1388
|
int potential_offset = sz_u64_clz(matches);
|
|
1389
1389
|
if (n_length <= 3 || sz_equal_skylake(h + h_length - n_length - potential_offset, n, n_length))
|
|
1390
1390
|
return h + h_length - n_length - potential_offset;
|
|
1391
|
-
sz_assert_((matches & (
|
|
1392
|
-
|
|
1393
|
-
matches &= ~((sz_u64_t)1 << (63 - potential_offset));
|
|
1391
|
+
sz_assert_((matches & (1ull << (63 - potential_offset))) != 0 && "The bit must be set before we squash it");
|
|
1392
|
+
matches &= ~(1ull << (63 - potential_offset));
|
|
1394
1393
|
}
|
|
1395
1394
|
}
|
|
1396
1395
|
|
|
@@ -1409,9 +1408,8 @@ SZ_PUBLIC sz_cptr_t sz_rfind_skylake(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
1409
1408
|
int potential_offset = sz_u64_clz(matches);
|
|
1410
1409
|
if (n_length <= 3 || sz_equal_skylake(h + 64 - potential_offset - 1, n, n_length))
|
|
1411
1410
|
return h + 64 - potential_offset - 1;
|
|
1412
|
-
sz_assert_((matches & (
|
|
1413
|
-
|
|
1414
|
-
matches &= ~((sz_u64_t)1 << (63 - potential_offset));
|
|
1411
|
+
sz_assert_((matches & (1ull << (63 - potential_offset))) != 0 && "The bit must be set before we squash it");
|
|
1412
|
+
matches &= ~(1ull << (63 - potential_offset));
|
|
1415
1413
|
}
|
|
1416
1414
|
}
|
|
1417
1415
|
|
|
@@ -288,7 +288,7 @@ SZ_PUBLIC sz_status_t sz_sequence_intersect_serial(
|
|
|
288
288
|
// Allocate memory for the hash table and initialize it with 0xFF.
|
|
289
289
|
// The higher is the `hash_table_slots` multiple - the more memory we will use,
|
|
290
290
|
// but the less likely the collisions will be.
|
|
291
|
-
sz_size_t const hash_table_slots = sz_size_bit_ceil(small_sequence->count) * (
|
|
291
|
+
sz_size_t const hash_table_slots = sz_size_bit_ceil(small_sequence->count) * (1u << SZ_SEQUENCE_INTERSECT_BUDGET);
|
|
292
292
|
sz_size_t const bytes_per_entry = sizeof(sz_size_t) + sizeof(sz_u64_t);
|
|
293
293
|
sz_size_t *const table_positions = (sz_size_t *)alloc->allocate(hash_table_slots * bytes_per_entry, alloc);
|
|
294
294
|
if (!table_positions) return sz_bad_alloc_k;
|
|
@@ -414,7 +414,7 @@ SZ_PUBLIC sz_status_t sz_sequence_intersect_ice(
|
|
|
414
414
|
// Allocate memory for the hash table and initialize it with 0xFF.
|
|
415
415
|
// The higher is the `hash_table_slots` multiple - the more memory we will use,
|
|
416
416
|
// but the less likely the collisions will be.
|
|
417
|
-
sz_size_t const hash_table_slots = sz_size_bit_ceil(small_sequence->count) * (
|
|
417
|
+
sz_size_t const hash_table_slots = sz_size_bit_ceil(small_sequence->count) * (1u << SZ_SEQUENCE_INTERSECT_BUDGET);
|
|
418
418
|
sz_size_t const bytes_per_entry = sizeof(sz_size_t) + sizeof(sz_u64_t);
|
|
419
419
|
sz_size_t *table_positions = (sz_size_t *)alloc->allocate(hash_table_slots * bytes_per_entry, alloc);
|
|
420
420
|
if (!table_positions) return sz_bad_alloc_k;
|
|
@@ -1194,6 +1194,7 @@ SZ_PUBLIC void sz_lookup_neon(sz_ptr_t target, sz_size_t length, sz_cptr_t sourc
|
|
|
1194
1194
|
|
|
1195
1195
|
sz_size_t head_length = (16 - ((sz_size_t)target % 16)) % 16; // 15 or less.
|
|
1196
1196
|
sz_size_t tail_length = (sz_size_t)(target + length) % 16; // 15 or less.
|
|
1197
|
+
sz_size_t body_length = length - head_length - tail_length;
|
|
1197
1198
|
|
|
1198
1199
|
// We need to pull the lookup table into 16x NEON registers. We have a total of 32 such registers.
|
|
1199
1200
|
// According to the Neoverse V2 manual, the 4-table lookup has a latency of 6 cycles, and 4x throughput.
|
|
@@ -1216,9 +1217,7 @@ SZ_PUBLIC void sz_lookup_neon(sz_ptr_t target, sz_size_t length, sz_cptr_t sourc
|
|
|
1216
1217
|
// to perform a 4-table lookup in a single instruction. The XORs are used to adjust the lookup position
|
|
1217
1218
|
// within each 64-byte range of the table.
|
|
1218
1219
|
// Details on the 4-table lookup: https://lemire.me/blog/2019/07/23/arbitrary-byte-to-byte-maps-using-arm-neon/
|
|
1219
|
-
|
|
1220
|
-
length -= tail_length;
|
|
1221
|
-
for (; length >= 16; source += 16, target += 16, length -= 16) {
|
|
1220
|
+
for (; body_length >= 16; source += 16, target += 16, body_length -= 16) {
|
|
1222
1221
|
source_vec.u8x16 = vld1q_u8((sz_u8_t const *)source);
|
|
1223
1222
|
lookup_0_to_63_vec.u8x16 = vqtbl4q_u8(lut_0_to_63_vec, source_vec.u8x16);
|
|
1224
1223
|
lookup_64_to_127_vec.u8x16 = vqtbl4q_u8(lut_64_to_127_vec, veorq_u8(source_vec.u8x16, vdupq_n_u8(0x40)));
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
|
|
68
68
|
#define STRINGZILLA_H_VERSION_MAJOR 4
|
|
69
69
|
#define STRINGZILLA_H_VERSION_MINOR 2
|
|
70
|
-
#define STRINGZILLA_H_VERSION_PATCH
|
|
70
|
+
#define STRINGZILLA_H_VERSION_PATCH 3
|
|
71
71
|
|
|
72
72
|
#include "types.h" // `sz_size_t`, `sz_bool_t`, `sz_ordering_t`
|
|
73
73
|
#include "compare.h" // `sz_equal`, `sz_order`
|
|
@@ -401,7 +401,7 @@ inline static constexpr exclude_overlaps_type exclude_overlaps;
|
|
|
401
401
|
* @brief Zero-cost wrapper around the `.find` member function of string-like classes.
|
|
402
402
|
* @see https://en.cppreference.com/w/cpp/string/basic_string/find
|
|
403
403
|
*/
|
|
404
|
-
template <typename string_type_, typename
|
|
404
|
+
template <typename string_type_, typename overlaps_type_ = include_overlaps_type>
|
|
405
405
|
struct matcher_find {
|
|
406
406
|
using size_type = typename string_type_::size_type;
|
|
407
407
|
string_type_ needle_;
|
|
@@ -411,7 +411,7 @@ struct matcher_find {
|
|
|
411
411
|
size_type operator()(string_type_ haystack) const noexcept { return haystack.find(needle_); }
|
|
412
412
|
size_type skip_length() const noexcept {
|
|
413
413
|
// TODO: Apply Galil rule to match repetitive patterns in strictly linear time.
|
|
414
|
-
return is_same_type<
|
|
414
|
+
return is_same_type<overlaps_type_, include_overlaps_type>::value ? 1 : needle_.length();
|
|
415
415
|
}
|
|
416
416
|
};
|
|
417
417
|
|
|
@@ -419,7 +419,7 @@ struct matcher_find {
|
|
|
419
419
|
* @brief Zero-cost wrapper around the `.rfind` member function of string-like classes.
|
|
420
420
|
* @see https://en.cppreference.com/w/cpp/string/basic_string/rfind
|
|
421
421
|
*/
|
|
422
|
-
template <typename string_type_, typename
|
|
422
|
+
template <typename string_type_, typename overlaps_type_ = include_overlaps_type>
|
|
423
423
|
struct matcher_rfind {
|
|
424
424
|
using size_type = typename string_type_::size_type;
|
|
425
425
|
string_type_ needle_;
|
|
@@ -429,7 +429,7 @@ struct matcher_rfind {
|
|
|
429
429
|
size_type operator()(string_type_ haystack) const noexcept { return haystack.rfind(needle_); }
|
|
430
430
|
size_type skip_length() const noexcept {
|
|
431
431
|
// TODO: Apply Galil rule to match repetitive patterns in strictly linear time.
|
|
432
|
-
return is_same_type<
|
|
432
|
+
return is_same_type<overlaps_type_, include_overlaps_type>::value ? 1 : needle_.length();
|
|
433
433
|
}
|
|
434
434
|
};
|
|
435
435
|
|
|
@@ -437,56 +437,97 @@ struct matcher_rfind {
|
|
|
437
437
|
* @brief Zero-cost wrapper around the `.find_first_of` member function of string-like classes.
|
|
438
438
|
* @see https://en.cppreference.com/w/cpp/string/basic_string/find_first_of
|
|
439
439
|
*/
|
|
440
|
-
template <typename
|
|
440
|
+
template <typename haystack_type_, typename needles_type_ = haystack_type_>
|
|
441
441
|
struct matcher_find_first_of {
|
|
442
|
-
using size_type = typename
|
|
443
|
-
|
|
442
|
+
using size_type = typename haystack_type_::size_type;
|
|
443
|
+
needles_type_ needles_;
|
|
444
444
|
constexpr size_type needle_length() const noexcept { return 1; }
|
|
445
445
|
constexpr size_type skip_length() const noexcept { return 1; }
|
|
446
|
-
size_type operator()(
|
|
446
|
+
size_type operator()(haystack_type_ haystack) const noexcept { return haystack.find_first_of(needles_); }
|
|
447
447
|
};
|
|
448
448
|
|
|
449
449
|
/**
|
|
450
450
|
* @brief Zero-cost wrapper around the `.find_last_of` member function of string-like classes.
|
|
451
451
|
* @see https://en.cppreference.com/w/cpp/string/basic_string/find_last_of
|
|
452
452
|
*/
|
|
453
|
-
template <typename
|
|
453
|
+
template <typename haystack_type_, typename needles_type_ = haystack_type_>
|
|
454
454
|
struct matcher_find_last_of {
|
|
455
|
-
using size_type = typename
|
|
456
|
-
|
|
455
|
+
using size_type = typename haystack_type_::size_type;
|
|
456
|
+
needles_type_ needles_;
|
|
457
457
|
constexpr size_type needle_length() const noexcept { return 1; }
|
|
458
458
|
constexpr size_type skip_length() const noexcept { return 1; }
|
|
459
|
-
size_type operator()(
|
|
459
|
+
size_type operator()(haystack_type_ haystack) const noexcept { return haystack.find_last_of(needles_); }
|
|
460
460
|
};
|
|
461
461
|
|
|
462
462
|
/**
|
|
463
463
|
* @brief Zero-cost wrapper around the `.find_first_not_of` member function of string-like classes.
|
|
464
464
|
* @see https://en.cppreference.com/w/cpp/string/basic_string/find_first_not_of
|
|
465
465
|
*/
|
|
466
|
-
template <typename
|
|
466
|
+
template <typename haystack_type_, typename needles_type_ = haystack_type_>
|
|
467
467
|
struct matcher_find_first_not_of {
|
|
468
|
-
using size_type = typename
|
|
469
|
-
|
|
468
|
+
using size_type = typename haystack_type_::size_type;
|
|
469
|
+
needles_type_ needles_;
|
|
470
470
|
constexpr size_type needle_length() const noexcept { return 1; }
|
|
471
471
|
constexpr size_type skip_length() const noexcept { return 1; }
|
|
472
|
-
size_type operator()(
|
|
472
|
+
size_type operator()(haystack_type_ haystack) const noexcept { return haystack.find_first_not_of(needles_); }
|
|
473
473
|
};
|
|
474
474
|
|
|
475
475
|
/**
|
|
476
476
|
* @brief Zero-cost wrapper around the `.find_last_not_of` member function of string-like classes.
|
|
477
477
|
* @see https://en.cppreference.com/w/cpp/string/basic_string/find_last_not_of
|
|
478
478
|
*/
|
|
479
|
-
template <typename
|
|
479
|
+
template <typename haystack_type_, typename needles_type_ = haystack_type_>
|
|
480
480
|
struct matcher_find_last_not_of {
|
|
481
|
-
using size_type = typename
|
|
482
|
-
|
|
481
|
+
using size_type = typename haystack_type_::size_type;
|
|
482
|
+
needles_type_ needles_;
|
|
483
483
|
constexpr size_type needle_length() const noexcept { return 1; }
|
|
484
484
|
constexpr size_type skip_length() const noexcept { return 1; }
|
|
485
|
-
size_type operator()(
|
|
485
|
+
size_type operator()(haystack_type_ haystack) const noexcept { return haystack.find_last_not_of(needles_); }
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* @brief Helper to detect if a type has a nested `::string_view` typedef.
|
|
490
|
+
* Uses SFINAE with no STL dependencies for `std::enabled_if` or `std::void_t`.
|
|
491
|
+
*/
|
|
492
|
+
template <typename type_>
|
|
493
|
+
struct has_string_view_member_ {
|
|
494
|
+
private:
|
|
495
|
+
template <typename candidate_>
|
|
496
|
+
static char test_(typename candidate_::string_view *);
|
|
497
|
+
template <typename candidate_>
|
|
498
|
+
static int test_(...);
|
|
499
|
+
|
|
500
|
+
public:
|
|
501
|
+
static constexpr bool value = sizeof(test_<type_>(0)) == sizeof(char);
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* @brief Helper to extract the appropriate view type for a string-like type.
|
|
506
|
+
* For StringZilla types, uses the nested ::string_view typedef.
|
|
507
|
+
* For STL types (like std::string_view), uses the type itself.
|
|
508
|
+
*/
|
|
509
|
+
template <typename string_type_, bool has_nested_view_ = has_string_view_member_<string_type_>::value>
|
|
510
|
+
struct string_view_for {
|
|
511
|
+
// Default: use the type itself (for STL types)
|
|
512
|
+
using type = string_type_;
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
// Specialization for types with nested ::string_view
|
|
516
|
+
template <typename string_type_>
|
|
517
|
+
struct string_view_for<string_type_, true> {
|
|
518
|
+
// For StringZilla types with nested ::string_view
|
|
519
|
+
using type = typename string_type_::string_view;
|
|
486
520
|
};
|
|
487
521
|
|
|
488
522
|
/**
|
|
489
523
|
* @brief A range of string slices representing the matches of a substring search.
|
|
524
|
+
*
|
|
525
|
+
* @note Lifetime semantics: Stores forwarded objects (including owning strings) to maintain lifetime.
|
|
526
|
+
* Iterators receive lightweight views only, ensuring safe iteration without ownership concerns.
|
|
527
|
+
* @note For-loop optimized: Iterators are lightweight views with minimal register pressure, ideal for
|
|
528
|
+
* high-performance applications where cache efficiency and register allocation matter.
|
|
529
|
+
* @note Sentinel support: Supports sentinel-based iteration via `operator==(end_sentinel_type)` for
|
|
530
|
+
* efficient termination without constructing full end iterators.
|
|
490
531
|
* @note Compatible with C++23 ranges, C++11 string views, and of course, StringZilla.
|
|
491
532
|
* @see Similar to a pair of `boost::algorithm::find_iterator`.
|
|
492
533
|
*/
|
|
@@ -495,6 +536,7 @@ class range_matches {
|
|
|
495
536
|
public:
|
|
496
537
|
using string_type = string_type_;
|
|
497
538
|
using matcher_type = matcher_type_;
|
|
539
|
+
using string_view_type = typename string_view_for<string_type>::type;
|
|
498
540
|
|
|
499
541
|
private:
|
|
500
542
|
matcher_type matcher_;
|
|
@@ -503,24 +545,24 @@ class range_matches {
|
|
|
503
545
|
public:
|
|
504
546
|
using size_type = std::size_t;
|
|
505
547
|
using difference_type = std::ptrdiff_t;
|
|
506
|
-
using value_type =
|
|
507
|
-
using pointer =
|
|
508
|
-
using reference =
|
|
548
|
+
using value_type = string_view_type;
|
|
549
|
+
using pointer = string_view_type; // Needed for compatibility with STL container constructors.
|
|
550
|
+
using reference = string_view_type; // Needed for compatibility with STL container constructors.
|
|
509
551
|
|
|
510
552
|
range_matches(string_type haystack, matcher_type needle) noexcept : matcher_(needle), haystack_(haystack) {}
|
|
511
553
|
|
|
512
554
|
class iterator {
|
|
513
555
|
matcher_type matcher_;
|
|
514
|
-
|
|
556
|
+
string_view_type remaining_;
|
|
515
557
|
|
|
516
558
|
public:
|
|
517
559
|
using iterator_category = std::forward_iterator_tag;
|
|
518
560
|
using difference_type = std::ptrdiff_t;
|
|
519
|
-
using value_type =
|
|
520
|
-
using pointer =
|
|
521
|
-
using reference =
|
|
561
|
+
using value_type = string_view_type;
|
|
562
|
+
using pointer = string_view_type; // Needed for compatibility with STL container constructors.
|
|
563
|
+
using reference = string_view_type; // Needed for compatibility with STL container constructors.
|
|
522
564
|
|
|
523
|
-
iterator(
|
|
565
|
+
iterator(string_view_type haystack, matcher_type matcher) noexcept : matcher_(matcher), remaining_(haystack) {
|
|
524
566
|
auto position = matcher_(remaining_);
|
|
525
567
|
remaining_.remove_prefix(position != string_type::npos ? position : remaining_.size());
|
|
526
568
|
}
|
|
@@ -548,8 +590,8 @@ class range_matches {
|
|
|
548
590
|
bool operator==(end_sentinel_type) const noexcept { return remaining_.empty(); }
|
|
549
591
|
};
|
|
550
592
|
|
|
551
|
-
iterator begin() const noexcept { return {haystack_, matcher_}; }
|
|
552
|
-
iterator end() const noexcept { return {
|
|
593
|
+
iterator begin() const noexcept { return {string_view_type(haystack_), matcher_}; }
|
|
594
|
+
iterator end() const noexcept { return {string_view_type(haystack_.data() + haystack_.size(), 0ull), matcher_}; }
|
|
553
595
|
size_type size() const noexcept { return static_cast<size_type>(ssize()); }
|
|
554
596
|
difference_type ssize() const noexcept { return std::distance(begin(), end()); }
|
|
555
597
|
bool empty() const noexcept { return begin() == end_sentinel_type {}; }
|
|
@@ -570,6 +612,13 @@ class range_matches {
|
|
|
570
612
|
|
|
571
613
|
/**
|
|
572
614
|
* @brief A range of string slices representing the matches of a @b reverse-order substring search.
|
|
615
|
+
*
|
|
616
|
+
* @note Lifetime semantics: Stores forwarded objects (including owning strings) to maintain lifetime.
|
|
617
|
+
* Iterators receive lightweight views only, ensuring safe iteration without ownership concerns.
|
|
618
|
+
* @note For-loop optimized: Iterators are lightweight views with minimal register pressure, ideal for
|
|
619
|
+
* high-performance applications where cache efficiency and register allocation matter.
|
|
620
|
+
* @note Sentinel support: Supports sentinel-based iteration via `operator==(end_sentinel_type)` for
|
|
621
|
+
* efficient termination without constructing full end iterators.
|
|
573
622
|
* @note Compatible with C++23 ranges, C++11 string views, and of course, StringZilla.
|
|
574
623
|
* @see Similar to a pair of `boost::algorithm::find_iterator`.
|
|
575
624
|
*/
|
|
@@ -578,12 +627,13 @@ class range_rmatches {
|
|
|
578
627
|
public:
|
|
579
628
|
using string_type = string_type_;
|
|
580
629
|
using matcher_type = matcher_type_;
|
|
630
|
+
using string_view_type = typename string_view_for<string_type>::type;
|
|
581
631
|
|
|
582
632
|
using size_type = std::size_t;
|
|
583
633
|
using difference_type = std::ptrdiff_t;
|
|
584
|
-
using value_type =
|
|
585
|
-
using pointer =
|
|
586
|
-
using reference =
|
|
634
|
+
using value_type = string_view_type;
|
|
635
|
+
using pointer = string_view_type; // Needed for compatibility with STL container constructors.
|
|
636
|
+
using reference = string_view_type; // Needed for compatibility with STL container constructors.
|
|
587
637
|
|
|
588
638
|
private:
|
|
589
639
|
matcher_type matcher_;
|
|
@@ -594,16 +644,16 @@ class range_rmatches {
|
|
|
594
644
|
|
|
595
645
|
class iterator {
|
|
596
646
|
matcher_type matcher_;
|
|
597
|
-
|
|
647
|
+
string_view_type remaining_;
|
|
598
648
|
|
|
599
649
|
public:
|
|
600
650
|
using iterator_category = std::forward_iterator_tag;
|
|
601
651
|
using difference_type = std::ptrdiff_t;
|
|
602
|
-
using value_type =
|
|
603
|
-
using pointer =
|
|
604
|
-
using reference =
|
|
652
|
+
using value_type = string_view_type;
|
|
653
|
+
using pointer = string_view_type; // Needed for compatibility with STL container constructors.
|
|
654
|
+
using reference = string_view_type; // Needed for compatibility with STL container constructors.
|
|
605
655
|
|
|
606
|
-
iterator(
|
|
656
|
+
iterator(string_view_type haystack, matcher_type matcher) noexcept : matcher_(matcher), remaining_(haystack) {
|
|
607
657
|
auto position = matcher_(remaining_);
|
|
608
658
|
remaining_.remove_suffix( //
|
|
609
659
|
position != string_type::npos //
|
|
@@ -644,8 +694,8 @@ class range_rmatches {
|
|
|
644
694
|
bool operator==(end_sentinel_type) const noexcept { return remaining_.empty(); }
|
|
645
695
|
};
|
|
646
696
|
|
|
647
|
-
iterator begin() const noexcept { return {haystack_, matcher_}; }
|
|
648
|
-
iterator end() const noexcept { return {
|
|
697
|
+
iterator begin() const noexcept { return {string_view_type(haystack_), matcher_}; }
|
|
698
|
+
iterator end() const noexcept { return {string_view_type(haystack_.data(), 0ull), matcher_}; }
|
|
649
699
|
size_type size() const noexcept { return static_cast<size_type>(ssize()); }
|
|
650
700
|
difference_type ssize() const noexcept { return std::distance(begin(), end()); }
|
|
651
701
|
bool empty() const noexcept { return begin() == end_sentinel_type {}; }
|
|
@@ -666,6 +716,13 @@ class range_rmatches {
|
|
|
666
716
|
|
|
667
717
|
/**
|
|
668
718
|
* @brief A range of string slices for different splits of the data.
|
|
719
|
+
*
|
|
720
|
+
* @note Lifetime semantics: Stores forwarded objects (including owning strings) to maintain lifetime.
|
|
721
|
+
* Iterators receive lightweight views only, ensuring safe iteration without ownership concerns.
|
|
722
|
+
* @note For-loop optimized: Iterators are lightweight views with minimal register pressure, ideal for
|
|
723
|
+
* high-performance applications where cache efficiency and register allocation matter.
|
|
724
|
+
* @note Sentinel support: Supports sentinel-based iteration via `operator==(end_sentinel_type)` for
|
|
725
|
+
* efficient termination without constructing full end iterators.
|
|
669
726
|
* @note Compatible with C++23 ranges, C++11 string views, and of course, StringZilla.
|
|
670
727
|
* @see Similar to a pair of `boost::algorithm::split_iterator`.
|
|
671
728
|
*
|
|
@@ -678,12 +735,13 @@ class range_splits {
|
|
|
678
735
|
public:
|
|
679
736
|
using string_type = string_type_;
|
|
680
737
|
using matcher_type = matcher_type_;
|
|
738
|
+
using string_view_type = typename string_view_for<string_type>::type;
|
|
681
739
|
|
|
682
740
|
using size_type = std::size_t;
|
|
683
741
|
using difference_type = std::ptrdiff_t;
|
|
684
|
-
using value_type =
|
|
685
|
-
using pointer =
|
|
686
|
-
using reference =
|
|
742
|
+
using value_type = string_view_type;
|
|
743
|
+
using pointer = string_view_type; // Needed for compatibility with STL container constructors.
|
|
744
|
+
using reference = string_view_type; // Needed for compatibility with STL container constructors.
|
|
687
745
|
|
|
688
746
|
private:
|
|
689
747
|
matcher_type matcher_;
|
|
@@ -694,24 +752,24 @@ class range_splits {
|
|
|
694
752
|
|
|
695
753
|
class iterator {
|
|
696
754
|
matcher_type matcher_;
|
|
697
|
-
|
|
755
|
+
string_view_type remaining_;
|
|
698
756
|
std::size_t length_within_remaining_;
|
|
699
757
|
bool reached_tail_;
|
|
700
758
|
|
|
701
759
|
public:
|
|
702
760
|
using iterator_category = std::forward_iterator_tag;
|
|
703
761
|
using difference_type = std::ptrdiff_t;
|
|
704
|
-
using value_type =
|
|
705
|
-
using pointer =
|
|
706
|
-
using reference =
|
|
762
|
+
using value_type = string_view_type;
|
|
763
|
+
using pointer = string_view_type; // Needed for compatibility with STL container constructors.
|
|
764
|
+
using reference = string_view_type; // Needed for compatibility with STL container constructors.
|
|
707
765
|
|
|
708
|
-
iterator(
|
|
766
|
+
iterator(string_view_type haystack, matcher_type matcher) noexcept : matcher_(matcher), remaining_(haystack) {
|
|
709
767
|
auto position = matcher_(remaining_);
|
|
710
768
|
length_within_remaining_ = position != string_type::npos ? position : remaining_.size();
|
|
711
769
|
reached_tail_ = false;
|
|
712
770
|
}
|
|
713
771
|
|
|
714
|
-
iterator(
|
|
772
|
+
iterator(string_view_type haystack, matcher_type matcher, end_sentinel_type) noexcept
|
|
715
773
|
: matcher_(matcher), remaining_(haystack), length_within_remaining_(0), reached_tail_(true) {}
|
|
716
774
|
|
|
717
775
|
pointer operator->() const noexcept = delete;
|
|
@@ -743,8 +801,8 @@ class range_splits {
|
|
|
743
801
|
bool is_last() const noexcept { return remaining_.size() == length_within_remaining_; }
|
|
744
802
|
};
|
|
745
803
|
|
|
746
|
-
iterator begin() const noexcept { return {haystack_, matcher_}; }
|
|
747
|
-
iterator end() const noexcept { return {
|
|
804
|
+
iterator begin() const noexcept { return {string_view_type(haystack_), matcher_}; }
|
|
805
|
+
iterator end() const noexcept { return {string_view_type(haystack_.end(), 0), matcher_, end_sentinel_type {}}; }
|
|
748
806
|
size_type size() const noexcept { return static_cast<size_type>(ssize()); }
|
|
749
807
|
difference_type ssize() const noexcept { return std::distance(begin(), end()); }
|
|
750
808
|
constexpr bool empty() const noexcept { return false; }
|
|
@@ -765,6 +823,13 @@ class range_splits {
|
|
|
765
823
|
|
|
766
824
|
/**
|
|
767
825
|
* @brief A range of string slices for different splits of the data in @b reverse-order.
|
|
826
|
+
*
|
|
827
|
+
* @note Lifetime semantics: Stores forwarded objects (including owning strings) to maintain lifetime.
|
|
828
|
+
* Iterators receive lightweight views only, ensuring safe iteration without ownership concerns.
|
|
829
|
+
* @note For-loop optimized: Iterators are lightweight views with minimal register pressure, ideal for
|
|
830
|
+
* high-performance applications where cache efficiency and register allocation matter.
|
|
831
|
+
* @note Sentinel support: Supports sentinel-based iteration via `operator==(end_sentinel_type)` for
|
|
832
|
+
* efficient termination without constructing full end iterators.
|
|
768
833
|
* @note Compatible with C++23 ranges, C++11 string views, and of course, StringZilla.
|
|
769
834
|
* @see Similar to a pair of `boost::algorithm::split_iterator`.
|
|
770
835
|
*
|
|
@@ -777,12 +842,13 @@ class range_rsplits {
|
|
|
777
842
|
public:
|
|
778
843
|
using string_type = string_type_;
|
|
779
844
|
using matcher_type = matcher_type_;
|
|
845
|
+
using string_view_type = typename string_view_for<string_type>::type;
|
|
780
846
|
|
|
781
847
|
using size_type = std::size_t;
|
|
782
848
|
using difference_type = std::ptrdiff_t;
|
|
783
|
-
using value_type =
|
|
784
|
-
using pointer =
|
|
785
|
-
using reference =
|
|
849
|
+
using value_type = string_view_type;
|
|
850
|
+
using pointer = string_view_type; // Needed for compatibility with STL container constructors.
|
|
851
|
+
using reference = string_view_type; // Needed for compatibility with STL container constructors.
|
|
786
852
|
|
|
787
853
|
private:
|
|
788
854
|
matcher_type matcher_;
|
|
@@ -793,18 +859,18 @@ class range_rsplits {
|
|
|
793
859
|
|
|
794
860
|
class iterator {
|
|
795
861
|
matcher_type matcher_;
|
|
796
|
-
|
|
862
|
+
string_view_type remaining_;
|
|
797
863
|
std::size_t length_within_remaining_;
|
|
798
864
|
bool reached_tail_;
|
|
799
865
|
|
|
800
866
|
public:
|
|
801
867
|
using iterator_category = std::forward_iterator_tag;
|
|
802
868
|
using difference_type = std::ptrdiff_t;
|
|
803
|
-
using value_type =
|
|
804
|
-
using pointer =
|
|
805
|
-
using reference =
|
|
869
|
+
using value_type = string_view_type;
|
|
870
|
+
using pointer = string_view_type; // Needed for compatibility with STL container constructors.
|
|
871
|
+
using reference = string_view_type; // Needed for compatibility with STL container constructors.
|
|
806
872
|
|
|
807
|
-
iterator(
|
|
873
|
+
iterator(string_view_type haystack, matcher_type matcher) noexcept : matcher_(matcher), remaining_(haystack) {
|
|
808
874
|
auto position = matcher_(remaining_);
|
|
809
875
|
length_within_remaining_ = position != string_type::npos
|
|
810
876
|
? remaining_.size() - position - matcher_.needle_length()
|
|
@@ -812,7 +878,7 @@ class range_rsplits {
|
|
|
812
878
|
reached_tail_ = false;
|
|
813
879
|
}
|
|
814
880
|
|
|
815
|
-
iterator(
|
|
881
|
+
iterator(string_view_type haystack, matcher_type matcher, end_sentinel_type) noexcept
|
|
816
882
|
: matcher_(matcher), remaining_(haystack), length_within_remaining_(0), reached_tail_(true) {}
|
|
817
883
|
|
|
818
884
|
pointer operator->() const noexcept = delete;
|
|
@@ -848,8 +914,8 @@ class range_rsplits {
|
|
|
848
914
|
bool is_last() const noexcept { return remaining_.size() == length_within_remaining_; }
|
|
849
915
|
};
|
|
850
916
|
|
|
851
|
-
iterator begin() const noexcept { return {haystack_, matcher_}; }
|
|
852
|
-
iterator end() const noexcept { return {
|
|
917
|
+
iterator begin() const noexcept { return {string_view_type(haystack_), matcher_}; }
|
|
918
|
+
iterator end() const noexcept { return {string_view_type(haystack_.data(), 0ull), matcher_, end_sentinel_type {}}; }
|
|
853
919
|
size_type size() const noexcept { return static_cast<size_type>(ssize()); }
|
|
854
920
|
difference_type ssize() const noexcept { return std::distance(begin(), end()); }
|
|
855
921
|
constexpr bool empty() const noexcept { return false; }
|
|
@@ -870,135 +936,141 @@ class range_rsplits {
|
|
|
870
936
|
|
|
871
937
|
/**
|
|
872
938
|
* @brief Find all potentially @b overlapping inclusions of a needle substring.
|
|
873
|
-
* @tparam
|
|
939
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
874
940
|
*/
|
|
875
|
-
template <typename
|
|
876
|
-
range_matches<
|
|
877
|
-
|
|
941
|
+
template <typename string_type_>
|
|
942
|
+
range_matches<string_type_, matcher_find<string_type_, include_overlaps_type>> find_all(
|
|
943
|
+
string_type_ const &h, string_type_ const &n, include_overlaps_type = {}) noexcept {
|
|
878
944
|
return {h, n};
|
|
879
945
|
}
|
|
880
946
|
|
|
881
947
|
/**
|
|
882
948
|
* @brief Find all potentially @b overlapping inclusions of a needle substring in @b reverse order.
|
|
883
|
-
* @tparam
|
|
949
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
884
950
|
*/
|
|
885
|
-
template <typename
|
|
886
|
-
range_rmatches<
|
|
887
|
-
|
|
951
|
+
template <typename string_type_>
|
|
952
|
+
range_rmatches<string_type_, matcher_rfind<string_type_, include_overlaps_type>> rfind_all(
|
|
953
|
+
string_type_ const &h, string_type_ const &n, include_overlaps_type = {}) noexcept {
|
|
888
954
|
return {h, n};
|
|
889
955
|
}
|
|
890
956
|
|
|
891
957
|
/**
|
|
892
958
|
* @brief Find all @b non-overlapping inclusions of a needle substring.
|
|
893
|
-
* @tparam
|
|
959
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
894
960
|
*/
|
|
895
|
-
template <typename
|
|
896
|
-
range_matches<
|
|
897
|
-
|
|
961
|
+
template <typename string_type_>
|
|
962
|
+
range_matches<string_type_, matcher_find<string_type_, exclude_overlaps_type>> find_all(
|
|
963
|
+
string_type_ const &h, string_type_ const &n, exclude_overlaps_type) noexcept {
|
|
898
964
|
return {h, n};
|
|
899
965
|
}
|
|
900
966
|
|
|
901
967
|
/**
|
|
902
968
|
* @brief Find all @b non-overlapping inclusions of a needle substring in @b reverse order.
|
|
903
|
-
* @tparam
|
|
969
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
904
970
|
*/
|
|
905
|
-
template <typename
|
|
906
|
-
range_rmatches<
|
|
907
|
-
|
|
971
|
+
template <typename string_type_>
|
|
972
|
+
range_rmatches<string_type_, matcher_rfind<string_type_, exclude_overlaps_type>> rfind_all(
|
|
973
|
+
string_type_ const &h, string_type_ const &n, exclude_overlaps_type) noexcept {
|
|
908
974
|
return {h, n};
|
|
909
975
|
}
|
|
910
976
|
|
|
911
977
|
/**
|
|
912
978
|
* @brief Find all inclusions of characters from the second string.
|
|
913
|
-
* @tparam
|
|
979
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
914
980
|
*/
|
|
915
|
-
template <typename
|
|
916
|
-
range_matches<
|
|
981
|
+
template <typename string_type_>
|
|
982
|
+
range_matches<string_type_, matcher_find_first_of<string_type_>> find_all_characters(string_type_ const &h,
|
|
983
|
+
string_type_ const &n) noexcept {
|
|
917
984
|
return {h, n};
|
|
918
985
|
}
|
|
919
986
|
|
|
920
987
|
/**
|
|
921
988
|
* @brief Find all inclusions of characters from the second string in @b reverse order.
|
|
922
|
-
* @tparam
|
|
989
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
923
990
|
*/
|
|
924
|
-
template <typename
|
|
925
|
-
range_rmatches<
|
|
991
|
+
template <typename string_type_>
|
|
992
|
+
range_rmatches<string_type_, matcher_find_last_of<string_type_>> rfind_all_characters(string_type_ const &h,
|
|
993
|
+
string_type_ const &n) noexcept {
|
|
926
994
|
return {h, n};
|
|
927
995
|
}
|
|
928
996
|
|
|
929
997
|
/**
|
|
930
998
|
* @brief Find all characters except the ones in the second string.
|
|
931
|
-
* @tparam
|
|
999
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
932
1000
|
*/
|
|
933
|
-
template <typename
|
|
934
|
-
range_matches<
|
|
935
|
-
|
|
1001
|
+
template <typename string_type_>
|
|
1002
|
+
range_matches<string_type_, matcher_find_first_not_of<string_type_>> find_all_other_characters(
|
|
1003
|
+
string_type_ const &h, string_type_ const &n) noexcept {
|
|
936
1004
|
return {h, n};
|
|
937
1005
|
}
|
|
938
1006
|
|
|
939
1007
|
/**
|
|
940
1008
|
* @brief Find all characters except the ones in the second string in @b reverse order.
|
|
941
|
-
* @tparam
|
|
1009
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
942
1010
|
*/
|
|
943
|
-
template <typename
|
|
944
|
-
range_rmatches<
|
|
945
|
-
|
|
1011
|
+
template <typename string_type_>
|
|
1012
|
+
range_rmatches<string_type_, matcher_find_last_not_of<string_type_>> rfind_all_other_characters(
|
|
1013
|
+
string_type_ const &h, string_type_ const &n) noexcept {
|
|
946
1014
|
return {h, n};
|
|
947
1015
|
}
|
|
948
1016
|
|
|
949
1017
|
/**
|
|
950
1018
|
* @brief Splits a string around every @b non-overlapping inclusion of the second string.
|
|
951
|
-
* @tparam
|
|
1019
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
952
1020
|
*/
|
|
953
|
-
template <typename
|
|
954
|
-
range_splits<
|
|
1021
|
+
template <typename string_type_>
|
|
1022
|
+
range_splits<string_type_, matcher_find<string_type_, exclude_overlaps_type>> split(string_type_ const &h,
|
|
1023
|
+
string_type_ const &n) noexcept {
|
|
955
1024
|
return {h, n};
|
|
956
1025
|
}
|
|
957
1026
|
|
|
958
1027
|
/**
|
|
959
1028
|
* @brief Splits a string around every @b non-overlapping inclusion of the second string in @b reverse order.
|
|
960
|
-
* @tparam
|
|
1029
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
961
1030
|
*/
|
|
962
|
-
template <typename
|
|
963
|
-
range_rsplits<
|
|
1031
|
+
template <typename string_type_>
|
|
1032
|
+
range_rsplits<string_type_, matcher_rfind<string_type_, exclude_overlaps_type>> rsplit(string_type_ const &h,
|
|
1033
|
+
string_type_ const &n) noexcept {
|
|
964
1034
|
return {h, n};
|
|
965
1035
|
}
|
|
966
1036
|
|
|
967
1037
|
/**
|
|
968
1038
|
* @brief Splits a string around every character from the second string.
|
|
969
|
-
* @tparam
|
|
1039
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
970
1040
|
*/
|
|
971
|
-
template <typename
|
|
972
|
-
range_splits<
|
|
1041
|
+
template <typename string_type_>
|
|
1042
|
+
range_splits<string_type_, matcher_find_first_of<string_type_>> split_characters(string_type_ const &h,
|
|
1043
|
+
string_type_ const &n) noexcept {
|
|
973
1044
|
return {h, n};
|
|
974
1045
|
}
|
|
975
1046
|
|
|
976
1047
|
/**
|
|
977
1048
|
* @brief Splits a string around every character from the second string in @b reverse order.
|
|
978
|
-
* @tparam
|
|
1049
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
979
1050
|
*/
|
|
980
|
-
template <typename
|
|
981
|
-
range_rsplits<
|
|
1051
|
+
template <typename string_type_>
|
|
1052
|
+
range_rsplits<string_type_, matcher_find_last_of<string_type_>> rsplit_characters(string_type_ const &h,
|
|
1053
|
+
string_type_ const &n) noexcept {
|
|
982
1054
|
return {h, n};
|
|
983
1055
|
}
|
|
984
1056
|
|
|
985
1057
|
/**
|
|
986
1058
|
* @brief Splits a string around every character except the ones from the second string.
|
|
987
|
-
* @tparam
|
|
1059
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
988
1060
|
*/
|
|
989
|
-
template <typename
|
|
990
|
-
range_splits<
|
|
991
|
-
|
|
1061
|
+
template <typename string_type_>
|
|
1062
|
+
range_splits<string_type_, matcher_find_first_not_of<string_type_>> split_other_characters(
|
|
1063
|
+
string_type_ const &h, string_type_ const &n) noexcept {
|
|
992
1064
|
return {h, n};
|
|
993
1065
|
}
|
|
994
1066
|
|
|
995
1067
|
/**
|
|
996
1068
|
* @brief Splits a string around every character except the ones from the second string in @b reverse order.
|
|
997
|
-
* @tparam
|
|
1069
|
+
* @tparam string_type_ A string-like type, ideally a view, like StringZilla or STL `string_view`.
|
|
998
1070
|
*/
|
|
999
|
-
template <typename
|
|
1000
|
-
range_rsplits<
|
|
1001
|
-
|
|
1071
|
+
template <typename string_type_>
|
|
1072
|
+
range_rsplits<string_type_, matcher_find_last_not_of<string_type_>> rsplit_other_characters(
|
|
1073
|
+
string_type_ const &h, string_type_ const &n) noexcept {
|
|
1002
1074
|
return {h, n};
|
|
1003
1075
|
}
|
|
1004
1076
|
|
|
@@ -1138,17 +1210,17 @@ class reversed_iterator_for {
|
|
|
1138
1210
|
* @see https://en.wikipedia.org/wiki/Expression_templates
|
|
1139
1211
|
* @sa `concatenate` function for usage examples.
|
|
1140
1212
|
*/
|
|
1141
|
-
template <typename
|
|
1213
|
+
template <typename first_type_, typename second_type_>
|
|
1142
1214
|
struct concatenation {
|
|
1143
1215
|
|
|
1144
|
-
using value_type = typename
|
|
1216
|
+
using value_type = typename first_type_::value_type;
|
|
1145
1217
|
using pointer = value_type *;
|
|
1146
1218
|
using const_pointer = value_type const *;
|
|
1147
|
-
using size_type = typename
|
|
1148
|
-
using difference_type = typename
|
|
1219
|
+
using size_type = typename first_type_::size_type;
|
|
1220
|
+
using difference_type = typename first_type_::difference_type;
|
|
1149
1221
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1222
|
+
first_type_ first;
|
|
1223
|
+
second_type_ second;
|
|
1152
1224
|
|
|
1153
1225
|
std::size_t size() const noexcept { return first.size() + second.size(); }
|
|
1154
1226
|
std::size_t length() const noexcept { return first.size() + second.size(); }
|
|
@@ -1168,7 +1240,7 @@ struct concatenation {
|
|
|
1168
1240
|
}
|
|
1169
1241
|
|
|
1170
1242
|
template <typename last_type>
|
|
1171
|
-
concatenation<concatenation<
|
|
1243
|
+
concatenation<concatenation<first_type_, second_type_>, last_type> operator|(last_type &&last) const {
|
|
1172
1244
|
return {*this, last};
|
|
1173
1245
|
}
|
|
1174
1246
|
};
|
|
@@ -1268,9 +1340,9 @@ class basic_string_slice {
|
|
|
1268
1340
|
* @brief Formatted output function for compatibility with STL's `std::basic_ostream`.
|
|
1269
1341
|
* @throw `std::ios_base::failure` if an exception occurred during output.
|
|
1270
1342
|
*/
|
|
1271
|
-
template <typename
|
|
1272
|
-
friend std::basic_ostream<value_type,
|
|
1273
|
-
|
|
1343
|
+
template <typename stream_traits_>
|
|
1344
|
+
friend std::basic_ostream<value_type, stream_traits_> &operator<<(
|
|
1345
|
+
std::basic_ostream<value_type, stream_traits_> &os, string_slice const &str) noexcept(false) {
|
|
1274
1346
|
return os.write(str.data(), str.size());
|
|
1275
1347
|
}
|
|
1276
1348
|
|
|
@@ -2016,8 +2088,8 @@ class basic_string {
|
|
|
2016
2088
|
*/
|
|
2017
2089
|
static_assert(std::is_empty<allocator_type_>::value, "We currently only support stateless allocators");
|
|
2018
2090
|
|
|
2019
|
-
template <typename
|
|
2020
|
-
static status_t _with_alloc(
|
|
2091
|
+
template <typename allocator_callback_>
|
|
2092
|
+
static status_t _with_alloc(allocator_callback_ &&callback) noexcept {
|
|
2021
2093
|
return ashvardanian::stringzilla::_with_alloc<allocator_type_>(callback);
|
|
2022
2094
|
}
|
|
2023
2095
|
|
|
@@ -2185,9 +2257,9 @@ class basic_string {
|
|
|
2185
2257
|
* @brief Formatted output function for compatibility with STL's `std::basic_ostream`.
|
|
2186
2258
|
* @throw `std::ios_base::failure` if an exception occurred during output.
|
|
2187
2259
|
*/
|
|
2188
|
-
template <typename
|
|
2189
|
-
friend std::basic_ostream<value_type,
|
|
2190
|
-
|
|
2260
|
+
template <typename stream_traits_>
|
|
2261
|
+
friend std::basic_ostream<value_type, stream_traits_> &operator<<(
|
|
2262
|
+
std::basic_ostream<value_type, stream_traits_> &os, basic_string const &str) noexcept(false) {
|
|
2191
2263
|
return os.write(str.data(), str.size());
|
|
2192
2264
|
}
|
|
2193
2265
|
|
|
@@ -2199,8 +2271,8 @@ class basic_string {
|
|
|
2199
2271
|
|
|
2200
2272
|
#endif
|
|
2201
2273
|
|
|
2202
|
-
template <typename
|
|
2203
|
-
explicit basic_string(concatenation<
|
|
2274
|
+
template <typename first_type_, typename second_type_>
|
|
2275
|
+
explicit basic_string(concatenation<first_type_, second_type_> const &expression) noexcept(false) {
|
|
2204
2276
|
raise(_with_alloc([&](sz_alloc_type &alloc) {
|
|
2205
2277
|
sz_ptr_t ptr = sz_string_init_length(&string_, expression.length(), &alloc);
|
|
2206
2278
|
if (!ptr) return sz_bad_alloc_k;
|
|
@@ -2209,8 +2281,8 @@ class basic_string {
|
|
|
2209
2281
|
}));
|
|
2210
2282
|
}
|
|
2211
2283
|
|
|
2212
|
-
template <typename
|
|
2213
|
-
basic_string &operator=(concatenation<
|
|
2284
|
+
template <typename first_type_, typename second_type_>
|
|
2285
|
+
basic_string &operator=(concatenation<first_type_, second_type_> const &expression) noexcept(false) {
|
|
2214
2286
|
if (!try_assign(expression)) throw std::bad_alloc();
|
|
2215
2287
|
return *this;
|
|
2216
2288
|
}
|
|
@@ -2772,8 +2844,8 @@ class basic_string {
|
|
|
2772
2844
|
* @param[in] other The concatenation object representing the sequence to assign.
|
|
2773
2845
|
* @return `true` if the assignment was successful, `false` otherwise.
|
|
2774
2846
|
*/
|
|
2775
|
-
template <typename
|
|
2776
|
-
bool try_assign(concatenation<
|
|
2847
|
+
template <typename first_type_, typename second_type_>
|
|
2848
|
+
bool try_assign(concatenation<first_type_, second_type_> const &other) noexcept;
|
|
2777
2849
|
|
|
2778
2850
|
/**
|
|
2779
2851
|
* @brief Attempts to add a single character to the end of the string.
|
|
@@ -3722,8 +3794,8 @@ bool basic_string<char_type_, allocator_>::try_replace_all_(pattern_type pattern
|
|
|
3722
3794
|
}
|
|
3723
3795
|
|
|
3724
3796
|
template <typename char_type_, typename allocator_>
|
|
3725
|
-
template <typename
|
|
3726
|
-
bool basic_string<char_type_, allocator_>::try_assign(concatenation<
|
|
3797
|
+
template <typename first_type_, typename second_type_>
|
|
3798
|
+
bool basic_string<char_type_, allocator_>::try_assign(concatenation<first_type_, second_type_> const &other) noexcept {
|
|
3727
3799
|
// We can't just assign the other string state, as its start address may be somewhere else on the stack.
|
|
3728
3800
|
sz_ptr_t string_start;
|
|
3729
3801
|
sz_size_t string_length;
|
|
@@ -3809,25 +3881,25 @@ struct hash {
|
|
|
3809
3881
|
};
|
|
3810
3882
|
|
|
3811
3883
|
/** @brief SFINAE-type used to infer the resulting type of concatenating multiple string together. */
|
|
3812
|
-
template <typename...
|
|
3884
|
+
template <typename... args_types_>
|
|
3813
3885
|
struct concatenation_result {};
|
|
3814
3886
|
|
|
3815
|
-
template <typename
|
|
3816
|
-
struct concatenation_result<
|
|
3817
|
-
using type = concatenation<
|
|
3887
|
+
template <typename first_type_, typename second_type_>
|
|
3888
|
+
struct concatenation_result<first_type_, second_type_> {
|
|
3889
|
+
using type = concatenation<first_type_, second_type_>;
|
|
3818
3890
|
};
|
|
3819
3891
|
|
|
3820
|
-
template <typename
|
|
3821
|
-
struct concatenation_result<
|
|
3822
|
-
using type = concatenation<
|
|
3892
|
+
template <typename first_type_, typename... following_types_>
|
|
3893
|
+
struct concatenation_result<first_type_, following_types_...> {
|
|
3894
|
+
using type = concatenation<first_type_, typename concatenation_result<following_types_...>::type>;
|
|
3823
3895
|
};
|
|
3824
3896
|
|
|
3825
3897
|
/**
|
|
3826
3898
|
* @brief Concatenates two strings into a template expression.
|
|
3827
3899
|
* @sa `concatenation` class for more details.
|
|
3828
3900
|
*/
|
|
3829
|
-
template <typename
|
|
3830
|
-
concatenation<
|
|
3901
|
+
template <typename first_type_, typename second_type_>
|
|
3902
|
+
concatenation<first_type_, second_type_> concatenate(first_type_ &&first, second_type_ &&second) noexcept(false) {
|
|
3831
3903
|
return {first, second};
|
|
3832
3904
|
}
|
|
3833
3905
|
|
|
@@ -3835,9 +3907,9 @@ concatenation<first_type, second_type> concatenate(first_type &&first, second_ty
|
|
|
3835
3907
|
* @brief Concatenates two or more strings into a template expression.
|
|
3836
3908
|
* @sa `concatenation` class for more details.
|
|
3837
3909
|
*/
|
|
3838
|
-
template <typename
|
|
3839
|
-
typename concatenation_result<
|
|
3840
|
-
|
|
3910
|
+
template <typename first_type_, typename second_type_, typename... following_types_>
|
|
3911
|
+
typename concatenation_result<first_type_, second_type_, following_types_...>::type concatenate(
|
|
3912
|
+
first_type_ &&first, second_type_ &&second, following_types_ &&...following) noexcept(false) {
|
|
3841
3913
|
// Fold expression like the one below would result in faster compile times,
|
|
3842
3914
|
// but would incur the penalty of additional `if`-statements in every `append` call.
|
|
3843
3915
|
// Moreover, those are only supported in C++17 and later.
|
|
@@ -3846,10 +3918,10 @@ typename concatenation_result<first_type, second_type, following_types...>::type
|
|
|
3846
3918
|
// result.reserve(total_size);
|
|
3847
3919
|
// (result.append(strings), ...);
|
|
3848
3920
|
return ashvardanian::stringzilla::concatenate( //
|
|
3849
|
-
std::forward<
|
|
3921
|
+
std::forward<first_type_>(first),
|
|
3850
3922
|
ashvardanian::stringzilla::concatenate( //
|
|
3851
|
-
std::forward<
|
|
3852
|
-
std::forward<
|
|
3923
|
+
std::forward<second_type_>(second), //
|
|
3924
|
+
std::forward<following_types_>(following)...));
|
|
3853
3925
|
}
|
|
3854
3926
|
|
|
3855
3927
|
/**
|
|
@@ -541,8 +541,7 @@ typedef enum sz_status_t {
|
|
|
541
541
|
sz_invalid_utf8_k = -12,
|
|
542
542
|
/** For algorithms that take collections of unique elements, this status indicates presence of duplicates. */
|
|
543
543
|
sz_contains_duplicates_k = -13,
|
|
544
|
-
/** For algorithms dealing with large inputs, this error reports the need to upcast the logic to larger types.
|
|
545
|
-
*/
|
|
544
|
+
/** For algorithms dealing with large inputs, this error reports the need to upcast the logic to larger types. */
|
|
546
545
|
sz_overflow_risk_k = -14,
|
|
547
546
|
/** For algorithms with multi-stage pipelines indicates input/output size mismatch. */
|
|
548
547
|
sz_unexpected_dimensions_k = -15,
|
|
@@ -841,6 +840,7 @@ typedef union sz_u16_vec_t {
|
|
|
841
840
|
*/
|
|
842
841
|
typedef union sz_u32_vec_t {
|
|
843
842
|
sz_u32_t u32;
|
|
843
|
+
sz_i32_t i32;
|
|
844
844
|
sz_u16_t u16s[2];
|
|
845
845
|
sz_i16_t i16s[2];
|
|
846
846
|
sz_u8_t u8s[4];
|
|
@@ -853,6 +853,7 @@ typedef union sz_u32_vec_t {
|
|
|
853
853
|
*/
|
|
854
854
|
typedef union sz_u64_vec_t {
|
|
855
855
|
sz_u64_t u64;
|
|
856
|
+
sz_i64_t i64;
|
|
856
857
|
sz_u32_t u32s[2];
|
|
857
858
|
sz_i32_t i32s[2];
|
|
858
859
|
sz_u16_t u16s[4];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stringzillas-cuda
|
|
3
|
-
Version: 4.2.
|
|
3
|
+
Version: 4.2.3
|
|
4
4
|
Summary: Search, hash, sort, fingerprint, and fuzzy-match strings faster via SWAR, SIMD, and CUDA on Nvidia GPUs
|
|
5
5
|
Home-page: https://github.com/ashvardanian/StringZilla
|
|
6
6
|
Author: Ash Vardanian
|
|
@@ -30,7 +30,7 @@ Classifier: Topic :: Text Processing :: Indexing
|
|
|
30
30
|
Requires-Python: >=3.8
|
|
31
31
|
Description-Content-Type: text/markdown
|
|
32
32
|
License-File: LICENSE
|
|
33
|
-
Requires-Dist: stringzilla==4.2.
|
|
33
|
+
Requires-Dist: stringzilla==4.2.3
|
|
34
34
|
Dynamic: author
|
|
35
35
|
Dynamic: author-email
|
|
36
36
|
Dynamic: classifier
|
|
@@ -1134,10 +1134,10 @@ Similar to GCC, StringZilla is 32 bytes in size, and similar to Clang it can fit
|
|
|
1134
1134
|
Our layout might be preferential, if you want to avoid branches.
|
|
1135
1135
|
If you use a different compiler, you may want to check its SSO buffer size with a [simple Gist](https://gist.github.com/ashvardanian/c197f15732d9855c4e070797adf17b21).
|
|
1136
1136
|
|
|
1137
|
-
|
|
|
1138
|
-
|
|
|
1139
|
-
| `sizeof
|
|
1140
|
-
|
|
|
1137
|
+
| | `libstdc++` in GCC 13 | `libc++` in Clang 17 | StringZilla |
|
|
1138
|
+
| :-------------- | ---------------------: | -------------------: | ----------: |
|
|
1139
|
+
| String `sizeof` | 32 | 24 | 32 |
|
|
1140
|
+
| Inner Capacity | 15 | __22__ | __22__ |
|
|
1141
1141
|
|
|
1142
1142
|
This design has been since ported to many high-level programming languages.
|
|
1143
1143
|
Swift, for example, [can store 15 bytes](https://developer.apple.com/documentation/swift/substring/withutf8(_:)#discussion) in the `String` instance itself.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
stringzilla==4.2.3
|
stringzillas_cuda-4.2.2/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
4.2.2
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
stringzilla==4.2.2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/stringzillas_cuda.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{stringzillas_cuda-4.2.2 → stringzillas_cuda-4.2.3}/stringzillas_cuda.egg-info/top_level.txt
RENAMED
|
File without changes
|