module None:S
None is an inefficient implementation of pools that uses OCaml's memory allocator
to allocate each object. It is useful for debugging Obj_array, as well as
debugging client code that may be misusing pointers.module Slots:Tuple_type.Slots
module Slot:Tuple_type.Slot
module Pointer:sig..end
type 'slots t
'slots will look like ('a1, ..., 'an) Slots.tn, and the
pool holds tuples of type 'a1 * ... * 'an.include Invariant.S1
val pointer_is_valid : 'slots t -> 'slots Pointer.t -> boolpointer_is_valid t pointer returns true iff pointer points to a live tuple in
t, i.e. pointer is not null, not free, and is in the range of t.
A pointer might not be in the range of a pool if it comes from another pool for
example. In this case unsafe_get/set functions would cause a segfault.
val id_of_pointer : 'slots t ->
'slots Pointer.t -> Pointer.Id.tid_of_pointer t pointer returns an id that is unique for the lifetime of
pointer's tuple. When the tuple is freed, the id is no longer valid, and
pointer_of_id_exn will fail on it. Pointer.null () has a distinct id from all
non-null pointers.val pointer_of_id_exn : 'slots t ->
Pointer.Id.t -> 'slots Pointer.tpointer_of_id_exn t id returns the pointer corresponding to id. It fails if the
tuple corresponding to id was already freed.
pointer_of_id_exn_is_supported says whether the implementation supports
pointer_of_id_exn; if not, it will always raise. We can not use the usual idiom
of making pointer_of_id_exn be an Or_error.t due to problems with the value
restriction.
val pointer_of_id_exn_is_supported : boolval create : ('tuple, 'a) Slots.t ->
capacity:int -> dummy:'tuple -> ('tuple, 'a) Slots.t tcreate slots ~capacity ~dummy creates an empty pool that can hold up to capacity
N-tuples. The slots of dummy are stored in free tuples.val capacity : 'a t -> intcapacity returns the maximum number of tuples that the pool can hold.val length : 'a t -> intlength returns the number of tuples currently in the pool.
0 <= length t <= capacity t
val grow : ?capacity:int -> 'a t -> 'a tgrow t ~capacity returns a new pool t' with the supplied capacity. The new pool
is to be used as a replacement for t. All live tuples in t are now live in
t', and valid pointers to tuples in t are now valid pointers to the identical
tuple in t'. It is an error to use t after calling grow t.
grow raises if the supplied capacity isn't larger than capacity t.
val is_full : 'a t -> boolis_full t returns true if no more tuples can be allocated in t.val free : 'slots t -> 'slots Pointer.t -> unitfree t pointer frees the tuple pointed to by pointer from t.val new1 : 'a0 Slots.t1 t -> 'a0 -> 'a0 Slots.t1 Pointer.tnew<N> t a0 ... a<N-1> returns a new tuple from the pool, with the tuple's
slots initialized to a0 ... a<N-1>. new raises if is_full t.val new2 : ('a0, 'a1) Slots.t2 t ->
'a0 -> 'a1 -> ('a0, 'a1) Slots.t2 Pointer.tval new3 : ('a0, 'a1, 'a2) Slots.t3 t ->
'a0 -> 'a1 -> 'a2 -> ('a0, 'a1, 'a2) Slots.t3 Pointer.tval new4 : ('a0, 'a1, 'a2, 'a3) Slots.t4 t ->
'a0 ->
'a1 -> 'a2 -> 'a3 -> ('a0, 'a1, 'a2, 'a3) Slots.t4 Pointer.tval new5 : ('a0, 'a1, 'a2, 'a3, 'a4) Slots.t5 t ->
'a0 ->
'a1 ->
'a2 -> 'a3 -> 'a4 -> ('a0, 'a1, 'a2, 'a3, 'a4) Slots.t5 Pointer.tval new6 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5) Slots.t6 t ->
'a0 ->
'a1 ->
'a2 ->
'a3 ->
'a4 -> 'a5 -> ('a0, 'a1, 'a2, 'a3, 'a4, 'a5) Slots.t6 Pointer.tval new7 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6) Slots.t7 t ->
'a0 ->
'a1 ->
'a2 ->
'a3 ->
'a4 ->
'a5 ->
'a6 -> ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6) Slots.t7 Pointer.tval new8 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7) Slots.t8 t ->
'a0 ->
'a1 ->
'a2 ->
'a3 ->
'a4 ->
'a5 ->
'a6 ->
'a7 ->
('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7) Slots.t8 Pointer.tval new9 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8) Slots.t9 t ->
'a0 ->
'a1 ->
'a2 ->
'a3 ->
'a4 ->
'a5 ->
'a6 ->
'a7 ->
'a8 ->
('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8) Slots.t9 Pointer.tval get_tuple : ('tuple, 'a) Slots.t t ->
('tuple, 'a) Slots.t Pointer.t -> 'tupleget_tuple t pointer allocates an OCaml tuple isomorphic to the pool t's tuple
pointed to by pointer.val get : ('a, 'variant) Slots.t t ->
('a, 'variant) Slots.t Pointer.t ->
('variant, 'slot) Slot.t -> 'slotget t pointer slot gets slot of the tuple pointed to by pointer in
pool t. In the usual way with manual memory management, it is an error to refer
to a pointer that has been freed. It is also an error to use a pointer with any
pool other than the one the pointer was new'd from or grown to.
unsafe_get is like get, but skips bounds checking, and can thus segfault.
unsafe_get is comparable in speed to get for immediate values, and 5%-10% faster
for pointers. Since the difference is so small, one should as usual be very
convinced of the speed benefit before using these and introducing the possibility of
segfaults.
val unsafe_get : ('a, 'variant) Slots.t t ->
('a, 'variant) Slots.t Pointer.t ->
('variant, 'slot) Slot.t -> 'slotval set : ('a, 'variant) Slots.t t ->
('a, 'variant) Slots.t Pointer.t ->
('variant, 'slot) Slot.t -> 'slot -> unitset t pointer slot a sets to a the slot of the tuple pointed to by pointer
in pool t. In the usual way with manual memory management, it is an error to
refer to a pointer that has been freed. It is also an error to use a pointer with
any pool other than the one the pointer was new'd from or grown to.
unsafe_set is like set, but skips bounds checking, and can thus segfault.
val unsafe_set : ('a, 'variant) Slots.t t ->
('a, 'variant) Slots.t Pointer.t ->
('variant, 'slot) Slot.t -> 'slot -> unitval sexp_of_t : ('slots -> Sexplib.Sexp.t) -> 'slots t -> Sexplib.Sexp.tpointer_is_valid t pointer returns true iff pointer points to a live tuple in
t, i.e. pointer is not null, not free, and is in the range of t.
A pointer might not be in the range of a pool if it comes from another pool for
example. In this case unsafe_get/set functions would cause a segfault.
id_of_pointer t pointer returns an id that is unique for the lifetime of
pointer's tuple. When the tuple is freed, the id is no longer valid, and
pointer_of_id_exn will fail on it. Pointer.null () has a distinct id from all
non-null pointers.
pointer_of_id_exn t id returns the pointer corresponding to id. It fails if the
tuple corresponding to id was already freed.
pointer_of_id_exn_is_supported says whether the implementation supports
pointer_of_id_exn; if not, it will always raise. We can not use the usual idiom
of making pointer_of_id_exn be an Or_error.t due to problems with the value
restriction.
create slots ~capacity ~dummy creates an empty pool that can hold up to capacity
N-tuples. The slots of dummy are stored in free tuples.
capacity returns the maximum number of tuples that the pool can hold.
length returns the number of tuples currently in the pool.
0 <= length t <= capacity t
grow t ~capacity returns a new pool t' with the supplied capacity. The new pool
is to be used as a replacement for t. All live tuples in t are now live in
t', and valid pointers to tuples in t are now valid pointers to the identical
tuple in t'. It is an error to use t after calling grow t.
grow raises if the supplied capacity isn't larger than capacity t.
default is 2 * capacity t
is_full t returns true if no more tuples can be allocated in t.
free t pointer frees the tuple pointed to by pointer from t.
new<N> t a0 ... a<N-1> returns a new tuple from the pool, with the tuple's
slots initialized to a0 ... a<N-1>. new raises if is_full t.
get_tuple t pointer allocates an OCaml tuple isomorphic to the pool t's tuple
pointed to by pointer.
get t pointer slot gets slot of the tuple pointed to by pointer in
pool t. In the usual way with manual memory management, it is an error to refer
to a pointer that has been freed. It is also an error to use a pointer with any
pool other than the one the pointer was new'd from or grown to.
unsafe_get is like get, but skips bounds checking, and can thus segfault.
unsafe_get is comparable in speed to get for immediate values, and 5%-10% faster
for pointers. Since the difference is so small, one should as usual be very
convinced of the speed benefit before using these and introducing the possibility of
segfaults.
set t pointer slot a sets to a the slot of the tuple pointed to by pointer
in pool t. In the usual way with manual memory management, it is an error to
refer to a pointer that has been freed. It is also an error to use a pointer with
any pool other than the one the pointer was new'd from or grown to.
unsafe_set is like set, but skips bounds checking, and can thus segfault.