@@ -1737,7 +1737,7 @@ val single_space : string
17371737
17381738val concat3 : string -> string -> string -> string
17391739val concat4 : string -> string -> string -> string -> string
1740-
1740+ val concat5 : string -> string -> string -> string -> string -> string
17411741val inter2 : string -> string -> string
17421742val inter3 : string -> string -> string -> string
17431743val inter4 : string -> string -> string -> string -> string
@@ -1957,15 +1957,15 @@ let contain_substring s sub =
19571957 find s ~sub >= 0
19581958
19591959(** TODO: optimize
1960- avoid nonterminating when string is empty
1960+ avoid nonterminating when string is empty
19611961*)
19621962let non_overlap_count ~sub s =
19631963 let sub_len = String.length sub in
19641964 let rec aux acc off =
19651965 let i = find ~start:off ~sub s in
19661966 if i < 0 then acc
19671967 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"
19691969 else aux 0 0
19701970
19711971
@@ -2128,19 +2128,95 @@ external compare : string -> string -> int = "caml_string_length_based_compare"
21282128
21292129let single_space = " "
21302130let single_colon = ":"
2131- let concat3 a b c = a ^ b ^ c
2132- let concat4 a b c d = a ^ b ^ c ^ d
21332131
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+
21352208
21362209let 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+
21382215
21392216let 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+
21442220end
21452221module Ounit_array_tests
21462222= struct
@@ -11939,7 +12015,7 @@ let suites =
1193912015 OUnit.assert_bool __LOC__ (Ext_string.compare a b < 0);
1194012016 OUnit.assert_bool __LOC__ (Ext_string.compare b a > 0)
1194112017 done ;
11942-
12018+
1194312019 end;
1194412020 __LOC__ >:: begin fun _ ->
1194512021 let slow_compare x y =
@@ -11949,20 +12025,96 @@ let suites =
1194912025 String.compare x y
1195012026 else
1195112027 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
1196612118 ]
1196712119end
1196812120module Ext_topsort : sig
0 commit comments