@@ -1737,7 +1737,7 @@ val single_space : string
1737
1737
1738
1738
val concat3 : string -> string -> string -> string
1739
1739
val concat4 : string -> string -> string -> string -> string
1740
-
1740
+ val concat5 : string -> string -> string -> string -> string -> string
1741
1741
val inter2 : string -> string -> string
1742
1742
val inter3 : string -> string -> string -> string
1743
1743
val inter4 : string -> string -> string -> string -> string
@@ -1957,15 +1957,15 @@ let contain_substring s sub =
1957
1957
find s ~sub >= 0
1958
1958
1959
1959
(** TODO: optimize
1960
- avoid nonterminating when string is empty
1960
+ avoid nonterminating when string is empty
1961
1961
*)
1962
1962
let non_overlap_count ~sub s =
1963
1963
let sub_len = String.length sub in
1964
1964
let rec aux acc off =
1965
1965
let i = find ~start:off ~sub s in
1966
1966
if i < 0 then acc
1967
1967
else aux (acc + 1) (i + sub_len) in
1968
- if String.length sub = 0 then invalid_arg "Ext_string.non_overlap_count"
1968
+ if String.length sub = 0 then invalid_arg "Ext_string.non_overlap_count"
1969
1969
else aux 0 0
1970
1970
1971
1971
@@ -2128,19 +2128,95 @@ external compare : string -> string -> int = "caml_string_length_based_compare"
2128
2128
2129
2129
let single_space = " "
2130
2130
let single_colon = ":"
2131
- let concat3 a b c = a ^ b ^ c
2132
- let concat4 a b c d = a ^ b ^ c ^ d
2133
2131
2134
- let inter2 a b = a ^ single_space ^ b
2132
+ let concat_array sep (s : string array) =
2133
+ let s_len = Array.length s in
2134
+ match s_len with
2135
+ | 0 -> empty
2136
+ | 1 -> Array.unsafe_get s 0
2137
+ | _ ->
2138
+ let sep_len = String.length sep in
2139
+ let len = ref 0 in
2140
+ for i = 0 to s_len - 1 do
2141
+ len := !len + String.length (Array.unsafe_get s i)
2142
+ done;
2143
+ let target =
2144
+ Bytes.create
2145
+ (!len + (s_len - 1) * sep_len ) in
2146
+ let hd = (Array.unsafe_get s 0) in
2147
+ let hd_len = String.length hd in
2148
+ String.unsafe_blit hd 0 target 0 hd_len;
2149
+ let current_offset = ref hd_len in
2150
+ for i = 1 to s_len - 1 do
2151
+ String.unsafe_blit sep 0 target !current_offset sep_len;
2152
+ let cur = Array.unsafe_get s i in
2153
+ let cur_len = String.length cur in
2154
+ let new_off_set = (!current_offset + sep_len ) in
2155
+ String.unsafe_blit cur 0 target new_off_set cur_len;
2156
+ current_offset :=
2157
+ new_off_set + cur_len ;
2158
+ done;
2159
+ Bytes.unsafe_to_string target
2160
+
2161
+ let concat3 a b c =
2162
+ let a_len = String.length a in
2163
+ let b_len = String.length b in
2164
+ let c_len = String.length c in
2165
+ let len = a_len + b_len + c_len in
2166
+ let target = Bytes.create len in
2167
+ String.unsafe_blit a 0 target 0 a_len ;
2168
+ String.unsafe_blit b 0 target a_len b_len;
2169
+ String.unsafe_blit c 0 target (a_len + b_len) c_len;
2170
+ Bytes.unsafe_to_string target
2171
+
2172
+ let concat4 a b c d =
2173
+ let a_len = String.length a in
2174
+ let b_len = String.length b in
2175
+ let c_len = String.length c in
2176
+ let d_len = String.length d in
2177
+ let len = a_len + b_len + c_len + d_len in
2178
+
2179
+ let target = Bytes.create len in
2180
+ String.unsafe_blit a 0 target 0 a_len ;
2181
+ String.unsafe_blit b 0 target a_len b_len;
2182
+ String.unsafe_blit c 0 target (a_len + b_len) c_len;
2183
+ String.unsafe_blit d 0 target (a_len + b_len + c_len) d_len;
2184
+ Bytes.unsafe_to_string target
2185
+
2186
+
2187
+ let concat5 a b c d e =
2188
+ let a_len = String.length a in
2189
+ let b_len = String.length b in
2190
+ let c_len = String.length c in
2191
+ let d_len = String.length d in
2192
+ let e_len = String.length e in
2193
+ let len = a_len + b_len + c_len + d_len + e_len in
2194
+
2195
+ let target = Bytes.create len in
2196
+ String.unsafe_blit a 0 target 0 a_len ;
2197
+ String.unsafe_blit b 0 target a_len b_len;
2198
+ String.unsafe_blit c 0 target (a_len + b_len) c_len;
2199
+ String.unsafe_blit d 0 target (a_len + b_len + c_len) d_len;
2200
+ String.unsafe_blit e 0 target (a_len + b_len + c_len + d_len) e_len;
2201
+ Bytes.unsafe_to_string target
2202
+
2203
+
2204
+
2205
+ let inter2 a b =
2206
+ concat3 a single_space b
2207
+
2135
2208
2136
2209
let inter3 a b c =
2137
- a ^ single_space ^ b ^ single_space ^ c
2210
+ concat5 a single_space b single_space c
2211
+
2212
+
2213
+
2214
+
2138
2215
2139
2216
let inter4 a b c d =
2140
- a ^ single_space ^ b ^ single_space ^ c ^ single_space ^ d
2141
- (** TODO: improve perf *)
2142
- let concat_array sep (s : string array) =
2143
- String.concat sep (Array.to_list s)
2217
+ concat_array single_space [| a; b ; c; d|]
2218
+
2219
+
2144
2220
end
2145
2221
module Ounit_array_tests
2146
2222
= struct
@@ -11939,7 +12015,7 @@ let suites =
11939
12015
OUnit.assert_bool __LOC__ (Ext_string.compare a b < 0);
11940
12016
OUnit.assert_bool __LOC__ (Ext_string.compare b a > 0)
11941
12017
done ;
11942
-
12018
+
11943
12019
end;
11944
12020
__LOC__ >:: begin fun _ ->
11945
12021
let slow_compare x y =
@@ -11949,20 +12025,96 @@ let suites =
11949
12025
String.compare x y
11950
12026
else
11951
12027
Pervasives.compare x_len y_len in
11952
- let same_sign x y =
11953
- if x = 0 then y = 0
11954
- else if x < 0 then y < 0
11955
- else y > 0 in
11956
- for i = 0 to 3000 do
11957
- let chars = [|'a';'b';'c';'d'|] in
11958
- let x = Ounit_data_random.random_string chars 129 in
11959
- let y = Ounit_data_random.random_string chars 129 in
11960
- let a = Ext_string.compare x y in
11961
- let b = slow_compare x y in
11962
- if same_sign a b then OUnit.assert_bool __LOC__ true
11963
- else failwith ("incosistent " ^ x ^ " " ^ y ^ " " ^ string_of_int a ^ " " ^ string_of_int b)
11964
- done
11965
- end
12028
+ let same_sign x y =
12029
+ if x = 0 then y = 0
12030
+ else if x < 0 then y < 0
12031
+ else y > 0 in
12032
+ for i = 0 to 3000 do
12033
+ let chars = [|'a';'b';'c';'d'|] in
12034
+ let x = Ounit_data_random.random_string chars 129 in
12035
+ let y = Ounit_data_random.random_string chars 129 in
12036
+ let a = Ext_string.compare x y in
12037
+ let b = slow_compare x y in
12038
+ if same_sign a b then OUnit.assert_bool __LOC__ true
12039
+ else failwith ("incosistent " ^ x ^ " " ^ y ^ " " ^ string_of_int a ^ " " ^ string_of_int b)
12040
+ done
12041
+ end ;
12042
+ __LOC__ >:: begin fun _ ->
12043
+ OUnit.assert_bool __LOC__
12044
+ (Ext_string.equal
12045
+ (Ext_string.concat3 "a0" "a1" "a2") "a0a1a2"
12046
+ );
12047
+ OUnit.assert_bool __LOC__
12048
+ (Ext_string.equal
12049
+ (Ext_string.concat3 "a0" "a11" "") "a0a11"
12050
+ );
12051
+
12052
+ OUnit.assert_bool __LOC__
12053
+ (Ext_string.equal
12054
+ (Ext_string.concat4 "a0" "a1" "a2" "a3") "a0a1a2a3"
12055
+ );
12056
+ OUnit.assert_bool __LOC__
12057
+ (Ext_string.equal
12058
+ (Ext_string.concat4 "a0" "a11" "" "a33") "a0a11a33"
12059
+ );
12060
+ end;
12061
+ __LOC__ >:: begin fun _ ->
12062
+ OUnit.assert_bool __LOC__
12063
+ (Ext_string.equal
12064
+ (Ext_string.inter2 "a0" "a1") "a0 a1"
12065
+ );
12066
+ OUnit.assert_bool __LOC__
12067
+ (Ext_string.equal
12068
+ (Ext_string.inter3 "a0" "a1" "a2") "a0 a1 a2"
12069
+ );
12070
+ OUnit.assert_bool __LOC__
12071
+ (Ext_string.equal
12072
+ (Ext_string.inter4 "a0" "a1" "a2" "a3") "a0 a1 a2 a3"
12073
+ );
12074
+ end;
12075
+ __LOC__ >:: begin fun _ ->
12076
+ OUnit.assert_bool __LOC__
12077
+ (Ext_string.equal
12078
+ (Ext_string.concat_array Ext_string.single_space [||])
12079
+ Ext_string.empty
12080
+ );
12081
+ OUnit.assert_bool __LOC__
12082
+ (Ext_string.equal
12083
+ (Ext_string.concat_array Ext_string.single_space [|"a0"|])
12084
+ "a0"
12085
+ );
12086
+ OUnit.assert_bool __LOC__
12087
+ (Ext_string.equal
12088
+ (Ext_string.concat_array Ext_string.single_space [|"a0";"a1"|])
12089
+ "a0 a1"
12090
+ );
12091
+ OUnit.assert_bool __LOC__
12092
+ (Ext_string.equal
12093
+ (Ext_string.concat_array Ext_string.single_space [|"a0";"a1"; "a2"|])
12094
+ "a0 a1 a2"
12095
+ );
12096
+ OUnit.assert_bool __LOC__
12097
+ (Ext_string.equal
12098
+ (Ext_string.concat_array Ext_string.single_space [|"a0";"a1"; "a2";"a3"|])
12099
+ "a0 a1 a2 a3"
12100
+ );
12101
+ OUnit.assert_bool __LOC__
12102
+ (Ext_string.equal
12103
+ (Ext_string.concat_array Ext_string.single_space [|"a0";"a1"; "a2";"a3";""; "a4"|])
12104
+ "a0 a1 a2 a3 a4"
12105
+ );
12106
+ OUnit.assert_bool __LOC__
12107
+ (Ext_string.equal
12108
+ (Ext_string.concat_array Ext_string.single_space [|"0";"a1"; "2";"a3";""; "a4"|])
12109
+ "0 a1 2 a3 a4"
12110
+ );
12111
+ OUnit.assert_bool __LOC__
12112
+ (Ext_string.equal
12113
+ (Ext_string.concat_array Ext_string.single_space [|"0";"a1"; "2";"3";"d"; ""; "e"|])
12114
+ "0 a1 2 3 d e"
12115
+ );
12116
+
12117
+ end
11966
12118
]
11967
12119
end
11968
12120
module Ext_topsort : sig
0 commit comments