My working unpac repository
at opam/upstream/seq 621 lines 19 kB view raw
1(**************************************************************************) 2(* *) 3(* OCaml *) 4(* *) 5(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) 6(* Nicolas Ojeda Bar, LexiFi *) 7(* *) 8(* Copyright 2018 Institut National de Recherche en Informatique et *) 9(* en Automatique. *) 10(* *) 11(* All rights reserved. This file is distributed under the terms of *) 12(* the GNU Lesser General Public License version 2.1, with the *) 13(* special exception on linking described in the file LICENSE. *) 14(* *) 15(**************************************************************************) 16 17external neg : float -> float = "%negfloat" 18external add : float -> float -> float = "%addfloat" 19external sub : float -> float -> float = "%subfloat" 20external mul : float -> float -> float = "%mulfloat" 21external div : float -> float -> float = "%divfloat" 22external rem : float -> float -> float = "caml_fmod_float" "fmod" 23 [@@unboxed] [@@noalloc] 24external fma : float -> float -> float -> float = "caml_fma_float" "caml_fma" 25 [@@unboxed] [@@noalloc] 26external abs : float -> float = "%absfloat" 27 28let zero = 0. 29let one = 1. 30let minus_one = -1. 31let infinity = Stdlib.infinity 32let neg_infinity = Stdlib.neg_infinity 33let nan = Stdlib.nan 34let quiet_nan = nan 35external float_of_bits : int64 -> float 36 = "caml_int64_float_of_bits" "caml_int64_float_of_bits_unboxed" 37 [@@unboxed] [@@noalloc] 38let signaling_nan = float_of_bits 0x7F_F0_00_00_00_00_00_01L 39let is_finite (x: float) = x -. x = 0. 40let is_infinite (x: float) = 1. /. x = 0. 41let is_nan (x: float) = x <> x 42 43let pi = 0x1.921fb54442d18p+1 44let max_float = Stdlib.max_float 45let min_float = Stdlib.min_float 46let epsilon = Stdlib.epsilon_float 47external of_int : int -> float = "%floatofint" 48external to_int : float -> int = "%intoffloat" 49external of_string : string -> float = "caml_float_of_string" 50let of_string_opt = Stdlib.float_of_string_opt 51let to_string = Stdlib.string_of_float 52type fpclass = Stdlib.fpclass = 53 FP_normal 54 | FP_subnormal 55 | FP_zero 56 | FP_infinite 57 | FP_nan 58external classify_float : (float [@unboxed]) -> fpclass = 59 "caml_classify_float" "caml_classify_float_unboxed" [@@noalloc] 60external pow : float -> float -> float = "caml_power_float" "pow" 61 [@@unboxed] [@@noalloc] 62external sqrt : float -> float = "caml_sqrt_float" "sqrt" 63 [@@unboxed] [@@noalloc] 64external cbrt : float -> float = "caml_cbrt_float" "caml_cbrt" 65 [@@unboxed] [@@noalloc] 66external exp : float -> float = "caml_exp_float" "exp" [@@unboxed] [@@noalloc] 67external exp2 : float -> float = "caml_exp2_float" "caml_exp2" 68 [@@unboxed] [@@noalloc] 69external log : float -> float = "caml_log_float" "log" [@@unboxed] [@@noalloc] 70external log10 : float -> float = "caml_log10_float" "log10" 71 [@@unboxed] [@@noalloc] 72external log2 : float -> float = "caml_log2_float" "caml_log2" 73 [@@unboxed] [@@noalloc] 74external expm1 : float -> float = "caml_expm1_float" "caml_expm1" 75 [@@unboxed] [@@noalloc] 76external log1p : float -> float = "caml_log1p_float" "caml_log1p" 77 [@@unboxed] [@@noalloc] 78external cos : float -> float = "caml_cos_float" "cos" [@@unboxed] [@@noalloc] 79external sin : float -> float = "caml_sin_float" "sin" [@@unboxed] [@@noalloc] 80external tan : float -> float = "caml_tan_float" "tan" [@@unboxed] [@@noalloc] 81external acos : float -> float = "caml_acos_float" "acos" 82 [@@unboxed] [@@noalloc] 83external asin : float -> float = "caml_asin_float" "asin" 84 [@@unboxed] [@@noalloc] 85external atan : float -> float = "caml_atan_float" "atan" 86 [@@unboxed] [@@noalloc] 87external atan2 : float -> float -> float = "caml_atan2_float" "atan2" 88 [@@unboxed] [@@noalloc] 89external hypot : float -> float -> float 90 = "caml_hypot_float" "caml_hypot" [@@unboxed] [@@noalloc] 91external cosh : float -> float = "caml_cosh_float" "cosh" 92 [@@unboxed] [@@noalloc] 93external sinh : float -> float = "caml_sinh_float" "sinh" 94 [@@unboxed] [@@noalloc] 95external tanh : float -> float = "caml_tanh_float" "tanh" 96 [@@unboxed] [@@noalloc] 97external acosh : float -> float = "caml_acosh_float" "caml_acosh" 98 [@@unboxed] [@@noalloc] 99external asinh : float -> float = "caml_asinh_float" "caml_asinh" 100 [@@unboxed] [@@noalloc] 101external atanh : float -> float = "caml_atanh_float" "caml_atanh" 102 [@@unboxed] [@@noalloc] 103external erf : float -> float = "caml_erf_float" "caml_erf" 104 [@@unboxed] [@@noalloc] 105external erfc : float -> float = "caml_erfc_float" "caml_erfc" 106 [@@unboxed] [@@noalloc] 107external trunc : float -> float = "caml_trunc_float" "caml_trunc" 108 [@@unboxed] [@@noalloc] 109external round : float -> float = "caml_round_float" "caml_round" 110 [@@unboxed] [@@noalloc] 111external ceil : float -> float = "caml_ceil_float" "ceil" 112 [@@unboxed] [@@noalloc] 113external floor : float -> float = "caml_floor_float" "floor" 114[@@unboxed] [@@noalloc] 115 116let is_integer x = x = trunc x && is_finite x 117 118external next_after : float -> float -> float 119 = "caml_nextafter_float" "caml_nextafter" [@@unboxed] [@@noalloc] 120 121let succ x = next_after x infinity 122let pred x = next_after x neg_infinity 123 124external copy_sign : float -> float -> float 125 = "caml_copysign_float" "caml_copysign" 126 [@@unboxed] [@@noalloc] 127external sign_bit : (float [@unboxed]) -> bool 128 = "caml_signbit_float" "caml_signbit" [@@noalloc] 129 130external frexp : float -> float * int = "caml_frexp_float" 131external ldexp : (float [@unboxed]) -> (int [@untagged]) -> (float [@unboxed]) = 132 "caml_ldexp_float" "caml_ldexp_float_unboxed" [@@noalloc] 133external modf : float -> float * float = "caml_modf_float" 134type t = float 135external compare : float -> float -> int = "%compare" 136let equal x y = compare x y = 0 137 138let[@inline] min (x: float) (y: float) = 139 if y > x || (not(sign_bit y) && sign_bit x) then 140 if is_nan y then y else x 141 else if is_nan x then x else y 142 143let[@inline] max (x: float) (y: float) = 144 if y > x || (not(sign_bit y) && sign_bit x) then 145 if is_nan x then x else y 146 else if is_nan y then y else x 147 148let[@inline] min_max (x: float) (y: float) = 149 if is_nan x || is_nan y then (nan, nan) 150 else if y > x || (not(sign_bit y) && sign_bit x) then (x, y) else (y, x) 151 152let[@inline] min_num (x: float) (y: float) = 153 if y > x || (not(sign_bit y) && sign_bit x) then 154 if is_nan x then y else x 155 else if is_nan y then x else y 156 157let[@inline] max_num (x: float) (y: float) = 158 if y > x || (not(sign_bit y) && sign_bit x) then 159 if is_nan y then x else y 160 else if is_nan x then y else x 161 162let[@inline] min_max_num (x: float) (y: float) = 163 if is_nan x then (y,y) 164 else if is_nan y then (x,x) 165 else if y > x || (not(sign_bit y) && sign_bit x) then (x,y) else (y,x) 166 167external seeded_hash_param : 168 int -> int -> int -> 'a -> int = "caml_hash" [@@noalloc] 169let seeded_hash seed x = seeded_hash_param 10 100 seed x 170let hash x = seeded_hash_param 10 100 0 x 171 172module Array = struct 173 174 type t = floatarray 175 176 external length : t -> int = "%floatarray_length" 177 external get : t -> int -> float = "%floatarray_safe_get" 178 external set : t -> int -> float -> unit = "%floatarray_safe_set" 179 external create : int -> t = "caml_floatarray_create" 180 external unsafe_get : t -> int -> float = "%floatarray_unsafe_get" 181 external unsafe_set : t -> int -> float -> unit = "%floatarray_unsafe_set" 182 183 external make : (int[@untagged]) -> (float[@unboxed]) -> t = 184 "caml_floatarray_make" "caml_floatarray_make_unboxed" 185 186 external unsafe_fill 187 : t -> (int[@untagged]) -> (int[@untagged]) -> (float[@unboxed]) -> unit 188 = "caml_floatarray_fill" "caml_floatarray_fill_unboxed" [@@noalloc] 189 190 external unsafe_blit: t -> int -> t -> int -> int -> unit = 191 "caml_floatarray_blit" [@@noalloc] 192 193 external unsafe_sub : t -> int -> int -> t = "caml_floatarray_sub" 194 external append_prim : t -> t -> t = "caml_floatarray_append" 195 external concat : t list -> t = "caml_floatarray_concat" 196 197 let check a ofs len msg = 198 if ofs < 0 || len < 0 || ofs + len < 0 || ofs + len > length a then 199 invalid_arg msg 200 201 let empty = create 0 202 203 let init l f = 204 if l < 0 then invalid_arg "Float.Array.init" 205 else 206 let res = create l in 207 for i = 0 to l - 1 do 208 unsafe_set res i (f i) 209 done; 210 res 211 212 let make_matrix sx sy v = 213 (* We raise even if [sx = 0 && sy < 0]: *) 214 if sy < 0 then invalid_arg "Float.Array.make_matrix"; 215 let res = Array.make sx (create 0) in 216 if sy > 0 then begin 217 for x = 0 to sx - 1 do 218 Array.unsafe_set res x (make sy v) 219 done; 220 end; 221 res 222 223 let init_matrix sx sy f = 224 (* We raise even if [sx = 0 && sy < 0]: *) 225 if sy < 0 then invalid_arg "Float.Array.init_matrix"; 226 let res = Array.make sx (create 0) in 227 if sy > 0 then begin 228 for x = 0 to sx - 1 do 229 let row = create sy in 230 for y = 0 to sy - 1 do 231 unsafe_set row y (f x y) 232 done; 233 Array.unsafe_set res x row 234 done; 235 end; 236 res 237 238 let sub a ofs len = 239 check a ofs len "Float.Array.sub"; 240 unsafe_sub a ofs len 241 242 let copy a = 243 let l = length a in 244 if l = 0 then empty 245 else unsafe_sub a 0 l 246 247 let append a1 a2 = 248 let l1 = length a1 in 249 if l1 = 0 then copy a2 250 else if length a2 = 0 then unsafe_sub a1 0 l1 251 else append_prim a1 a2 252 253 (* inlining exposes a float-unboxing opportunity for [v] *) 254 let[@inline] fill a ofs len v = 255 check a ofs len "Float.Array.fill"; 256 unsafe_fill a ofs len v 257 258 let blit src sofs dst dofs len = 259 check src sofs len "Float.array.blit"; 260 check dst dofs len "Float.array.blit"; 261 unsafe_blit src sofs dst dofs len 262 263 let to_list a = 264 List.init (length a) (unsafe_get a) 265 266 let of_list l = 267 let result = create (List.length l) in 268 let rec fill i l = 269 match l with 270 | [] -> result 271 | h :: t -> unsafe_set result i h; fill (i + 1) t 272 in 273 fill 0 l 274 275 (* duplicated from array.ml *) 276 let equal eq a b = 277 if length a <> length b then false else 278 let i = ref 0 in 279 let len = length a in 280 while !i < len && eq (unsafe_get a !i) (unsafe_get b !i) do incr i done; 281 !i = len 282 283 let float_compare = compare 284 (* duplicated from array.ml *) 285 let compare cmp a b = 286 let len_a = length a and len_b = length b in 287 let diff = len_a - len_b in 288 if diff <> 0 then (if diff < 0 then -1 else 1) else 289 let i = ref 0 and c = ref 0 in 290 while !i < len_a && !c = 0 291 do c := cmp (unsafe_get a !i) (unsafe_get b !i); incr i done; 292 !c 293 294 (* duplicated from array.ml *) 295 let iter f a = 296 for i = 0 to length a - 1 do f (unsafe_get a i) done 297 298 (* duplicated from array.ml *) 299 let iter2 f a b = 300 if length a <> length b then 301 invalid_arg "Float.Array.iter2: arrays must have the same length" 302 else 303 for i = 0 to length a - 1 do f (unsafe_get a i) (unsafe_get b i) done 304 305 let map f a = 306 let l = length a in 307 let r = create l in 308 for i = 0 to l - 1 do 309 unsafe_set r i (f (unsafe_get a i)) 310 done; 311 r 312 313 (* duplicated from array.ml *) 314 let map_inplace f a = 315 for i = 0 to length a - 1 do 316 unsafe_set a i (f (unsafe_get a i)) 317 done 318 319 let map2 f a b = 320 let la = length a in 321 let lb = length b in 322 if la <> lb then 323 invalid_arg "Float.Array.map2: arrays must have the same length" 324 else begin 325 let r = create la in 326 for i = 0 to la - 1 do 327 unsafe_set r i (f (unsafe_get a i) (unsafe_get b i)) 328 done; 329 r 330 end 331 332 (* duplicated from array.ml *) 333 let iteri f a = 334 for i = 0 to length a - 1 do f i (unsafe_get a i) done 335 336 let mapi f a = 337 let l = length a in 338 let r = create l in 339 for i = 0 to l - 1 do 340 unsafe_set r i (f i (unsafe_get a i)) 341 done; 342 r 343 344 (* duplicated from array.ml *) 345 let mapi_inplace f a = 346 for i = 0 to length a - 1 do 347 unsafe_set a i (f i (unsafe_get a i)) 348 done 349 350 (* duplicated from array.ml *) 351 let fold_left f x a = 352 let r = ref x in 353 for i = 0 to length a - 1 do 354 r := f !r (unsafe_get a i) 355 done; 356 !r 357 358 (* duplicated from array.ml *) 359 let fold_right f a x = 360 let r = ref x in 361 for i = length a - 1 downto 0 do 362 r := f (unsafe_get a i) !r 363 done; 364 !r 365 366 (* duplicated from array.ml *) 367 let exists p a = 368 let n = length a in 369 let rec loop i = 370 if i = n then false 371 else if p (unsafe_get a i) then true 372 else loop (i + 1) in 373 loop 0 374 375 (* duplicated from array.ml *) 376 let for_all p a = 377 let n = length a in 378 let rec loop i = 379 if i = n then true 380 else if p (unsafe_get a i) then loop (i + 1) 381 else false in 382 loop 0 383 384 (* duplicated from array.ml *) 385 let mem x a = 386 let n = length a in 387 let rec loop i = 388 if i = n then false 389 else if float_compare (unsafe_get a i) x = 0 then true 390 else loop (i + 1) 391 in 392 loop 0 393 394 (* mostly duplicated from array.ml, but slightly different *) 395 let mem_ieee x a = 396 let n = length a in 397 let rec loop i = 398 if i = n then false 399 else if x = (unsafe_get a i) then true 400 else loop (i + 1) 401 in 402 loop 0 403 404 (* duplicated from array.ml *) 405 let find_opt p a = 406 let n = length a in 407 let rec loop i = 408 if i = n then None 409 else 410 let x = unsafe_get a i in 411 if p x then Some x 412 else loop (i + 1) 413 in 414 loop 0 415 416 (* duplicated from array.ml *) 417 let find_index p a = 418 let n = length a in 419 let rec loop i = 420 if i = n then None 421 else if p (unsafe_get a i) then Some i 422 else loop (i + 1) in 423 loop 0 424 425 (* duplicated from array.ml *) 426 let find_map f a = 427 let n = length a in 428 let rec loop i = 429 if i = n then None 430 else 431 match f (unsafe_get a i) with 432 | None -> loop (i + 1) 433 | Some _ as r -> r 434 in 435 loop 0 436 437 (* duplicated from array.ml *) 438 let find_mapi f a = 439 let n = length a in 440 let rec loop i = 441 if i = n then None 442 else 443 match f i (unsafe_get a i) with 444 | None -> loop (i + 1) 445 | Some _ as r -> r 446 in 447 loop 0 448 449 (* duplicated from array.ml *) 450 exception Bottom of int 451 let sort cmp a = 452 let maxson l i = 453 let i31 = i+i+i+1 in 454 let x = ref i31 in 455 if i31+2 < l then begin 456 if cmp (get a i31) (get a (i31+1)) < 0 then x := i31+1; 457 if cmp (get a !x) (get a (i31+2)) < 0 then x := i31+2; 458 !x 459 end else 460 if i31+1 < l && cmp (get a i31) (get a (i31+1)) < 0 461 then i31+1 462 else if i31 < l then i31 else raise (Bottom i) 463 in 464 let rec trickledown l i e = 465 let j = maxson l i in 466 if cmp (get a j) e > 0 then begin 467 set a i (get a j); 468 trickledown l j e; 469 end else begin 470 set a i e; 471 end; 472 in 473 let trickle l i e = try trickledown l i e with Bottom i -> set a i e in 474 let rec bubbledown l i = 475 let j = maxson l i in 476 set a i (get a j); 477 bubbledown l j 478 in 479 let bubble l i = try bubbledown l i with Bottom i -> i in 480 let rec trickleup i e = 481 let father = (i - 1) / 3 in 482 assert (i <> father); 483 if cmp (get a father) e < 0 then begin 484 set a i (get a father); 485 if father > 0 then trickleup father e else set a 0 e; 486 end else begin 487 set a i e; 488 end; 489 in 490 let l = length a in 491 for i = (l + 1) / 3 - 1 downto 0 do trickle l i (get a i); done; 492 for i = l - 1 downto 2 do 493 let e = (get a i) in 494 set a i (get a 0); 495 trickleup (bubble i 0) e; 496 done; 497 if l > 1 then (let e = (get a 1) in set a 1 (get a 0); set a 0 e) 498 499 (* duplicated from array.ml, except for the call to [create] *) 500 let cutoff = 5 501 let stable_sort cmp a = 502 let merge src1ofs src1len src2 src2ofs src2len dst dstofs = 503 let src1r = src1ofs + src1len and src2r = src2ofs + src2len in 504 let rec loop i1 s1 i2 s2 d = 505 if cmp s1 s2 <= 0 then begin 506 set dst d s1; 507 let i1 = i1 + 1 in 508 if i1 < src1r then 509 loop i1 (get a i1) i2 s2 (d + 1) 510 else 511 blit src2 i2 dst (d + 1) (src2r - i2) 512 end else begin 513 set dst d s2; 514 let i2 = i2 + 1 in 515 if i2 < src2r then 516 loop i1 s1 i2 (get src2 i2) (d + 1) 517 else 518 blit a i1 dst (d + 1) (src1r - i1) 519 end 520 in loop src1ofs (get a src1ofs) src2ofs (get src2 src2ofs) dstofs; 521 in 522 let isortto srcofs dst dstofs len = 523 for i = 0 to len - 1 do 524 let e = (get a (srcofs + i)) in 525 let j = ref (dstofs + i - 1) in 526 while (!j >= dstofs && cmp (get dst !j) e > 0) do 527 set dst (!j + 1) (get dst !j); 528 decr j; 529 done; 530 set dst (!j + 1) e; 531 done; 532 in 533 let rec sortto srcofs dst dstofs len = 534 if len <= cutoff then isortto srcofs dst dstofs len else begin 535 let l1 = len / 2 in 536 let l2 = len - l1 in 537 sortto (srcofs + l1) dst (dstofs + l1) l2; 538 sortto srcofs a (srcofs + l2) l1; 539 merge (srcofs + l2) l1 dst (dstofs + l1) l2 dst dstofs; 540 end; 541 in 542 let l = length a in 543 if l <= cutoff then isortto 0 a 0 l else begin 544 let l1 = l / 2 in 545 let l2 = l - l1 in 546 let t = create l2 in 547 sortto l1 t 0 l2; 548 sortto 0 a l2 l1; 549 merge l2 l1 t 0 l2 a 0; 550 end 551 552 let fast_sort = stable_sort 553 554 (* duplicated from array.ml *) 555 let shuffle ~rand a = (* Fisher-Yates *) 556 for i = length a - 1 downto 1 do 557 let j = rand (i + 1) in 558 let v = unsafe_get a i in 559 unsafe_set a i (get a j); 560 unsafe_set a j v 561 done 562 563 (* duplicated from array.ml *) 564 let to_seq a = 565 let rec aux i () = 566 if i < length a 567 then 568 let x = unsafe_get a i in 569 Seq.Cons (x, aux (i+1)) 570 else Seq.Nil 571 in 572 aux 0 573 574 (* duplicated from array.ml *) 575 let to_seqi a = 576 let rec aux i () = 577 if i < length a 578 then 579 let x = unsafe_get a i in 580 Seq.Cons ((i,x), aux (i+1)) 581 else Seq.Nil 582 in 583 aux 0 584 585 (* mostly duplicated from array.ml *) 586 let of_rev_list l = 587 let len = List.length l in 588 let a = create len in 589 let rec fill i = function 590 [] -> a 591 | hd::tl -> unsafe_set a i hd; fill (i-1) tl 592 in 593 fill (len-1) l 594 595 (* duplicated from array.ml *) 596 let of_seq i = 597 let l = Seq.fold_left (fun acc x -> x::acc) [] i in 598 of_rev_list l 599 600 601 let map_to_array f a = 602 let l = length a in 603 if l = 0 then [| |] else begin 604 let r = Array.make l (f (unsafe_get a 0)) in 605 for i = 1 to l - 1 do 606 Array.unsafe_set r i (f (unsafe_get a i)) 607 done; 608 r 609 end 610 611 let map_from_array f a = 612 let l = Array.length a in 613 let r = create l in 614 for i = 0 to l - 1 do 615 unsafe_set r i (f (Array.unsafe_get a i)) 616 done; 617 r 618 619end 620 621module ArrayLabels = Array