module type S =sig..end
S is the module type for a pool.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.  create raises if
      capacity < 0.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. The tuple gets copied, but its slots do not.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.
      set t pointer slot a sets to a the slot of the tuple pointed to by pointer
      in pool t.
      In get and set, 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.  These errors will lead to undefined behavior, but will
      not segfault.
      unsafe_get is comparable in speed to get for immediate values, and 5%-10% faster
      for pointers.
      unsafe_get and unsafe_set skip bounds checking, and can thus segfault.
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 -> unitval 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.  create raises if
      capacity < 0.
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. The tuple gets copied, but its slots do not.
get t pointer slot gets slot of the tuple pointed to by pointer in
      pool t.
      set t pointer slot a sets to a the slot of the tuple pointed to by pointer
      in pool t.
      In get and set, 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.  These errors will lead to undefined behavior, but will
      not segfault.
      unsafe_get is comparable in speed to get for immediate values, and 5%-10% faster
      for pointers.
      unsafe_get and unsafe_set skip bounds checking, and can thus segfault.