Skip to content

Commit 8c52a72

Browse files
v0.18~preview.130.83+317
1 parent 52a6c24 commit 8c52a72

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+3741
-1623
lines changed

LICENSE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License
22

3-
Copyright (c) 2016--2025 Jane Street Group, LLC <opensource-contacts@janestreet.com>
3+
Copyright (c) 2016--2026 Jane Street Group, LLC <opensource-contacts@janestreet.com>
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

src/array.ml

Lines changed: 71 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ include Array
1111
type ('a : any mod separable) t = 'a array
1212

1313
[%%template
14-
[@@@kind_set.define values = (value_with_imm, value mod external_, value mod external64)]
14+
[@@@kind_set.define base_with_ext = (base, value mod external64)]
1515

16-
type%template ('a : k) t = 'a array [@@kind k = (base_non_value, immediate, immediate64)]
16+
type%template ('a : k) t = 'a array [@@kind k = (base_non_value, value mod external64)]
1717

1818
[%%rederive.portable
1919
type nonrec ('a : value_or_null mod separable) t = 'a array
@@ -47,7 +47,7 @@ type%template ('a : k) t = 'a array [@@kind k = (base_non_value, immediate, imme
4747
- http://www.sorting-algorithms.com/quick-sort-3-way *)
4848

4949
module%template.portable
50-
[@kind k = values] [@modality p] Sorter (S : sig
50+
[@kind k = (value, value mod external64)] [@modality p] Sorter (S : sig
5151
type ('a : k) t
5252

5353
val get : local_ 'a t -> int -> 'a
@@ -293,7 +293,8 @@ struct
293293
end
294294
[@@inline]
295295

296-
module%template [@kind k = values] Sort = Sorter [@kind k] [@modality portable] (struct
296+
module%template [@kind k = (value, value mod external64)] Sort =
297+
Sorter [@kind k] [@modality portable] (struct
297298
type nonrec ('a : k) t = 'a t
298299

299300
let get = unsafe_get
@@ -303,13 +304,13 @@ module%template [@kind k = values] Sort = Sorter [@kind k] [@modality portable]
303304

304305
let sort = Sort.sort
305306

306-
let%template get_opt arr n : (_ Option.t[@kind k]) =
307+
let%template get_opt arr n : (_ Option.t[@kind k or value_or_null]) =
307308
if 0 <= n && n < length arr
308309
then
309310
Some ((unsafe_get [@mode c]) arr n)
310311
(* SAFETY: bounds checked above *) [@exclave_if_stack a]
311312
else None
312-
[@@mode c = (uncontended, shared)] [@@kind k = base_with_imm] [@@alloc a = (heap, stack)]
313+
[@@mode c = (uncontended, shared)] [@@kind k = base] [@@alloc a = (heap, stack)]
313314
;;
314315

315316
let is_sorted t ~compare =
@@ -362,13 +363,13 @@ let raise_length_mismatch name n1 n2 =
362363
;;
363364

364365
[%%template
365-
let length t = length t [@@kind k = (base_non_value, immediate, immediate64)]
366+
let length t = length t [@@kind k = (base_non_value, value mod external64)]
366367

367-
[@@@kind.default k1 = base_with_imm]
368+
[@@@kind.default k1 = base_with_ext]
368369

369370
let to_array t = t
370371
let of_array t = t
371-
let is_empty t = (length [@kind k1]) t = 0
372+
let is_empty t = length t = 0
372373

373374
let for_all t ~f =
374375
let i = ref (length t - 1) in
@@ -425,7 +426,9 @@ let existsi t ~f =
425426

426427
let mem t a ~equal = (exists [@kind k1]) t ~f:(equal a) [@nontail]
427428

428-
let[@inline always] extremal_element t ~compare ~keep_left_if : (_ Option.t[@kind k1]) =
429+
let[@inline always] extremal_element t ~compare ~keep_left_if
430+
: (_ Option.t[@kind k1 or value_or_null])
431+
=
429432
if (is_empty [@kind k1]) t
430433
then None
431434
else (
@@ -436,7 +439,7 @@ let[@inline always] extremal_element t ~compare ~keep_left_if : (_ Option.t[@kin
436439
let x = unsafe_get t i in
437440
loop
438441
(i + 1)
439-
((Bool0.select [@kind k1])
442+
((Bool0.select [@kind k1 or value_or_null])
440443
((keep_left_if [@inlined]) ((compare [@inlined hint]) x result))
441444
x
442445
result))
@@ -475,7 +478,7 @@ let find t ~(f @ local) =
475478
(findi_internal [@inlined] [@kind k1 value])
476479
t
477480
~f:(fun _ v -> f v)
478-
~if_found:(fun ~i:_ ~value : (_ Option.t[@kind k1]) -> Some value)
481+
~if_found:(fun ~i:_ ~value : (_ Option.t[@kind k1 or value_or_null]) -> Some value)
479482
~if_not_found:(fun () -> None) [@nontail]
480483
;;
481484

@@ -485,14 +488,16 @@ let find_exn t ~(f @ local) =
485488
~f:(fun _i x -> f x)
486489
~if_found:(fun ~i:_ ~value -> value)
487490
~if_not_found:(fun () ->
488-
(raise [@kind k1]) (Not_found_s (Atom "Array.find_exn: not found"))) [@nontail]
491+
(raise [@kind k1 or value_or_null]) (Not_found_s (Atom "Array.find_exn: not found")))
492+
[@nontail]
489493
;;
490494

491495
let findi t ~f =
492496
(findi_internal [@inlined] [@kind k1 value])
493497
t
494498
~f
495-
~if_found:(fun ~i ~value : (_ Option.t[@kind value & k1]) -> Some #(i, value))
499+
~if_found:(fun ~i ~value : (_ Option.t[@kind value & (k1 or value)]) ->
500+
Some #(i, value))
496501
~if_not_found:(fun () -> None)
497502
;;
498503

@@ -502,11 +507,12 @@ let findi_exn t ~f =
502507
~f
503508
~if_found:(fun ~i ~value -> #(i, value))
504509
~if_not_found:(fun () ->
505-
(raise [@kind value & k1]) (Not_found_s (Atom "Array.findi_exn: not found")))
510+
(raise [@kind value & (k1 or value)])
511+
(Not_found_s (Atom "Array.findi_exn: not found")))
506512
;;
507513

508514
(* The [value] version of this implementation initializes the output only once, based on
509-
the primitive [caml_array_sub]. Other approaches, like [init] or [map], first
515+
the primitive [caml_array_sub]. Other approaches, like [init] or [map], first
510516
initialize with a fixed value, then blit from the source. *)
511517
let copy t = (sub [@kind k1]) t ~pos:0 ~len:(length t)
512518

@@ -526,11 +532,11 @@ let rev t =
526532
t
527533
;;
528534

529-
let of_list_rev (l : (_ List.Constructors.t[@kind k1])) =
535+
let of_list_rev (l : (_ List.Constructors.t[@kind k1 or value_or_null])) =
530536
match l with
531537
| [] -> [||]
532538
| a :: l ->
533-
let len = 1 + (List.length [@kind k1]) l in
539+
let len = 1 + (List.length [@kind k1 or value_or_null]) l in
534540
let t = create ~len a in
535541
let r = ref l in
536542
(* We start at [len - 2] because we already put [a] at [t.(len - 1)]. *)
@@ -562,7 +568,7 @@ let iteri_until t ~f ~finish =
562568
then (
563569
match
564570
((f [@inlined hint]) i (unsafe_get t i)
565-
: (_ Container.Continue_or_stop.t[@kind value k2]))
571+
: (_ Container.Continue_or_stop.t[@kind value_or_null (k2 or value_or_null)]))
566572
with
567573
| Continue () -> loop (i + 1)
568574
| Stop res -> res)
@@ -661,13 +667,13 @@ let foldi t ~init ~f =
661667
(loop [@inlined]) 0 init [@nontail]
662668
;;]
663669

664-
[@@@kind.default k2 = base_with_imm]
670+
[@@@kind.default k2 = base_with_ext]
665671

666672
let filter_mapi t ~f =
667673
let r = ref [||] in
668674
let k = ref 0 in
669675
for i = 0 to length t - 1 do
670-
match (f i (unsafe_get t i) : (_ Option.t[@kind k2])) with
676+
match (f i (unsafe_get t i) : (_ Option.t[@kind k2 or value_or_null])) with
671677
| None -> ()
672678
| Some a ->
673679
if !k = 0 then r := create ~len:(length t) a;
@@ -689,12 +695,16 @@ let check_length2_exn name t1 t2 =
689695

690696
(* [of_list_map] and [of_list_rev_map] are based on functions from the OCaml distribution. *)
691697

692-
let of_list_map (xs : (_ List.Constructors.t[@kind k1])) ~f =
698+
let of_list_map (xs : (_ List.Constructors.t[@kind k1 or value_or_null])) ~f =
693699
match xs with
694700
| [] -> [||]
695701
| hd :: tl ->
696-
let a = create ~len:(1 + (List.length [@kind k1]) tl) ((f [@inlined hint]) hd) in
697-
let rec fill i : (_ List.Constructors.t[@kind k1]) -> _ = function
702+
let a =
703+
create
704+
~len:(1 + (List.length [@kind k1 or value_or_null]) tl)
705+
((f [@inlined hint]) hd)
706+
in
707+
let rec fill i : (_ List.Constructors.t[@kind k1 or value_or_null]) -> _ = function
698708
| [] -> a
699709
| hd :: tl ->
700710
unsafe_set a i ((f [@inlined hint]) hd);
@@ -703,12 +713,16 @@ let of_list_map (xs : (_ List.Constructors.t[@kind k1])) ~f =
703713
fill 1 tl [@nontail]
704714
;;
705715

706-
let of_list_mapi (xs : (_ List.Constructors.t[@kind k1])) ~f =
716+
let of_list_mapi (xs : (_ List.Constructors.t[@kind k1 or value_or_null])) ~f =
707717
match xs with
708718
| [] -> [||]
709719
| hd :: tl ->
710-
let a = create ~len:(1 + (List.length [@kind k1]) tl) ((f [@inlined hint]) 0 hd) in
711-
let rec fill a i : (_ List.Constructors.t[@kind k1]) -> _ = function
720+
let a =
721+
create
722+
~len:(1 + (List.length [@kind k1 or value_or_null]) tl)
723+
((f [@inlined hint]) 0 hd)
724+
in
725+
let rec fill a i : (_ List.Constructors.t[@kind k1 or value_or_null]) -> _ = function
712726
| [] -> a
713727
| hd :: tl ->
714728
unsafe_set a i ((f [@inlined hint]) i hd);
@@ -737,8 +751,17 @@ let for_all2_exn t1 t2 ~f =
737751
(loop [@inlined]) (length t1 - 1) [@nontail]
738752
;;]]
739753

754+
let globalize = (globalize_array [@kind k]) [@@kind k = base]
755+
740756
[%%template
741-
[@@@kind.default k1 = base_with_imm]
757+
[@@@kind.default k = base]
758+
[@@@mode.default m = (global, local)]
759+
760+
let equal = (equal_array [@kind k] [@mode m])
761+
let compare = (compare_array [@kind k] [@mode m])]
762+
763+
[%%template
764+
[@@@kind.default k1 = base_with_ext]
742765

743766
let filter t ~f =
744767
(filter_map [@kind k1 k1]) t ~f:(fun x -> if f x then Some x else None) [@nontail]
@@ -748,15 +771,6 @@ let filteri t ~f =
748771
(filter_mapi [@kind k1 k1]) t ~f:(fun i x -> if f i x then Some x else None) [@nontail]
749772
;;
750773

751-
let globalize = (globalize_array [@kind k1])
752-
753-
[%%template
754-
[@@@kind.default k1]
755-
[@@@mode.default m = (global, local)]
756-
757-
let equal = (equal_array [@kind k1] [@mode m])
758-
let compare = (compare_array [@kind k1] [@mode m])]
759-
760774
[%%template
761775
[@@@kind.default k1 = k1, k2 = base, k3 = base]
762776

@@ -767,7 +781,8 @@ let foldi_until t ~init ~f ~finish =
767781
then (
768782
match
769783
((f [@inlined hint]) i acc (unsafe_get t i)
770-
: (_ Container.Continue_or_stop.t[@kind k2 k3]))
784+
: (_ Container.Continue_or_stop.t
785+
[@kind (k2 or value_or_null) (k3 or value_or_null)]))
771786
with
772787
| Continue acc -> loop (i + 1) acc
773788
| Stop res -> res)
@@ -784,7 +799,7 @@ let fold_until t ~init ~f ~finish =
784799
~finish:(fun _i acc -> finish acc) [@nontail]
785800
;;]
786801

787-
[@@@kind.default k2 = base_with_imm]
802+
[@@@kind.default k2 = base_with_ext]
788803

789804
let of_list_rev_map xs ~f =
790805
let t = (of_list_map [@kind k1 k2]) xs ~f in
@@ -798,18 +813,20 @@ let of_list_rev_mapi xs ~f =
798813
t
799814
;;
800815

801-
[@@@kind.default k3 = base_with_imm]
816+
[@@@kind.default k3 = base_with_ext]
802817

803818
let partition_mapi t ~f =
804-
let (both : (_ Either0.t[@kind k2 k3]) t) = (mapi [@kind k1 value]) t ~f in
819+
let (both : (_ Either0.t[@kind (k2 or value_or_null) (k3 or value_or_null)]) t) =
820+
(mapi [@kind k1 value]) t ~f
821+
in
805822
let firsts =
806823
(filter_map [@kind value k2]) both ~f:(function
807-
| First x -> (Some x : (_ Option.t[@kind k2]))
824+
| First x -> (Some x : (_ Option.t[@kind k2 or value_or_null]))
808825
| Second _ -> None)
809826
in
810827
let seconds =
811828
(filter_map [@kind value k3]) both ~f:(function
812-
| First _ -> (None : (_ Option.t[@kind k3]))
829+
| First _ -> (None : (_ Option.t[@kind k3 or value_or_null]))
813830
| Second x -> Some x)
814831
in
815832
firsts, seconds
@@ -820,7 +837,7 @@ let partition_map t ~f =
820837
;;]
821838

822839
[%%template
823-
[@@@kind.default k = base_with_imm]
840+
[@@@kind.default k = base_with_ext]
824841

825842
let partitioni_tf t ~f =
826843
(partition_mapi [@kind k k k]) t ~f:(fun i x -> if f i x then First x else Second x)
@@ -838,8 +855,6 @@ let partition_tf t ~f = (partitioni_tf [@kind k]) t ~f:(fun _ x -> f x) [@nontai
838855
[%%template
839856
[@@@alloc.default a @ m = (heap_global, stack_local)]
840857

841-
let sexp_of_t = (sexp_of_t [@alloc a]) [@@kind k = (immediate, immediate64)]
842-
843858
let sexp_of_t (sexp_of_elt : _ @ m -> Sexp0.t @ m) (t @ m) : Sexp0.t =
844859
(let rec loop i res =
845860
if i < 0
@@ -852,15 +867,13 @@ let sexp_of_t (sexp_of_elt : _ @ m -> Sexp0.t @ m) (t @ m) : Sexp0.t =
852867
;;]
853868

854869
[%%template
855-
let t_of_sexp = t_of_sexp [@@kind k = (immediate, immediate64)]
856-
857-
let t_of_sexp elt_of_sexp (sexp : Sexp0.t) =
858-
match sexp with
859-
| List [] -> [||]
860-
| List (_ :: _ as l) -> (of_list_map [@kind value k]) l ~f:elt_of_sexp
861-
| Atom _ -> of_sexp_error "array_of_sexp: list needed" sexp
862-
[@@kind k = base_non_value]
863-
;;]
870+
let t_of_sexp elt_of_sexp (sexp : Sexp0.t) =
871+
match sexp with
872+
| List [] -> [||]
873+
| List (_ :: _ as l) -> (of_list_map [@kind value k]) l ~f:elt_of_sexp
874+
| Atom _ -> of_sexp_error "array_of_sexp: list needed" sexp
875+
[@@kind k = base_non_value]
876+
;;]
864877

865878
(* We generated [findi]s that return [value & value]s, but for backwards compatibility we
866879
want to return the boxed product instead when dealing only with values. *)
@@ -1104,7 +1117,7 @@ let transpose_exn tt =
11041117

11051118
[@@@warning "-incompatible-with-upstream"]
11061119

1107-
let%template[@kind k1 = base_with_imm, k2 = base_with_imm] map t ~f =
1120+
let%template[@kind k1 = base_with_ext, k2 = base_with_ext] map t ~f =
11081121
(map [@kind k1 k2]) t ~f
11091122
;;
11101123

@@ -1160,9 +1173,9 @@ let sub t ~pos ~len = sub t ~pos ~len
11601173
let invariant invariant_a t = iter t ~f:invariant_a
11611174

11621175
module Private = struct
1163-
module%template [@kind k = values] Sort = Sort [@kind k]
1176+
module%template [@kind k = (value, value mod external64)] Sort = Sort [@kind k]
11641177

1165-
module%template.portable [@kind k = values] [@modality p] Sorter =
1178+
module%template.portable [@kind k = (value, value mod external64)] [@modality p] Sorter =
11661179
Sorter
11671180
[@kind k]
11681181
[@modality p]

0 commit comments

Comments
 (0)