sig
  module type S =
    sig
      type key
      type !'a t
      val create : int -> 'Ephemeron.S.t
      val clear : 'Ephemeron.S.t -> unit
      val reset : 'Ephemeron.S.t -> unit
      val copy : 'Ephemeron.S.t -> 'Ephemeron.S.t
      val add : 'Ephemeron.S.t -> Ephemeron.S.key -> '-> unit
      val remove : 'Ephemeron.S.t -> Ephemeron.S.key -> unit
      val find : 'Ephemeron.S.t -> Ephemeron.S.key -> 'a
      val find_opt : 'Ephemeron.S.t -> Ephemeron.S.key -> 'a option
      val find_all : 'Ephemeron.S.t -> Ephemeron.S.key -> 'a list
      val replace : 'Ephemeron.S.t -> Ephemeron.S.key -> '-> unit
      val mem : 'Ephemeron.S.t -> Ephemeron.S.key -> bool
      val iter : (Ephemeron.S.key -> '-> unit) -> 'Ephemeron.S.t -> unit
      val filter_map_inplace :
        (Ephemeron.S.key -> '-> 'a option) -> 'Ephemeron.S.t -> unit
      val fold :
        (Ephemeron.S.key -> '-> '-> 'b) -> 'Ephemeron.S.t -> '-> 'b
      val length : 'Ephemeron.S.t -> int
      val stats : 'Ephemeron.S.t -> Stdlib.Hashtbl.statistics
      val to_seq : 'Ephemeron.S.t -> (Ephemeron.S.key * 'a) Stdlib.Seq.t
      val to_seq_keys : 'Ephemeron.S.t -> Ephemeron.S.key Stdlib.Seq.t
      val to_seq_values : 'Ephemeron.S.t -> 'Stdlib.Seq.t
      val add_seq :
        'Ephemeron.S.t -> (Ephemeron.S.key * 'a) Stdlib.Seq.t -> unit
      val replace_seq :
        'Ephemeron.S.t -> (Ephemeron.S.key * 'a) Stdlib.Seq.t -> unit
      val of_seq : (Ephemeron.S.key * 'a) Stdlib.Seq.t -> 'Ephemeron.S.t
      val clean : 'Ephemeron.S.t -> unit
      val stats_alive : 'Ephemeron.S.t -> Stdlib.Hashtbl.statistics
    end
  module type SeededS =
    sig
      type key
      type !'a t
      val create : ?random:bool -> int -> 'Ephemeron.SeededS.t
      val clear : 'Ephemeron.SeededS.t -> unit
      val reset : 'Ephemeron.SeededS.t -> unit
      val copy : 'Ephemeron.SeededS.t -> 'Ephemeron.SeededS.t
      val add : 'Ephemeron.SeededS.t -> Ephemeron.SeededS.key -> '-> unit
      val remove : 'Ephemeron.SeededS.t -> Ephemeron.SeededS.key -> unit
      val find : 'Ephemeron.SeededS.t -> Ephemeron.SeededS.key -> 'a
      val find_opt :
        'Ephemeron.SeededS.t -> Ephemeron.SeededS.key -> 'a option
      val find_all :
        'Ephemeron.SeededS.t -> Ephemeron.SeededS.key -> 'a list
      val replace :
        'Ephemeron.SeededS.t -> Ephemeron.SeededS.key -> '-> unit
      val mem : 'Ephemeron.SeededS.t -> Ephemeron.SeededS.key -> bool
      val iter :
        (Ephemeron.SeededS.key -> '-> unit) ->
        'Ephemeron.SeededS.t -> unit
      val filter_map_inplace :
        (Ephemeron.SeededS.key -> '-> 'a option) ->
        'Ephemeron.SeededS.t -> unit
      val fold :
        (Ephemeron.SeededS.key -> '-> '-> 'b) ->
        'Ephemeron.SeededS.t -> '-> 'b
      val length : 'Ephemeron.SeededS.t -> int
      val stats : 'Ephemeron.SeededS.t -> Stdlib.Hashtbl.statistics
      val to_seq :
        'Ephemeron.SeededS.t -> (Ephemeron.SeededS.key * 'a) Stdlib.Seq.t
      val to_seq_keys :
        'Ephemeron.SeededS.t -> Ephemeron.SeededS.key Stdlib.Seq.t
      val to_seq_values : 'Ephemeron.SeededS.t -> 'Stdlib.Seq.t
      val add_seq :
        'Ephemeron.SeededS.t ->
        (Ephemeron.SeededS.key * 'a) Stdlib.Seq.t -> unit
      val replace_seq :
        'Ephemeron.SeededS.t ->
        (Ephemeron.SeededS.key * 'a) Stdlib.Seq.t -> unit
      val of_seq :
        (Ephemeron.SeededS.key * 'a) Stdlib.Seq.t -> 'Ephemeron.SeededS.t
      val clean : 'Ephemeron.SeededS.t -> unit
      val stats_alive : 'Ephemeron.SeededS.t -> Stdlib.Hashtbl.statistics
    end
  module K1 :
    sig
      type ('k, 'd) t
      val create : unit -> ('k, 'd) Ephemeron.K1.t
      val get_key : ('k, 'd) Ephemeron.K1.t -> 'k option
      val get_key_copy : ('k, 'd) Ephemeron.K1.t -> 'k option
      val set_key : ('k, 'd) Ephemeron.K1.t -> '-> unit
      val unset_key : ('k, 'd) Ephemeron.K1.t -> unit
      val check_key : ('k, 'd) Ephemeron.K1.t -> bool
      val blit_key :
        ('k, 'a) Ephemeron.K1.t -> ('k, 'b) Ephemeron.K1.t -> unit
      val get_data : ('k, 'd) Ephemeron.K1.t -> 'd option
      val get_data_copy : ('k, 'd) Ephemeron.K1.t -> 'd option
      val set_data : ('k, 'd) Ephemeron.K1.t -> '-> unit
      val unset_data : ('k, 'd) Ephemeron.K1.t -> unit
      val check_data : ('k, 'd) Ephemeron.K1.t -> bool
      val blit_data :
        ('a, 'd) Ephemeron.K1.t -> ('b, 'd) Ephemeron.K1.t -> unit
      val make : '-> '-> ('k, 'd) Ephemeron.K1.t
      val query : ('k, 'd) Ephemeron.K1.t -> '-> 'd option
      module Make :
        functor (H : Hashtbl.HashedType->
          sig
            type key = H.t
            type !'a t
            val create : int -> 'a t
            val clear : 'a t -> unit
            val reset : 'a t -> unit
            val copy : 'a t -> 'a t
            val add : 'a t -> key -> '-> unit
            val remove : 'a t -> key -> unit
            val find : 'a t -> key -> 'a
            val find_opt : 'a t -> key -> 'a option
            val find_all : 'a t -> key -> 'a list
            val replace : 'a t -> key -> '-> unit
            val mem : 'a t -> key -> bool
            val iter : (key -> '-> unit) -> 'a t -> unit
            val filter_map_inplace : (key -> '-> 'a option) -> 'a t -> unit
            val fold : (key -> '-> '-> 'b) -> 'a t -> '-> 'b
            val length : 'a t -> int
            val stats : 'a t -> Hashtbl.statistics
            val to_seq : 'a t -> (key * 'a) Seq.t
            val to_seq_keys : 'a t -> key Seq.t
            val to_seq_values : 'a t -> 'Seq.t
            val add_seq : 'a t -> (key * 'a) Seq.t -> unit
            val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
            val of_seq : (key * 'a) Seq.t -> 'a t
            val clean : 'a t -> unit
            val stats_alive : 'a t -> Hashtbl.statistics
          end
      module MakeSeeded :
        functor (H : Hashtbl.SeededHashedType->
          sig
            type key = H.t
            type !'a t
            val create : ?random:bool -> int -> 'a t
            val clear : 'a t -> unit
            val reset : 'a t -> unit
            val copy : 'a t -> 'a t
            val add : 'a t -> key -> '-> unit
            val remove : 'a t -> key -> unit
            val find : 'a t -> key -> 'a
            val find_opt : 'a t -> key -> 'a option
            val find_all : 'a t -> key -> 'a list
            val replace : 'a t -> key -> '-> unit
            val mem : 'a t -> key -> bool
            val iter : (key -> '-> unit) -> 'a t -> unit
            val filter_map_inplace : (key -> '-> 'a option) -> 'a t -> unit
            val fold : (key -> '-> '-> 'b) -> 'a t -> '-> 'b
            val length : 'a t -> int
            val stats : 'a t -> Hashtbl.statistics
            val to_seq : 'a t -> (key * 'a) Seq.t
            val to_seq_keys : 'a t -> key Seq.t
            val to_seq_values : 'a t -> 'Seq.t
            val add_seq : 'a t -> (key * 'a) Seq.t -> unit
            val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
            val of_seq : (key * 'a) Seq.t -> 'a t
            val clean : 'a t -> unit
            val stats_alive : 'a t -> Hashtbl.statistics
          end
      module Bucket :
        sig
          type ('k, 'd) t
          val make : unit -> ('k, 'd) Ephemeron.K1.Bucket.t
          val add : ('k, 'd) Ephemeron.K1.Bucket.t -> '-> '-> unit
          val remove : ('k, 'd) Ephemeron.K1.Bucket.t -> '-> unit
          val find : ('k, 'd) Ephemeron.K1.Bucket.t -> '-> 'd option
          val length : ('k, 'd) Ephemeron.K1.Bucket.t -> int
          val clear : ('k, 'd) Ephemeron.K1.Bucket.t -> unit
        end
    end
  module K2 :
    sig
      type ('k1, 'k2, 'd) t
      val create : unit -> ('k1, 'k2, 'd) Ephemeron.K2.t
      val get_key1 : ('k1, 'k2, 'd) Ephemeron.K2.t -> 'k1 option
      val get_key1_copy : ('k1, 'k2, 'd) Ephemeron.K2.t -> 'k1 option
      val set_key1 : ('k1, 'k2, 'd) Ephemeron.K2.t -> 'k1 -> unit
      val unset_key1 : ('k1, 'k2, 'd) Ephemeron.K2.t -> unit
      val check_key1 : ('k1, 'k2, 'd) Ephemeron.K2.t -> bool
      val get_key2 : ('k1, 'k2, 'd) Ephemeron.K2.t -> 'k2 option
      val get_key2_copy : ('k1, 'k2, 'd) Ephemeron.K2.t -> 'k2 option
      val set_key2 : ('k1, 'k2, 'd) Ephemeron.K2.t -> 'k2 -> unit
      val unset_key2 : ('k1, 'k2, 'd) Ephemeron.K2.t -> unit
      val check_key2 : ('k1, 'k2, 'd) Ephemeron.K2.t -> bool
      val blit_key1 :
        ('k1, 'a, 'b) Ephemeron.K2.t -> ('k1, 'c, 'd) Ephemeron.K2.t -> unit
      val blit_key2 :
        ('a, 'k2, 'b) Ephemeron.K2.t -> ('c, 'k2, 'd) Ephemeron.K2.t -> unit
      val blit_key12 :
        ('k1, 'k2, 'a) Ephemeron.K2.t ->
        ('k1, 'k2, 'b) Ephemeron.K2.t -> unit
      val get_data : ('k1, 'k2, 'd) Ephemeron.K2.t -> 'd option
      val get_data_copy : ('k1, 'k2, 'd) Ephemeron.K2.t -> 'd option
      val set_data : ('k1, 'k2, 'd) Ephemeron.K2.t -> '-> unit
      val unset_data : ('k1, 'k2, 'd) Ephemeron.K2.t -> unit
      val check_data : ('k1, 'k2, 'd) Ephemeron.K2.t -> bool
      val blit_data :
        ('k1, 'k2, 'd) Ephemeron.K2.t ->
        ('k1, 'k2, 'd) Ephemeron.K2.t -> unit
      val make : 'k1 -> 'k2 -> '-> ('k1, 'k2, 'd) Ephemeron.K2.t
      val query : ('k1, 'k2, 'd) Ephemeron.K2.t -> 'k1 -> 'k2 -> 'd option
      module Make :
        functor (H1 : Hashtbl.HashedType) (H2 : Hashtbl.HashedType->
          sig
            type key = H1.t * H2.t
            type !'a t
            val create : int -> 'a t
            val clear : 'a t -> unit
            val reset : 'a t -> unit
            val copy : 'a t -> 'a t
            val add : 'a t -> key -> '-> unit
            val remove : 'a t -> key -> unit
            val find : 'a t -> key -> 'a
            val find_opt : 'a t -> key -> 'a option
            val find_all : 'a t -> key -> 'a list
            val replace : 'a t -> key -> '-> unit
            val mem : 'a t -> key -> bool
            val iter : (key -> '-> unit) -> 'a t -> unit
            val filter_map_inplace : (key -> '-> 'a option) -> 'a t -> unit
            val fold : (key -> '-> '-> 'b) -> 'a t -> '-> 'b
            val length : 'a t -> int
            val stats : 'a t -> Hashtbl.statistics
            val to_seq : 'a t -> (key * 'a) Seq.t
            val to_seq_keys : 'a t -> key Seq.t
            val to_seq_values : 'a t -> 'Seq.t
            val add_seq : 'a t -> (key * 'a) Seq.t -> unit
            val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
            val of_seq : (key * 'a) Seq.t -> 'a t
            val clean : 'a t -> unit
            val stats_alive : 'a t -> Hashtbl.statistics
          end
      module MakeSeeded :
        functor (H1 : Hashtbl.SeededHashedType)
          (H2 : Hashtbl.SeededHashedType->
          sig
            type key = H1.t * H2.t
            type !'a t
            val create : ?random:bool -> int -> 'a t
            val clear : 'a t -> unit
            val reset : 'a t -> unit
            val copy : 'a t -> 'a t
            val add : 'a t -> key -> '-> unit
            val remove : 'a t -> key -> unit
            val find : 'a t -> key -> 'a
            val find_opt : 'a t -> key -> 'a option
            val find_all : 'a t -> key -> 'a list
            val replace : 'a t -> key -> '-> unit
            val mem : 'a t -> key -> bool
            val iter : (key -> '-> unit) -> 'a t -> unit
            val filter_map_inplace : (key -> '-> 'a option) -> 'a t -> unit
            val fold : (key -> '-> '-> 'b) -> 'a t -> '-> 'b
            val length : 'a t -> int
            val stats : 'a t -> Hashtbl.statistics
            val to_seq : 'a t -> (key * 'a) Seq.t
            val to_seq_keys : 'a t -> key Seq.t
            val to_seq_values : 'a t -> 'Seq.t
            val add_seq : 'a t -> (key * 'a) Seq.t -> unit
            val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
            val of_seq : (key * 'a) Seq.t -> 'a t
            val clean : 'a t -> unit
            val stats_alive : 'a t -> Hashtbl.statistics
          end
      module Bucket :
        sig
          type ('k1, 'k2, 'd) t
          val make : unit -> ('k1, 'k2, 'd) Ephemeron.K2.Bucket.t
          val add :
            ('k1, 'k2, 'd) Ephemeron.K2.Bucket.t -> 'k1 -> 'k2 -> '-> unit
          val remove :
            ('k1, 'k2, 'd) Ephemeron.K2.Bucket.t -> 'k1 -> 'k2 -> unit
          val find :
            ('k1, 'k2, 'd) Ephemeron.K2.Bucket.t -> 'k1 -> 'k2 -> 'd option
          val length : ('k1, 'k2, 'd) Ephemeron.K2.Bucket.t -> int
          val clear : ('k1, 'k2, 'd) Ephemeron.K2.Bucket.t -> unit
        end
    end
  module Kn :
    sig
      type ('k, 'd) t
      val create : int -> ('k, 'd) Ephemeron.Kn.t
      val get_key : ('k, 'd) Ephemeron.Kn.t -> int -> 'k option
      val get_key_copy : ('k, 'd) Ephemeron.Kn.t -> int -> 'k option
      val set_key : ('k, 'd) Ephemeron.Kn.t -> int -> '-> unit
      val unset_key : ('k, 'd) Ephemeron.Kn.t -> int -> unit
      val check_key : ('k, 'd) Ephemeron.Kn.t -> int -> bool
      val blit_key :
        ('k, 'a) Ephemeron.Kn.t ->
        int -> ('k, 'b) Ephemeron.Kn.t -> int -> int -> unit
      val get_data : ('k, 'd) Ephemeron.Kn.t -> 'd option
      val get_data_copy : ('k, 'd) Ephemeron.Kn.t -> 'd option
      val set_data : ('k, 'd) Ephemeron.Kn.t -> '-> unit
      val unset_data : ('k, 'd) Ephemeron.Kn.t -> unit
      val check_data : ('k, 'd) Ephemeron.Kn.t -> bool
      val blit_data :
        ('k, 'd) Ephemeron.Kn.t -> ('k, 'd) Ephemeron.Kn.t -> unit
      val make : 'k array -> '-> ('k, 'd) Ephemeron.Kn.t
      val query : ('k, 'd) Ephemeron.Kn.t -> 'k array -> 'd option
      module Make :
        functor (H : Hashtbl.HashedType->
          sig
            type key = H.t array
            type !'a t
            val create : int -> 'a t
            val clear : 'a t -> unit
            val reset : 'a t -> unit
            val copy : 'a t -> 'a t
            val add : 'a t -> key -> '-> unit
            val remove : 'a t -> key -> unit
            val find : 'a t -> key -> 'a
            val find_opt : 'a t -> key -> 'a option
            val find_all : 'a t -> key -> 'a list
            val replace : 'a t -> key -> '-> unit
            val mem : 'a t -> key -> bool
            val iter : (key -> '-> unit) -> 'a t -> unit
            val filter_map_inplace : (key -> '-> 'a option) -> 'a t -> unit
            val fold : (key -> '-> '-> 'b) -> 'a t -> '-> 'b
            val length : 'a t -> int
            val stats : 'a t -> Hashtbl.statistics
            val to_seq : 'a t -> (key * 'a) Seq.t
            val to_seq_keys : 'a t -> key Seq.t
            val to_seq_values : 'a t -> 'Seq.t
            val add_seq : 'a t -> (key * 'a) Seq.t -> unit
            val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
            val of_seq : (key * 'a) Seq.t -> 'a t
            val clean : 'a t -> unit
            val stats_alive : 'a t -> Hashtbl.statistics
          end
      module MakeSeeded :
        functor (H : Hashtbl.SeededHashedType->
          sig
            type key = H.t array
            type !'a t
            val create : ?random:bool -> int -> 'a t
            val clear : 'a t -> unit
            val reset : 'a t -> unit
            val copy : 'a t -> 'a t
            val add : 'a t -> key -> '-> unit
            val remove : 'a t -> key -> unit
            val find : 'a t -> key -> 'a
            val find_opt : 'a t -> key -> 'a option
            val find_all : 'a t -> key -> 'a list
            val replace : 'a t -> key -> '-> unit
            val mem : 'a t -> key -> bool
            val iter : (key -> '-> unit) -> 'a t -> unit
            val filter_map_inplace : (key -> '-> 'a option) -> 'a t -> unit
            val fold : (key -> '-> '-> 'b) -> 'a t -> '-> 'b
            val length : 'a t -> int
            val stats : 'a t -> Hashtbl.statistics
            val to_seq : 'a t -> (key * 'a) Seq.t
            val to_seq_keys : 'a t -> key Seq.t
            val to_seq_values : 'a t -> 'Seq.t
            val add_seq : 'a t -> (key * 'a) Seq.t -> unit
            val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
            val of_seq : (key * 'a) Seq.t -> 'a t
            val clean : 'a t -> unit
            val stats_alive : 'a t -> Hashtbl.statistics
          end
      module Bucket :
        sig
          type ('k, 'd) t
          val make : unit -> ('k, 'd) Ephemeron.Kn.Bucket.t
          val add : ('k, 'd) Ephemeron.Kn.Bucket.t -> 'k array -> '-> unit
          val remove : ('k, 'd) Ephemeron.Kn.Bucket.t -> 'k array -> unit
          val find : ('k, 'd) Ephemeron.Kn.Bucket.t -> 'k array -> 'd option
          val length : ('k, 'd) Ephemeron.Kn.Bucket.t -> int
          val clear : ('k, 'd) Ephemeron.Kn.Bucket.t -> unit
        end
    end
  module GenHashTable :
    sig
      type equal = ETrue | EFalse | EDead
      module MakeSeeded :
        functor
          (H : sig
                 type t
                 type 'a container
                 val hash : int -> Ephemeron.GenHashTable.MakeSeeded.t -> int
                 val equal :
                   'Ephemeron.GenHashTable.MakeSeeded.container ->
                   Ephemeron.GenHashTable.MakeSeeded.t ->
                   Ephemeron.GenHashTable.equal
                 val create :
                   Ephemeron.GenHashTable.MakeSeeded.t ->
                   '-> 'Ephemeron.GenHashTable.MakeSeeded.container
                 val get_key :
                   'Ephemeron.GenHashTable.MakeSeeded.container ->
                   Ephemeron.GenHashTable.MakeSeeded.t option
                 val get_data :
                   'Ephemeron.GenHashTable.MakeSeeded.container ->
                   'a option
                 val set_key_data :
                   'Ephemeron.GenHashTable.MakeSeeded.container ->
                   Ephemeron.GenHashTable.MakeSeeded.t -> '-> unit
                 val check_key :
                   'Ephemeron.GenHashTable.MakeSeeded.container -> bool
               end)
          ->
          sig
            type key = H.t
            type !'a t
            val create : ?random:bool -> int -> 'a t
            val clear : 'a t -> unit
            val reset : 'a t -> unit
            val copy : 'a t -> 'a t
            val add : 'a t -> key -> '-> unit
            val remove : 'a t -> key -> unit
            val find : 'a t -> key -> 'a
            val find_opt : 'a t -> key -> 'a option
            val find_all : 'a t -> key -> 'a list
            val replace : 'a t -> key -> '-> unit
            val mem : 'a t -> key -> bool
            val iter : (key -> '-> unit) -> 'a t -> unit
            val filter_map_inplace : (key -> '-> 'a option) -> 'a t -> unit
            val fold : (key -> '-> '-> 'b) -> 'a t -> '-> 'b
            val length : 'a t -> int
            val stats : 'a t -> Hashtbl.statistics
            val to_seq : 'a t -> (key * 'a) Seq.t
            val to_seq_keys : 'a t -> key Seq.t
            val to_seq_values : 'a t -> 'Seq.t
            val add_seq : 'a t -> (key * 'a) Seq.t -> unit
            val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
            val of_seq : (key * 'a) Seq.t -> 'a t
            val clean : 'a t -> unit
            val stats_alive : 'a t -> Hashtbl.statistics
          end
    end
end