bytes.odin 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474
  1. package bytes
  2. import "base:intrinsics"
  3. import "core:mem"
  4. import "core:simd"
  5. import "core:unicode"
  6. import "core:unicode/utf8"
  7. when ODIN_ARCH == .amd64 && intrinsics.has_target_feature("avx2") {
  8. @(private)
  9. SCANNER_INDICES_256 : simd.u8x32 : {
  10. 0, 1, 2, 3, 4, 5, 6, 7,
  11. 8, 9, 10, 11, 12, 13, 14, 15,
  12. 16, 17, 18, 19, 20, 21, 22, 23,
  13. 24, 25, 26, 27, 28, 29, 30, 31,
  14. }
  15. @(private)
  16. SCANNER_SENTINEL_MAX_256: simd.u8x32 : u8(0x00)
  17. @(private)
  18. SCANNER_SENTINEL_MIN_256: simd.u8x32 : u8(0xff)
  19. @(private)
  20. SIMD_REG_SIZE_256 :: 32
  21. }
  22. @(private)
  23. SCANNER_INDICES_128 : simd.u8x16 : {
  24. 0, 1, 2, 3, 4, 5, 6, 7,
  25. 8, 9, 10, 11, 12, 13, 14, 15,
  26. }
  27. @(private)
  28. SCANNER_SENTINEL_MAX_128: simd.u8x16 : u8(0x00)
  29. @(private)
  30. SCANNER_SENTINEL_MIN_128: simd.u8x16 : u8(0xff)
  31. @(private)
  32. SIMD_REG_SIZE_128 :: 16
  33. clone :: proc(s: []byte, allocator := context.allocator, loc := #caller_location) -> []byte {
  34. c := make([]byte, len(s), allocator, loc)
  35. copy(c, s)
  36. return c[:len(s)]
  37. }
  38. clone_safe :: proc(s: []byte, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: mem.Allocator_Error) {
  39. c := make([]byte, len(s), allocator, loc) or_return
  40. copy(c, s)
  41. return c[:len(s)], nil
  42. }
  43. ptr_from_slice :: ptr_from_bytes
  44. ptr_from_bytes :: proc(str: []byte) -> ^byte {
  45. d := transmute(mem.Raw_String)str
  46. return d.data
  47. }
  48. truncate_to_byte :: proc(str: []byte, b: byte) -> []byte {
  49. n := index_byte(str, b)
  50. if n < 0 {
  51. n = len(str)
  52. }
  53. return str[:n]
  54. }
  55. truncate_to_rune :: proc(str: []byte, r: rune) -> []byte {
  56. n := index_rune(str, r)
  57. if n < 0 {
  58. n = len(str)
  59. }
  60. return str[:n]
  61. }
  62. // Compares two strings, returning a value representing which one comes first lexiographically.
  63. // -1 for `a`; 1 for `b`, or 0 if they are equal.
  64. compare :: proc(lhs, rhs: []byte) -> int {
  65. return mem.compare(lhs, rhs)
  66. }
  67. contains_rune :: proc(s: []byte, r: rune) -> int {
  68. for c, offset in string(s) {
  69. if c == r {
  70. return offset
  71. }
  72. }
  73. return -1
  74. }
  75. contains :: proc(s, substr: []byte) -> bool {
  76. return index(s, substr) >= 0
  77. }
  78. contains_any :: proc(s, chars: []byte) -> bool {
  79. return index_any(s, chars) >= 0
  80. }
  81. rune_count :: proc(s: []byte) -> int {
  82. return utf8.rune_count(s)
  83. }
  84. equal :: proc(a, b: []byte) -> bool {
  85. return string(a) == string(b)
  86. }
  87. equal_fold :: proc(u, v: []byte) -> bool {
  88. s, t := string(u), string(v)
  89. loop: for s != "" && t != "" {
  90. sr, tr: rune
  91. if s[0] < utf8.RUNE_SELF {
  92. sr, s = rune(s[0]), s[1:]
  93. } else {
  94. r, size := utf8.decode_rune_in_string(s)
  95. sr, s = r, s[size:]
  96. }
  97. if t[0] < utf8.RUNE_SELF {
  98. tr, t = rune(t[0]), t[1:]
  99. } else {
  100. r, size := utf8.decode_rune_in_string(t)
  101. tr, t = r, t[size:]
  102. }
  103. if tr == sr { // easy case
  104. continue loop
  105. }
  106. if tr < sr {
  107. tr, sr = sr, tr
  108. }
  109. if tr < utf8.RUNE_SELF {
  110. switch sr {
  111. case 'A'..='Z':
  112. if tr == (sr+'a')-'A' {
  113. continue loop
  114. }
  115. }
  116. return false
  117. }
  118. // TODO(bill): Unicode folding
  119. return false
  120. }
  121. return s == t
  122. }
  123. has_prefix :: proc(s, prefix: []byte) -> bool {
  124. return len(s) >= len(prefix) && string(s[0:len(prefix)]) == string(prefix)
  125. }
  126. has_suffix :: proc(s, suffix: []byte) -> bool {
  127. return len(s) >= len(suffix) && string(s[len(s)-len(suffix):]) == string(suffix)
  128. }
  129. join :: proc(a: [][]byte, sep: []byte, allocator := context.allocator) -> []byte {
  130. if len(a) == 0 {
  131. return nil
  132. }
  133. n := len(sep) * (len(a) - 1)
  134. for s in a {
  135. n += len(s)
  136. }
  137. b := make([]byte, n, allocator)
  138. i := copy(b, a[0])
  139. for s in a[1:] {
  140. i += copy(b[i:], sep)
  141. i += copy(b[i:], s)
  142. }
  143. return b
  144. }
  145. join_safe :: proc(a: [][]byte, sep: []byte, allocator := context.allocator) -> (data: []byte, err: mem.Allocator_Error) {
  146. if len(a) == 0 {
  147. return nil, nil
  148. }
  149. n := len(sep) * (len(a) - 1)
  150. for s in a {
  151. n += len(s)
  152. }
  153. b := make([]byte, n, allocator) or_return
  154. i := copy(b, a[0])
  155. for s in a[1:] {
  156. i += copy(b[i:], sep)
  157. i += copy(b[i:], s)
  158. }
  159. return b, nil
  160. }
  161. concatenate :: proc(a: [][]byte, allocator := context.allocator) -> []byte {
  162. if len(a) == 0 {
  163. return nil
  164. }
  165. n := 0
  166. for s in a {
  167. n += len(s)
  168. }
  169. b := make([]byte, n, allocator)
  170. i := 0
  171. for s in a {
  172. i += copy(b[i:], s)
  173. }
  174. return b
  175. }
  176. concatenate_safe :: proc(a: [][]byte, allocator := context.allocator) -> (data: []byte, err: mem.Allocator_Error) {
  177. if len(a) == 0 {
  178. return nil, nil
  179. }
  180. n := 0
  181. for s in a {
  182. n += len(s)
  183. }
  184. b := make([]byte, n, allocator) or_return
  185. i := 0
  186. for s in a {
  187. i += copy(b[i:], s)
  188. }
  189. return b, nil
  190. }
  191. @private
  192. _split :: proc(s, sep: []byte, sep_save, n: int, allocator := context.allocator) -> [][]byte {
  193. s, n := s, n
  194. if n == 0 {
  195. return nil
  196. }
  197. if sep == nil {
  198. l := utf8.rune_count(s)
  199. if n < 0 || n > l {
  200. n = l
  201. }
  202. res := make([dynamic][]byte, n, allocator)
  203. for i := 0; i < n-1; i += 1 {
  204. _, w := utf8.decode_rune(s)
  205. res[i] = s[:w]
  206. s = s[w:]
  207. }
  208. if n > 0 {
  209. res[n-1] = s
  210. }
  211. return res[:]
  212. }
  213. if n < 0 {
  214. n = count(s, sep) + 1
  215. }
  216. res := make([dynamic][]byte, n, allocator)
  217. n -= 1
  218. i := 0
  219. for ; i < n; i += 1 {
  220. m := index(s, sep)
  221. if m < 0 {
  222. break
  223. }
  224. res[i] = s[:m+sep_save]
  225. s = s[m+len(sep):]
  226. }
  227. res[i] = s
  228. return res[:i+1]
  229. }
  230. split :: proc(s, sep: []byte, allocator := context.allocator) -> [][]byte {
  231. return _split(s, sep, 0, -1, allocator)
  232. }
  233. split_n :: proc(s, sep: []byte, n: int, allocator := context.allocator) -> [][]byte {
  234. return _split(s, sep, 0, n, allocator)
  235. }
  236. split_after :: proc(s, sep: []byte, allocator := context.allocator) -> [][]byte {
  237. return _split(s, sep, len(sep), -1, allocator)
  238. }
  239. split_after_n :: proc(s, sep: []byte, n: int, allocator := context.allocator) -> [][]byte {
  240. return _split(s, sep, len(sep), n, allocator)
  241. }
  242. @private
  243. _split_iterator :: proc(s: ^[]byte, sep: []byte, sep_save: int) -> (res: []byte, ok: bool) {
  244. if len(sep) == 0 {
  245. res = s[:]
  246. ok = true
  247. s^ = s[len(s):]
  248. return
  249. }
  250. m := index(s^, sep)
  251. if m < 0 {
  252. // not found
  253. res = s[:]
  254. ok = len(res) != 0
  255. s^ = s[len(s):]
  256. } else {
  257. res = s[:m+sep_save]
  258. ok = true
  259. s^ = s[m+len(sep):]
  260. }
  261. return
  262. }
  263. split_iterator :: proc(s: ^[]byte, sep: []byte) -> ([]byte, bool) {
  264. return _split_iterator(s, sep, 0)
  265. }
  266. split_after_iterator :: proc(s: ^[]byte, sep: []byte) -> ([]byte, bool) {
  267. return _split_iterator(s, sep, len(sep))
  268. }
  269. /*
  270. Scan a slice of bytes for a specific byte.
  271. This procedure safely handles slices of any length, including empty slices.
  272. Inputs:
  273. - data: A slice of bytes.
  274. - c: The byte to search for.
  275. Returns:
  276. - index: The index of the byte `c`, or -1 if it was not found.
  277. */
  278. index_byte :: proc(s: []byte, c: byte) -> (index: int) #no_bounds_check {
  279. i, l := 0, len(s)
  280. // Guard against small strings. On modern systems, it is ALWAYS
  281. // worth vectorizing assuming there is a hardware vector unit, and
  282. // the data size is large enough.
  283. if l < SIMD_REG_SIZE_128 {
  284. for /**/; i < l; i += 1 {
  285. if s[i] == c {
  286. return i
  287. }
  288. }
  289. return -1
  290. }
  291. c_vec: simd.u8x16 = c
  292. when !simd.IS_EMULATED {
  293. // Note: While this is something that could also logically take
  294. // advantage of AVX512, the various downclocking and power
  295. // consumption related woes make premature to have a dedicated
  296. // code path.
  297. when ODIN_ARCH == .amd64 && intrinsics.has_target_feature("avx2") {
  298. c_vec_256: simd.u8x32 = c
  299. s_vecs: [4]simd.u8x32 = ---
  300. c_vecs: [4]simd.u8x32 = ---
  301. m_vec: [4]u8 = ---
  302. // Scan 128-byte chunks, using 256-bit SIMD.
  303. for nr_blocks := l / (4 * SIMD_REG_SIZE_256); nr_blocks > 0; nr_blocks -= 1 {
  304. #unroll for j in 0..<4 {
  305. s_vecs[j] = intrinsics.unaligned_load(cast(^simd.u8x32)raw_data(s[i+j*SIMD_REG_SIZE_256:]))
  306. c_vecs[j] = simd.lanes_eq(s_vecs[j], c_vec_256)
  307. m_vec[j] = simd.reduce_or(c_vecs[j])
  308. }
  309. if m_vec[0] | m_vec[1] | m_vec[2] | m_vec[3] > 0 {
  310. #unroll for j in 0..<4 {
  311. if m_vec[j] > 0 {
  312. sel := simd.select(c_vecs[j], SCANNER_INDICES_256, SCANNER_SENTINEL_MIN_256)
  313. off := simd.reduce_min(sel)
  314. return i + j * SIMD_REG_SIZE_256 + int(off)
  315. }
  316. }
  317. }
  318. i += 4 * SIMD_REG_SIZE_256
  319. }
  320. // Scan 64-byte chunks, using 256-bit SIMD.
  321. for nr_blocks := (l - i) / (2 * SIMD_REG_SIZE_256); nr_blocks > 0; nr_blocks -= 1 {
  322. #unroll for j in 0..<2 {
  323. s_vecs[j] = intrinsics.unaligned_load(cast(^simd.u8x32)raw_data(s[i+j*SIMD_REG_SIZE_256:]))
  324. c_vecs[j] = simd.lanes_eq(s_vecs[j], c_vec_256)
  325. m_vec[j] = simd.reduce_or(c_vecs[j])
  326. }
  327. if m_vec[0] | m_vec[1] > 0 {
  328. #unroll for j in 0..<2 {
  329. if m_vec[j] > 0 {
  330. sel := simd.select(c_vecs[j], SCANNER_INDICES_256, SCANNER_SENTINEL_MIN_256)
  331. off := simd.reduce_min(sel)
  332. return i + j * SIMD_REG_SIZE_256 + int(off)
  333. }
  334. }
  335. }
  336. i += 2 * SIMD_REG_SIZE_256
  337. }
  338. } else {
  339. s_vecs: [4]simd.u8x16 = ---
  340. c_vecs: [4]simd.u8x16 = ---
  341. m_vecs: [4]u8 = ---
  342. // Scan 64-byte chunks, using 128-bit SIMD.
  343. for nr_blocks := l / (4 * SIMD_REG_SIZE_128); nr_blocks > 0; nr_blocks -= 1 {
  344. #unroll for j in 0..<4 {
  345. s_vecs[j]= intrinsics.unaligned_load(cast(^simd.u8x16)raw_data(s[i+j*SIMD_REG_SIZE_128:]))
  346. c_vecs[j] = simd.lanes_eq(s_vecs[j], c_vec)
  347. m_vecs[j] = simd.reduce_or(c_vecs[j])
  348. }
  349. if m_vecs[0] | m_vecs[1] | m_vecs[2] | m_vecs[3] > 0 {
  350. #unroll for j in 0..<4 {
  351. if m_vecs[j] > 0 {
  352. sel := simd.select(c_vecs[j], SCANNER_INDICES_128, SCANNER_SENTINEL_MIN_128)
  353. off := simd.reduce_min(sel)
  354. return i + j * SIMD_REG_SIZE_128 + int(off)
  355. }
  356. }
  357. }
  358. i += 4 * SIMD_REG_SIZE_128
  359. }
  360. }
  361. }
  362. // Scan the remaining SIMD register sized chunks.
  363. //
  364. // Apparently LLVM does ok with 128-bit SWAR, so this path is also taken
  365. // on potato targets. Scanning more at a time when LLVM is emulating SIMD
  366. // likely does not buy much, as all that does is increase GP register
  367. // pressure.
  368. for nr_blocks := (l - i) / SIMD_REG_SIZE_128; nr_blocks > 0; nr_blocks -= 1 {
  369. s0 := intrinsics.unaligned_load(cast(^simd.u8x16)raw_data(s[i:]))
  370. c0 := simd.lanes_eq(s0, c_vec)
  371. if simd.reduce_or(c0) > 0 {
  372. sel := simd.select(c0, SCANNER_INDICES_128, SCANNER_SENTINEL_MIN_128)
  373. off := simd.reduce_min(sel)
  374. return i + int(off)
  375. }
  376. i += SIMD_REG_SIZE_128
  377. }
  378. // Scan serially for the remainder.
  379. for /**/; i < l; i += 1 {
  380. if s[i] == c {
  381. return i
  382. }
  383. }
  384. return -1
  385. }
  386. /*
  387. Scan a slice of bytes for a specific byte, starting from the end and working
  388. backwards to the start.
  389. This procedure safely handles slices of any length, including empty slices.
  390. Inputs:
  391. - data: A slice of bytes.
  392. - c: The byte to search for.
  393. Returns:
  394. - index: The index of the byte `c`, or -1 if it was not found.
  395. */
  396. last_index_byte :: proc(s: []byte, c: byte) -> int #no_bounds_check {
  397. i := len(s)
  398. // Guard against small strings. On modern systems, it is ALWAYS
  399. // worth vectorizing assuming there is a hardware vector unit, and
  400. // the data size is large enough.
  401. if i < SIMD_REG_SIZE_128 {
  402. if i > 0 { // Handle s == nil.
  403. for /**/; i >= 0; i -= 1 {
  404. if s[i] == c {
  405. return i
  406. }
  407. }
  408. }
  409. return -1
  410. }
  411. c_vec: simd.u8x16 = c
  412. when !simd.IS_EMULATED {
  413. // Note: While this is something that could also logically take
  414. // advantage of AVX512, the various downclocking and power
  415. // consumption related woes make premature to have a dedicated
  416. // code path.
  417. when ODIN_ARCH == .amd64 && intrinsics.has_target_feature("avx2") {
  418. c_vec_256: simd.u8x32 = c
  419. s_vecs: [4]simd.u8x32 = ---
  420. c_vecs: [4]simd.u8x32 = ---
  421. m_vec: [4]u8 = ---
  422. // Scan 128-byte chunks, using 256-bit SIMD.
  423. for i >= 4 * SIMD_REG_SIZE_256 {
  424. i -= 4 * SIMD_REG_SIZE_256
  425. #unroll for j in 0..<4 {
  426. s_vecs[j] = intrinsics.unaligned_load(cast(^simd.u8x32)raw_data(s[i+j*SIMD_REG_SIZE_256:]))
  427. c_vecs[j] = simd.lanes_eq(s_vecs[j], c_vec_256)
  428. m_vec[j] = simd.reduce_or(c_vecs[j])
  429. }
  430. if m_vec[0] | m_vec[1] | m_vec[2] | m_vec[3] > 0 {
  431. #unroll for j in 0..<4 {
  432. if m_vec[3-j] > 0 {
  433. sel := simd.select(c_vecs[3-j], SCANNER_INDICES_256, SCANNER_SENTINEL_MAX_256)
  434. off := simd.reduce_max(sel)
  435. return i + (3-j) * SIMD_REG_SIZE_256 + int(off)
  436. }
  437. }
  438. }
  439. }
  440. // Scan 64-byte chunks, using 256-bit SIMD.
  441. for i >= 2 * SIMD_REG_SIZE_256 {
  442. i -= 2 * SIMD_REG_SIZE_256
  443. #unroll for j in 0..<2 {
  444. s_vecs[j] = intrinsics.unaligned_load(cast(^simd.u8x32)raw_data(s[i+j*SIMD_REG_SIZE_256:]))
  445. c_vecs[j] = simd.lanes_eq(s_vecs[j], c_vec_256)
  446. m_vec[j] = simd.reduce_or(c_vecs[j])
  447. }
  448. if m_vec[0] | m_vec[1] > 0 {
  449. #unroll for j in 0..<2 {
  450. if m_vec[1-j] > 0 {
  451. sel := simd.select(c_vecs[1-j], SCANNER_INDICES_256, SCANNER_SENTINEL_MAX_256)
  452. off := simd.reduce_max(sel)
  453. return i + (1-j) * SIMD_REG_SIZE_256 + int(off)
  454. }
  455. }
  456. }
  457. }
  458. } else {
  459. s_vecs: [4]simd.u8x16 = ---
  460. c_vecs: [4]simd.u8x16 = ---
  461. m_vecs: [4]u8 = ---
  462. // Scan 64-byte chunks, using 128-bit SIMD.
  463. for i >= 4 * SIMD_REG_SIZE_128 {
  464. i -= 4 * SIMD_REG_SIZE_128
  465. #unroll for j in 0..<4 {
  466. s_vecs[j] = intrinsics.unaligned_load(cast(^simd.u8x16)raw_data(s[i+j*SIMD_REG_SIZE_128:]))
  467. c_vecs[j] = simd.lanes_eq(s_vecs[j], c_vec)
  468. m_vecs[j] = simd.reduce_or(c_vecs[j])
  469. }
  470. if m_vecs[0] | m_vecs[1] | m_vecs[2] | m_vecs[3] > 0 {
  471. #unroll for j in 0..<4 {
  472. if m_vecs[3-j] > 0 {
  473. sel := simd.select(c_vecs[3-j], SCANNER_INDICES_128, SCANNER_SENTINEL_MAX_128)
  474. off := simd.reduce_max(sel)
  475. return i + (3-j) * SIMD_REG_SIZE_128 + int(off)
  476. }
  477. }
  478. }
  479. }
  480. }
  481. }
  482. // Scan the remaining SIMD register sized chunks.
  483. //
  484. // Apparently LLVM does ok with 128-bit SWAR, so this path is also taken
  485. // on potato targets. Scanning more at a time when LLVM is emulating SIMD
  486. // likely does not buy much, as all that does is increase GP register
  487. // pressure.
  488. for i >= SIMD_REG_SIZE_128 {
  489. i -= SIMD_REG_SIZE_128
  490. s0 := intrinsics.unaligned_load(cast(^simd.u8x16)raw_data(s[i:]))
  491. c0 := simd.lanes_eq(s0, c_vec)
  492. if simd.reduce_or(c0) > 0 {
  493. sel := simd.select(c0, SCANNER_INDICES_128, SCANNER_SENTINEL_MAX_128)
  494. off := simd.reduce_max(sel)
  495. return i + int(off)
  496. }
  497. }
  498. // Scan serially for the remainder.
  499. for i > 0 {
  500. i -= 1
  501. if s[i] == c {
  502. return i
  503. }
  504. }
  505. return -1
  506. }
  507. @private PRIME_RABIN_KARP :: 16777619
  508. index :: proc(s, substr: []byte) -> int {
  509. hash_str_rabin_karp :: proc(s: []byte) -> (hash: u32 = 0, pow: u32 = 1) {
  510. for i := 0; i < len(s); i += 1 {
  511. hash = hash*PRIME_RABIN_KARP + u32(s[i])
  512. }
  513. sq := u32(PRIME_RABIN_KARP)
  514. for i := len(s); i > 0; i >>= 1 {
  515. if (i & 1) != 0 {
  516. pow *= sq
  517. }
  518. sq *= sq
  519. }
  520. return
  521. }
  522. n := len(substr)
  523. switch {
  524. case n == 0:
  525. return 0
  526. case n == 1:
  527. return index_byte(s, substr[0])
  528. case n == len(s):
  529. if string(s) == string(substr) {
  530. return 0
  531. }
  532. return -1
  533. case n > len(s):
  534. return -1
  535. }
  536. hash, pow := hash_str_rabin_karp(substr)
  537. h: u32
  538. for i := 0; i < n; i += 1 {
  539. h = h*PRIME_RABIN_KARP + u32(s[i])
  540. }
  541. if h == hash && string(s[:n]) == string(substr) {
  542. return 0
  543. }
  544. for i := n; i < len(s); /**/ {
  545. h *= PRIME_RABIN_KARP
  546. h += u32(s[i])
  547. h -= pow * u32(s[i-n])
  548. i += 1
  549. if h == hash && string(s[i-n:i]) == string(substr) {
  550. return i - n
  551. }
  552. }
  553. return -1
  554. }
  555. last_index :: proc(s, substr: []byte) -> int {
  556. hash_str_rabin_karp_reverse :: proc(s: []byte) -> (hash: u32 = 0, pow: u32 = 1) {
  557. for i := len(s) - 1; i >= 0; i -= 1 {
  558. hash = hash*PRIME_RABIN_KARP + u32(s[i])
  559. }
  560. sq := u32(PRIME_RABIN_KARP)
  561. for i := len(s); i > 0; i >>= 1 {
  562. if (i & 1) != 0 {
  563. pow *= sq
  564. }
  565. sq *= sq
  566. }
  567. return
  568. }
  569. n := len(substr)
  570. switch {
  571. case n == 0:
  572. return len(s)
  573. case n == 1:
  574. return last_index_byte(s, substr[0])
  575. case n == len(s):
  576. return 0 if string(substr) == string(s) else -1
  577. case n > len(s):
  578. return -1
  579. }
  580. hash, pow := hash_str_rabin_karp_reverse(substr)
  581. last := len(s) - n
  582. h: u32
  583. for i := len(s)-1; i >= last; i -= 1 {
  584. h = h*PRIME_RABIN_KARP + u32(s[i])
  585. }
  586. if h == hash && string(s[last:]) == string(substr) {
  587. return last
  588. }
  589. for i := last-1; i >= 0; i -= 1 {
  590. h *= PRIME_RABIN_KARP
  591. h += u32(s[i])
  592. h -= pow * u32(s[i+n])
  593. if h == hash && string(s[i:i+n]) == string(substr) {
  594. return i
  595. }
  596. }
  597. return -1
  598. }
  599. index_any :: proc(s, chars: []byte) -> int {
  600. if chars == nil {
  601. return -1
  602. }
  603. // TODO(bill): Optimize
  604. for r, i in s {
  605. for c in chars {
  606. if r == c {
  607. return i
  608. }
  609. }
  610. }
  611. return -1
  612. }
  613. last_index_any :: proc(s, chars: []byte) -> int {
  614. if chars == nil {
  615. return -1
  616. }
  617. for i := len(s); i > 0; {
  618. r, w := utf8.decode_last_rune(s[:i])
  619. i -= w
  620. for c in string(chars) {
  621. if r == c {
  622. return i
  623. }
  624. }
  625. }
  626. return -1
  627. }
  628. count :: proc(s, substr: []byte) -> int {
  629. if len(substr) == 0 { // special case
  630. return rune_count(s) + 1
  631. }
  632. if len(substr) == 1 {
  633. c := substr[0]
  634. switch len(s) {
  635. case 0:
  636. return 0
  637. case 1:
  638. return int(s[0] == c)
  639. }
  640. n := 0
  641. for i := 0; i < len(s); i += 1 {
  642. if s[i] == c {
  643. n += 1
  644. }
  645. }
  646. return n
  647. }
  648. // TODO(bill): Use a non-brute for approach
  649. n := 0
  650. str := s
  651. for {
  652. i := index(str, substr)
  653. if i == -1 {
  654. return n
  655. }
  656. n += 1
  657. str = str[i+len(substr):]
  658. }
  659. return n
  660. }
  661. repeat :: proc(s: []byte, count: int, allocator := context.allocator) -> []byte {
  662. if count < 0 {
  663. panic("bytes: negative repeat count")
  664. } else if count > 0 && (len(s)*count)/count != len(s) {
  665. panic("bytes: repeat count will cause an overflow")
  666. }
  667. b := make([]byte, len(s)*count, allocator)
  668. i := copy(b, s)
  669. for i < len(b) { // 2^N trick to reduce the need to copy
  670. copy(b[i:], b[:i])
  671. i *= 2
  672. }
  673. return b
  674. }
  675. replace_all :: proc(s, old, new: []byte, allocator := context.allocator) -> (output: []byte, was_allocation: bool) {
  676. return replace(s, old, new, -1, allocator)
  677. }
  678. // if n < 0, no limit on the number of replacements
  679. replace :: proc(s, old, new: []byte, n: int, allocator := context.allocator) -> (output: []byte, was_allocation: bool) {
  680. if string(old) == string(new) || n == 0 {
  681. was_allocation = false
  682. output = s
  683. return
  684. }
  685. byte_count := n
  686. if m := count(s, old); m == 0 {
  687. was_allocation = false
  688. output = s
  689. return
  690. } else if n < 0 || m < n {
  691. byte_count = m
  692. }
  693. t := make([]byte, len(s) + byte_count*(len(new) - len(old)), allocator)
  694. was_allocation = true
  695. w := 0
  696. start := 0
  697. for i := 0; i < byte_count; i += 1 {
  698. j := start
  699. if len(old) == 0 {
  700. if i > 0 {
  701. _, width := utf8.decode_rune(s[start:])
  702. j += width
  703. }
  704. } else {
  705. j += index(s[start:], old)
  706. }
  707. w += copy(t[w:], s[start:j])
  708. w += copy(t[w:], new)
  709. start = j + len(old)
  710. }
  711. w += copy(t[w:], s[start:])
  712. output = t[0:w]
  713. return
  714. }
  715. remove :: proc(s, key: []byte, n: int, allocator := context.allocator) -> (output: []byte, was_allocation: bool) {
  716. return replace(s, key, {}, n, allocator)
  717. }
  718. remove_all :: proc(s, key: []byte, allocator := context.allocator) -> (output: []byte, was_allocation: bool) {
  719. return remove(s, key, -1, allocator)
  720. }
  721. @(private) _ascii_space := [256]u8{'\t' = 1, '\n' = 1, '\v' = 1, '\f' = 1, '\r' = 1, ' ' = 1}
  722. is_ascii_space :: proc(r: rune) -> bool {
  723. if r < utf8.RUNE_SELF {
  724. return _ascii_space[u8(r)] != 0
  725. }
  726. return false
  727. }
  728. is_space :: proc(r: rune) -> bool {
  729. if r < 0x2000 {
  730. switch r {
  731. case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xa0, 0x1680:
  732. return true
  733. }
  734. } else {
  735. if r <= 0x200a {
  736. return true
  737. }
  738. switch r {
  739. case 0x2028, 0x2029, 0x202f, 0x205f, 0x3000:
  740. return true
  741. }
  742. }
  743. return false
  744. }
  745. is_null :: proc(r: rune) -> bool {
  746. return r == 0x0000
  747. }
  748. index_proc :: proc(s: []byte, p: proc(rune) -> bool, truth := true) -> int {
  749. for r, i in string(s) {
  750. if p(r) == truth {
  751. return i
  752. }
  753. }
  754. return -1
  755. }
  756. index_proc_with_state :: proc(s: []byte, p: proc(rawptr, rune) -> bool, state: rawptr, truth := true) -> int {
  757. for r, i in string(s) {
  758. if p(state, r) == truth {
  759. return i
  760. }
  761. }
  762. return -1
  763. }
  764. last_index_proc :: proc(s: []byte, p: proc(rune) -> bool, truth := true) -> int {
  765. // TODO(bill): Probably use Rabin-Karp Search
  766. for i := len(s); i > 0; {
  767. r, size := utf8.decode_last_rune(s[:i])
  768. i -= size
  769. if p(r) == truth {
  770. return i
  771. }
  772. }
  773. return -1
  774. }
  775. last_index_proc_with_state :: proc(s: []byte, p: proc(rawptr, rune) -> bool, state: rawptr, truth := true) -> int {
  776. // TODO(bill): Probably use Rabin-Karp Search
  777. for i := len(s); i > 0; {
  778. r, size := utf8.decode_last_rune(s[:i])
  779. i -= size
  780. if p(state, r) == truth {
  781. return i
  782. }
  783. }
  784. return -1
  785. }
  786. trim_left_proc :: proc(s: []byte, p: proc(rune) -> bool) -> []byte {
  787. i := index_proc(s, p, false)
  788. if i == -1 {
  789. return nil
  790. }
  791. return s[i:]
  792. }
  793. index_rune :: proc(s: []byte, r: rune) -> int {
  794. switch {
  795. case u32(r) < utf8.RUNE_SELF:
  796. return index_byte(s, byte(r))
  797. case r == utf8.RUNE_ERROR:
  798. for c, i in string(s) {
  799. if c == utf8.RUNE_ERROR {
  800. return i
  801. }
  802. }
  803. return -1
  804. case !utf8.valid_rune(r):
  805. return -1
  806. }
  807. b, w := utf8.encode_rune(r)
  808. return index(s, b[:w])
  809. }
  810. trim_left_proc_with_state :: proc(s: []byte, p: proc(rawptr, rune) -> bool, state: rawptr) -> []byte {
  811. i := index_proc_with_state(s, p, state, false)
  812. if i == -1 {
  813. return nil
  814. }
  815. return s[i:]
  816. }
  817. trim_right_proc :: proc(s: []byte, p: proc(rune) -> bool) -> []byte {
  818. i := last_index_proc(s, p, false)
  819. if i >= 0 && s[i] >= utf8.RUNE_SELF {
  820. _, w := utf8.decode_rune(s[i:])
  821. i += w
  822. } else {
  823. i += 1
  824. }
  825. return s[0:i]
  826. }
  827. trim_right_proc_with_state :: proc(s: []byte, p: proc(rawptr, rune) -> bool, state: rawptr) -> []byte {
  828. i := last_index_proc_with_state(s, p, state, false)
  829. if i >= 0 && s[i] >= utf8.RUNE_SELF {
  830. _, w := utf8.decode_rune(s[i:])
  831. i += w
  832. } else {
  833. i += 1
  834. }
  835. return s[0:i]
  836. }
  837. is_in_cutset :: proc(state: rawptr, r: rune) -> bool {
  838. if state == nil {
  839. return false
  840. }
  841. cutset := (^string)(state)^
  842. for c in cutset {
  843. if r == c {
  844. return true
  845. }
  846. }
  847. return false
  848. }
  849. trim_left :: proc(s: []byte, cutset: []byte) -> []byte {
  850. if s == nil || cutset == nil {
  851. return s
  852. }
  853. state := cutset
  854. return trim_left_proc_with_state(s, is_in_cutset, &state)
  855. }
  856. trim_right :: proc(s: []byte, cutset: []byte) -> []byte {
  857. if s == nil || cutset == nil {
  858. return s
  859. }
  860. state := cutset
  861. return trim_right_proc_with_state(s, is_in_cutset, &state)
  862. }
  863. trim :: proc(s: []byte, cutset: []byte) -> []byte {
  864. return trim_right(trim_left(s, cutset), cutset)
  865. }
  866. trim_left_space :: proc(s: []byte) -> []byte {
  867. return trim_left_proc(s, is_space)
  868. }
  869. trim_right_space :: proc(s: []byte) -> []byte {
  870. return trim_right_proc(s, is_space)
  871. }
  872. trim_space :: proc(s: []byte) -> []byte {
  873. return trim_right_space(trim_left_space(s))
  874. }
  875. trim_left_null :: proc(s: []byte) -> []byte {
  876. return trim_left_proc(s, is_null)
  877. }
  878. trim_right_null :: proc(s: []byte) -> []byte {
  879. return trim_right_proc(s, is_null)
  880. }
  881. trim_null :: proc(s: []byte) -> []byte {
  882. return trim_right_null(trim_left_null(s))
  883. }
  884. trim_prefix :: proc(s, prefix: []byte) -> []byte {
  885. if has_prefix(s, prefix) {
  886. return s[len(prefix):]
  887. }
  888. return s
  889. }
  890. trim_suffix :: proc(s, suffix: []byte) -> []byte {
  891. if has_suffix(s, suffix) {
  892. return s[:len(s)-len(suffix)]
  893. }
  894. return s
  895. }
  896. split_multi :: proc(s: []byte, substrs: [][]byte, skip_empty := false, allocator := context.allocator) -> [][]byte #no_bounds_check {
  897. if s == nil || len(substrs) <= 0 {
  898. return nil
  899. }
  900. sublen := len(substrs[0])
  901. for substr in substrs[1:] {
  902. sublen = min(sublen, len(substr))
  903. }
  904. shared := len(s) - sublen
  905. if shared <= 0 {
  906. return nil
  907. }
  908. // number, index, last
  909. n, i, l := 0, 0, 0
  910. // count results
  911. first_pass: for i <= shared {
  912. for substr in substrs {
  913. if string(s[i:i+sublen]) == string(substr) {
  914. if !skip_empty || i - l > 0 {
  915. n += 1
  916. }
  917. i += sublen
  918. l = i
  919. continue first_pass
  920. }
  921. }
  922. _, skip := utf8.decode_rune(s[i:])
  923. i += skip
  924. }
  925. if !skip_empty || len(s) - l > 0 {
  926. n += 1
  927. }
  928. if n < 1 {
  929. // no results
  930. return nil
  931. }
  932. buf := make([][]byte, n, allocator)
  933. n, i, l = 0, 0, 0
  934. // slice results
  935. second_pass: for i <= shared {
  936. for substr in substrs {
  937. if string(s[i:i+sublen]) == string(substr) {
  938. if !skip_empty || i - l > 0 {
  939. buf[n] = s[l:i]
  940. n += 1
  941. }
  942. i += sublen
  943. l = i
  944. continue second_pass
  945. }
  946. }
  947. _, skip := utf8.decode_rune(s[i:])
  948. i += skip
  949. }
  950. if !skip_empty || len(s) - l > 0 {
  951. buf[n] = s[l:]
  952. }
  953. return buf
  954. }
  955. split_multi_iterator :: proc(s: ^[]byte, substrs: [][]byte, skip_empty := false) -> ([]byte, bool) #no_bounds_check {
  956. if s == nil || s^ == nil || len(substrs) <= 0 {
  957. return nil, false
  958. }
  959. sublen := len(substrs[0])
  960. for substr in substrs[1:] {
  961. sublen = min(sublen, len(substr))
  962. }
  963. shared := len(s) - sublen
  964. if shared <= 0 {
  965. return nil, false
  966. }
  967. // index, last
  968. i, l := 0, 0
  969. loop: for i <= shared {
  970. for substr in substrs {
  971. if string(s[i:i+sublen]) == string(substr) {
  972. if !skip_empty || i - l > 0 {
  973. res := s[l:i]
  974. s^ = s[i:]
  975. return res, true
  976. }
  977. i += sublen
  978. l = i
  979. continue loop
  980. }
  981. }
  982. _, skip := utf8.decode_rune(s[i:])
  983. i += skip
  984. }
  985. if !skip_empty || len(s) - l > 0 {
  986. res := s[l:]
  987. s^ = s[len(s):]
  988. return res, true
  989. }
  990. return nil, false
  991. }
  992. // Scrubs invalid utf-8 characters and replaces them with the replacement string
  993. // Adjacent invalid bytes are only replaced once
  994. scrub :: proc(s: []byte, replacement: []byte, allocator := context.allocator) -> []byte {
  995. str := s
  996. b: Buffer
  997. buffer_init_allocator(&b, 0, len(s), allocator)
  998. has_error := false
  999. cursor := 0
  1000. origin := str
  1001. for len(str) > 0 {
  1002. r, w := utf8.decode_rune(str)
  1003. if r == utf8.RUNE_ERROR {
  1004. if !has_error {
  1005. has_error = true
  1006. buffer_write(&b, origin[:cursor])
  1007. }
  1008. } else if has_error {
  1009. has_error = false
  1010. buffer_write(&b, replacement)
  1011. origin = origin[cursor:]
  1012. cursor = 0
  1013. }
  1014. cursor += w
  1015. str = str[w:]
  1016. }
  1017. return buffer_to_bytes(&b)
  1018. }
  1019. reverse :: proc(s: []byte, allocator := context.allocator) -> []byte {
  1020. str := s
  1021. n := len(str)
  1022. buf := make([]byte, n)
  1023. i := n
  1024. for len(str) > 0 {
  1025. _, w := utf8.decode_rune(str)
  1026. i -= w
  1027. copy(buf[i:], str[:w])
  1028. str = str[w:]
  1029. }
  1030. return buf
  1031. }
  1032. expand_tabs :: proc(s: []byte, tab_size: int, allocator := context.allocator) -> []byte {
  1033. if tab_size <= 0 {
  1034. panic("tab size must be positive")
  1035. }
  1036. if s == nil {
  1037. return nil
  1038. }
  1039. b: Buffer
  1040. buffer_init_allocator(&b, 0, len(s), allocator)
  1041. str := s
  1042. column: int
  1043. for len(str) > 0 {
  1044. r, w := utf8.decode_rune(str)
  1045. if r == '\t' {
  1046. expand := tab_size - column%tab_size
  1047. for i := 0; i < expand; i += 1 {
  1048. buffer_write_byte(&b, ' ')
  1049. }
  1050. column += expand
  1051. } else {
  1052. if r == '\n' {
  1053. column = 0
  1054. } else {
  1055. column += w
  1056. }
  1057. buffer_write_rune(&b, r)
  1058. }
  1059. str = str[w:]
  1060. }
  1061. return buffer_to_bytes(&b)
  1062. }
  1063. partition :: proc(str, sep: []byte) -> (head, match, tail: []byte) {
  1064. i := index(str, sep)
  1065. if i == -1 {
  1066. head = str
  1067. return
  1068. }
  1069. head = str[:i]
  1070. match = str[i:i+len(sep)]
  1071. tail = str[i+len(sep):]
  1072. return
  1073. }
  1074. center_justify :: centre_justify // NOTE(bill): Because Americans exist
  1075. // centre_justify returns a byte slice with a pad byte slice at boths sides if the str's rune length is smaller than length
  1076. centre_justify :: proc(str: []byte, length: int, pad: []byte, allocator := context.allocator) -> []byte {
  1077. n := rune_count(str)
  1078. if n >= length || pad == nil {
  1079. return clone(str, allocator)
  1080. }
  1081. remains := length-1
  1082. pad_len := rune_count(pad)
  1083. b: Buffer
  1084. buffer_init_allocator(&b, 0, len(str) + (remains/pad_len + 1)*len(pad), allocator)
  1085. write_pad_string(&b, pad, pad_len, remains/2)
  1086. buffer_write(&b, str)
  1087. write_pad_string(&b, pad, pad_len, (remains+1)/2)
  1088. return buffer_to_bytes(&b)
  1089. }
  1090. // left_justify returns a byte slice with a pad byte slice at left side if the str's rune length is smaller than length
  1091. left_justify :: proc(str: []byte, length: int, pad: []byte, allocator := context.allocator) -> []byte {
  1092. n := rune_count(str)
  1093. if n >= length || pad == nil {
  1094. return clone(str, allocator)
  1095. }
  1096. remains := length-1
  1097. pad_len := rune_count(pad)
  1098. b: Buffer
  1099. buffer_init_allocator(&b, 0, len(str) + (remains/pad_len + 1)*len(pad), allocator)
  1100. buffer_write(&b, str)
  1101. write_pad_string(&b, pad, pad_len, remains)
  1102. return buffer_to_bytes(&b)
  1103. }
  1104. // right_justify returns a byte slice with a pad byte slice at right side if the str's rune length is smaller than length
  1105. right_justify :: proc(str: []byte, length: int, pad: []byte, allocator := context.allocator) -> []byte {
  1106. n := rune_count(str)
  1107. if n >= length || pad == nil {
  1108. return clone(str, allocator)
  1109. }
  1110. remains := length-1
  1111. pad_len := rune_count(pad)
  1112. b: Buffer
  1113. buffer_init_allocator(&b, 0, len(str) + (remains/pad_len + 1)*len(pad), allocator)
  1114. write_pad_string(&b, pad, pad_len, remains)
  1115. buffer_write(&b, str)
  1116. return buffer_to_bytes(&b)
  1117. }
  1118. @private
  1119. write_pad_string :: proc(b: ^Buffer, pad: []byte, pad_len, remains: int) {
  1120. repeats := remains / pad_len
  1121. for i := 0; i < repeats; i += 1 {
  1122. buffer_write(b, pad)
  1123. }
  1124. n := remains % pad_len
  1125. p := pad
  1126. for i := 0; i < n; i += 1 {
  1127. r, width := utf8.decode_rune(p)
  1128. buffer_write_rune(b, r)
  1129. p = p[width:]
  1130. }
  1131. }
  1132. // fields splits the byte slice s around each instance of one or more consecutive white space character, defined by unicode.is_space
  1133. // returning a slice of subslices of s or an empty slice if s only contains white space
  1134. fields :: proc(s: []byte, allocator := context.allocator) -> [][]byte #no_bounds_check {
  1135. n := 0
  1136. was_space := 1
  1137. set_bits := u8(0)
  1138. // check to see
  1139. for i in 0..<len(s) {
  1140. r := s[i]
  1141. set_bits |= r
  1142. is_space := int(_ascii_space[r])
  1143. n += was_space & ~is_space
  1144. was_space = is_space
  1145. }
  1146. if set_bits >= utf8.RUNE_SELF {
  1147. return fields_proc(s, unicode.is_space, allocator)
  1148. }
  1149. if n == 0 {
  1150. return nil
  1151. }
  1152. a := make([][]byte, n, allocator)
  1153. na := 0
  1154. field_start := 0
  1155. i := 0
  1156. for i < len(s) && _ascii_space[s[i]] != 0 {
  1157. i += 1
  1158. }
  1159. field_start = i
  1160. for i < len(s) {
  1161. if _ascii_space[s[i]] == 0 {
  1162. i += 1
  1163. continue
  1164. }
  1165. a[na] = s[field_start : i]
  1166. na += 1
  1167. i += 1
  1168. for i < len(s) && _ascii_space[s[i]] != 0 {
  1169. i += 1
  1170. }
  1171. field_start = i
  1172. }
  1173. if field_start < len(s) {
  1174. a[na] = s[field_start:]
  1175. }
  1176. return a
  1177. }
  1178. // fields_proc splits the byte slice s at each run of unicode code points `ch` satisfying f(ch)
  1179. // returns a slice of subslices of s
  1180. // If all code points in s satisfy f(ch) or string is empty, an empty slice is returned
  1181. //
  1182. // fields_proc makes no guarantee about the order in which it calls f(ch)
  1183. // it assumes that `f` always returns the same value for a given ch
  1184. fields_proc :: proc(s: []byte, f: proc(rune) -> bool, allocator := context.allocator) -> [][]byte #no_bounds_check {
  1185. subslices := make([dynamic][]byte, 0, 32, allocator)
  1186. start, end := -1, -1
  1187. for r, offset in string(s) {
  1188. end = offset
  1189. if f(r) {
  1190. if start >= 0 {
  1191. append(&subslices, s[start : end])
  1192. // -1 could be used, but just speed it up through bitwise not
  1193. // gotta love 2's complement
  1194. start = ~start
  1195. }
  1196. } else {
  1197. if start < 0 {
  1198. start = end
  1199. }
  1200. }
  1201. }
  1202. if start >= 0 {
  1203. append(&subslices, s[start : len(s)])
  1204. }
  1205. return subslices[:]
  1206. }
  1207. // alias returns true iff a and b have a non-zero length, and any part of
  1208. // a overlaps with b.
  1209. alias :: proc "contextless" (a, b: []byte) -> bool {
  1210. a_len, b_len := len(a), len(b)
  1211. if a_len == 0 || b_len == 0 {
  1212. return false
  1213. }
  1214. a_start, b_start := uintptr(raw_data(a)), uintptr(raw_data(b))
  1215. a_end, b_end := a_start + uintptr(a_len-1), b_start + uintptr(b_len-1)
  1216. return a_start <= b_end && b_start <= a_end
  1217. }
  1218. // alias_inexactly returns true iff a and b have a non-zero length,
  1219. // the base pointer of a and b are NOT equal, and any part of a overlaps
  1220. // with b (ie: `alias(a, b)` with an exception that returns false for
  1221. // `a == b`, `b = a[:len(a)-69]` and similar conditions).
  1222. alias_inexactly :: proc "contextless" (a, b: []byte) -> bool {
  1223. if raw_data(a) == raw_data(b) {
  1224. return false
  1225. }
  1226. return alias(a, b)
  1227. }