@@ -6,9 +6,12 @@ open! Import
6
6
7
7
module Definitions = struct
8
8
module type Public = sig
9
- type 'a t
10
- [@@ deriving
11
- compare ~localize , equal ~localize , globalize , sexp ~localize , sexp_grammar ]
9
+ type ('a : any_non_null) t
10
+
11
+ [%% rederive:
12
+ type nonrec 'a t = 'a t
13
+ [@@ deriving
14
+ compare ~localize , equal ~localize , globalize , sexp ~localize , sexp_grammar ]]
12
15
13
16
include Binary_searchable. S1 with type 'a t := 'a t
14
17
include Indexed_container. S1_with_creators with type 'a t := 'a t
@@ -18,55 +21,95 @@ module Definitions = struct
18
21
[max_length/2] on 32-bit machines and [max_length] on 64-bit machines. *)
19
22
val max_length : int
20
23
21
- (* _ Declared as externals so that the compiler skips the caml_apply_X wrapping even when
22
- compiling without cross library inlining. *)
24
+ (* _ Declared as externals so that the compiler skips the caml_apply_X wrapping even
25
+ when compiling without cross library inlining. *)
23
26
24
- external length : ('a t [@ local_opt]) -> int = " %array_length"
27
+ external length
28
+ : ('a : any_non_null ).
29
+ ('a array [@ local_opt]) @ contended -> int
30
+ = " %array_length"
31
+ [@@ layout_poly]
25
32
26
33
(* * [Array.get a n] returns the element number [n] of array [a]. The first element has
27
34
number 0. The last element has number [Array.length a - 1]. You can also write
28
35
[a.(n)] instead of [Array.get a n].
29
36
30
37
Raise [Invalid_argument "index out of bounds"] if [n] is outside the range 0 to
31
38
[(Array.length a - 1)]. *)
32
- external get : ('a t [@ local_opt]) -> (int [@ local_opt]) -> 'a = " %array_safe_get"
39
+ external% template get
40
+ : ('a : any_non_null ).
41
+ ('a array [@ local_opt]) @ m -> (int [@ local_opt]) -> 'a @ m
42
+ = " %array_safe_get"
43
+ [@@ layout_poly] [@@ mode m = (uncontended, shared)]
33
44
34
45
(* * [Array.set a n x] modifies array [a] in place, replacing element number [n] with
35
46
[x]. You can also write [a.(n) <- x] instead of [Array.set a n x].
36
47
37
48
Raise [Invalid_argument "index out of bounds"] if [n] is outside the range 0 to
38
49
[Array.length a - 1]. *)
39
50
external set
40
- : ('a t[@ local_opt])
41
- -> (int [@ local_opt])
42
- -> 'a
43
- -> unit
51
+ : ('a : any_non_null ).
52
+ ('a array [@ local_opt]) -> (int [@ local_opt]) -> 'a -> unit
44
53
= " %array_safe_set"
54
+ [@@ layout_poly]
45
55
46
56
(* * Unsafe version of [get]. Can cause arbitrary behavior when used for an
47
57
out-of-bounds array access. *)
48
- external unsafe_get
49
- : ('a t[@ local_opt])
50
- -> (int [@ local_opt])
51
- -> 'a
58
+ external% template unsafe_get
59
+ : ('a : any_non_null ).
60
+ ('a array [@ local_opt]) @ m -> (int [@ local_opt]) -> 'a @ m
52
61
= " %array_unsafe_get"
62
+ [@@ layout_poly] [@@ mode m = (uncontended, shared)]
53
63
54
64
(* * Unsafe version of [set]. Can cause arbitrary behavior when used for an
55
65
out-of-bounds array access. *)
56
66
external unsafe_set
57
- : ('a t[@ local_opt])
58
- -> (int [@ local_opt])
59
- -> 'a
60
- -> unit
67
+ : ('a : any_non_null ).
68
+ ('a array [@ local_opt]) -> (int [@ local_opt]) -> 'a -> unit
61
69
= " %array_unsafe_set"
62
-
63
- (* * [create ~len x] creates an array of length [len] with the value [x] populated in
64
- each element. *)
65
- val create : len :int -> 'a -> 'a t
66
-
67
- (* * [create_local ~len x] is like [create]. It allocates the array on the local stack.
68
- The array's elements are still global. *)
69
- val create_local : len :int -> 'a -> local_ 'a t
70
+ [@@ layout_poly]
71
+
72
+ [%% template:
73
+ external create
74
+ : ('a : any_non_null ).
75
+ len:int -> 'a -> 'a array @ m
76
+ = " %makearray_dynamic"
77
+ [@@ ocaml.doc
78
+ " [create ~len x] creates an array of length [len] with the value [x] populated in\n \
79
+ \ each element. " ]
80
+ [@@ layout_poly]
81
+ [@@ alloc __ @ m = (heap_global, stack_local)]]
82
+
83
+ external create_local
84
+ : ('a : any_non_null ).
85
+ len:int -> 'a -> local_ 'a array
86
+ = " %makearray_dynamic"
87
+ [@@ ocaml.doc
88
+ " [create_local ~len x] is like [create]. It allocates the array on the local\n \
89
+ \ stack. The array's elements are still global. " ]
90
+ [@@ layout_poly]
91
+
92
+ external magic_create_uninitialized
93
+ : ('a : any_non_null ).
94
+ len:int -> ('a array [@ local_opt])
95
+ = " %makearray_dynamic_uninit"
96
+ [@@ ocaml.doc
97
+ " [magic_create_uninitialized ~len] creates an array of length [len] with\n \
98
+ \ uninitialized elements -- that is, they may contain arbitrary, \
99
+ nondeterministic\n \
100
+ \ 'a values. This can be significantly faster than using [create].\n\n \
101
+ \ [magic_create_uninitialized] can only be used for GC-ignorable arrays not\n \
102
+ \ involving tagged immediates and arrays of elements with unboxed number \
103
+ layout.\n \
104
+ \ The compiler rejects attempts to use [magic_create_uninitialized] to \
105
+ produce\n \
106
+ \ e.g. an [('a : value) array].\n\n \
107
+ \ [magic_create_uninitialized] can break abstraction boundaries and type \
108
+ safety\n \
109
+ \ (e.g. by creating phony witnesses to type equality) and so should be \
110
+ used with\n \
111
+ \ caution. " ]
112
+ [@@ layout_poly]
70
113
71
114
(* * [create_float_uninitialized ~len] creates a float array of length [len] with
72
115
uninitialized elements -- that is, they may contain arbitrary, nondeterministic
@@ -116,6 +159,13 @@ module Definitions = struct
116
159
types. The unsafe versions do not bound-check the arguments. *)
117
160
include Blit. S1 with type 'a t := 'a t
118
161
162
+ val% template foldi_right
163
+ : 'a t @ local
164
+ -> init:'acc @ m
165
+ -> f:(int -> 'a -> 'acc @ m -> 'acc @ m)
166
+ -> 'acc @ m
167
+ [@@ alloc a @ m = (stack_local, heap_global)]
168
+
119
169
(* * [folding_map] is a version of [map] that threads an accumulator through calls to
120
170
[f]. *)
121
171
val folding_map : 'a t -> init :'acc -> f :local_ ('acc -> 'a -> 'acc * 'b ) -> 'b t
@@ -139,7 +189,12 @@ module Definitions = struct
139
189
(* * [Array.fold_right f a ~init] computes
140
190
[f a.(0) (f a.(1) ( ... (f a.(n-1) init) ...))], where [n] is the length of the
141
191
array [a]. *)
142
- val fold_right : 'a t -> f :local_ ('a -> 'acc -> 'acc ) -> init :'acc -> 'acc
192
+ val% template fold_right
193
+ : 'a t @ m
194
+ -> f:local_ ('a @ m -> 'acc -> 'acc)
195
+ -> init:'acc
196
+ -> 'acc
197
+ [@@ mode m = (uncontended, shared)]
143
198
144
199
(* * All sort functions in this module sort in increasing order by default. *)
145
200
@@ -309,7 +364,7 @@ module type Array = sig @@ portable
309
364
include Definitions
310
365
end
311
366
312
- include Public with type 'a t = 'a array (* * @inline *)
367
+ include Public with type ('a : any_non_null ) t = 'a array (* * @inline *)
313
368
314
369
(* */**)
315
370
0 commit comments