1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
module String_set = Set.Make (String)
module Char_set = Set.Make (Char)
external ext_string_length : string -> int = "%string_length"
external ext_string_unsafe_get : string -> int -> char = "%string_unsafe_get"
external ext_bytes_length : bytes -> int = "%bytes_length"
external ext_bytes_unsafe_get : bytes -> int -> char = "%bytes_unsafe_get"
external ext_bytes_of_string : string -> bytes = "%bytes_of_string"
let bytes_fold_left f x a =
let r = ref x in
for i = 0 to ext_bytes_length a - 1 do
r := f !r (ext_bytes_unsafe_get a i)
done;
!r
let string_fold_left f a x = bytes_fold_left f a (ext_bytes_of_string x)
let bytes_for_all p s =
let n = ext_bytes_length s in
let rec loop i =
if i = n then true
else if p (ext_bytes_unsafe_get s i) then loop (succ i)
else false
in
loop 0
let string_for_all f s = bytes_for_all f (ext_bytes_of_string s)
let string_starts_with ~prefix s =
let len_s = ext_string_length s and len_pre = ext_string_length prefix in
let rec aux i =
if i = len_pre then true
else if ext_string_unsafe_get s i <> ext_string_unsafe_get prefix i then
false
else aux (i + 1)
in
len_s >= len_pre && aux 0
let string_ends_with ~suffix s =
let len_s = ext_string_length s and len_suf = ext_string_length suffix in
let diff = len_s - len_suf in
let rec aux i =
if i = len_suf then true
else if ext_string_unsafe_get s (diff + i) <> ext_string_unsafe_get suffix i
then false
else aux (i + 1)
in
diff >= 0 && aux 0
let bytes_swap_inplace bytes i j =
let tmp = Stdlib.Bytes.get bytes i in
Stdlib.Bytes.set bytes i (Stdlib.Bytes.get bytes j);
Stdlib.Bytes.set bytes j tmp
let bytes_rev_inplace bytes =
let len = Bytes.length bytes in
for i = 0 to (len / 2) - 1 do
let tmp = Bytes.get bytes i in
Bytes.set bytes i (Bytes.get bytes (len - 1 - i));
Bytes.set bytes (len - 1 - i) tmp
done
let bytes_shuffle_inplace bytes =
let bytes_len = Stdlib.Bytes.length bytes in
for i = 0 to bytes_len - 1 - 1 do
let j = bytes_len - 1 - i in
let r =
((i * j) + Stdlib.Bytes.get_uint8 bytes i + Stdlib.Bytes.get_uint8 bytes j)
mod bytes_len
in
bytes_swap_inplace bytes i r
done
let bytes_rotate bytes offset =
let len = Bytes.length bytes in
let rotated_bytes = Bytes.create len in
for i = 0 to len - 1 do
Bytes.set rotated_bytes i (Bytes.get bytes ((i + offset) mod len))
done;
rotated_bytes
let char_is_digit c = match c with '0' .. '9' -> true | _ -> false
let string_has_dups str =
let module Char_set = Set.Make (Char) in
let set =
string_fold_left (fun set c -> Char_set.add c set) Char_set.empty str
in
Stdlib.String.length str <> Char_set.cardinal set
let string_is_infix ~affix s =
let len_a = ext_string_length affix in
let len_s = ext_string_length s in
if len_a > len_s then false
else
let max_idx_a = len_a - 1 in
let max_idx_s = len_s - len_a in
let rec loop i k =
if i > max_idx_s then false
else if k > max_idx_a then true
else if k > 0 then
if ext_string_unsafe_get affix k = ext_string_unsafe_get s (i + k) then
loop i (k + 1)
else loop (i + 1) 0
else if ext_string_unsafe_get affix 0 = ext_string_unsafe_get s i then
loop i 1
else loop (i + 1) 0
in
loop 0 0
let list_is_empty = function [] -> true | _ -> false