#include <stdint.h>
#include <stddef.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>

#define restrict

#ifdef __has_builtin
#define DPA__U__has_builtin(X) __has_builtin(X)
#else
#define DPA__U__has_builtin(X) 0
#endif

#if __STDC_VERSION__ >= 202311
#define dpa_u_reproducible [[reproducible, gnu::pure]]
#elif defined(__GNUC__) || defined(__llvm__)
#define dpa_u_reproducible  __attribute__((pure))
#else
#define dpa_u_reproducible
#endif

#if __STDC_VERSION__ >= 202311
#define dpa_u_unsequenced [[unsequenced, gnu::const]]
#elif defined(__GNUC__) || defined(__llvm__)
#define dpa_u_unsequenced __attribute__((const))
#else
#define dpa_u_unsequenced
#endif

#define dpa__u_api
#define dpa__u_api_var

#if DPA__U__has_builtin(__builtin_unreachable)
#define dpa_u_unreachable(...) { __builtin_unreachable(); }
#elif DPA__U__has_builtin(__builtin_trap)
#define dpa_u_unreachable(...) { __builtin_trap(); }
#else
//#define dpa_u_unreachable(...) { abort(); }
#define dpa_u_unreachable(...) { exit(1); }
#endif

typedef unsigned dpa_u_bitmap_entry_t;

typedef struct dpa_u_optional_pointer {
  void* value;
  bool present;
} dpa_u_optional_pointer_t;

// This variable is to help with benchmarks
dpa__u_api_var extern long dpa_u_total_resize_time;

#if DPA__U__has_builtin(__builtin_popcountg)
#define dpa_u_count_bits __builtin_popcountg
#elif DPA__U__has_builtin(__builtin_popcountll)
#define dpa_u_count_bits __builtin_popcountll
#else
dpa_u_unsequenced dpa__u_api inline int dpa_u_count_bits(long long unsigned int x){
  int n = 0;
  for(unsigned i=0; i<sizeof(x)*CHAR_BIT; i++)
    if(x & (1llu<<i))
      n++;
  return n;
}
#endif

typedef struct dpa_u_set_pointer dpa_u_set_pointer_t;
struct dpa_u_set_pointer {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    uintptr_t*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
};
/**
 * Adds an entry to the set.
 * \returns 1 if the entry was already present, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_set_pointer_add(dpa_u_set_pointer_t* that, void* key);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_set_pointer_remove(dpa_u_set_pointer_t* that, void* key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_set_pointer_has(const dpa_u_set_pointer_t* that, void* key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_set_pointer_clear(dpa_u_set_pointer_t* that);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_set_pointer_count(const dpa_u_set_pointer_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_set_pointer_dump_hashmap_key_hashes(dpa_u_set_pointer_t* that);


typedef struct dpa_u_set_uc dpa_u_set_uc_t;
// For CHAR_BIT == 8, for a set containing one of 256 entries, we only need 256 bits.
// That'd be 32 bytes/chars (because 8 bits per char). For larger integer types, we need less entries.
// u8: 32 entries, u16: 16 entries, u32: 8 entries, u64: 4 entries, u128: 2 entries, u256: 1 entry
// This will not safe any space, but it may make the lookup more efficient. And 32 bytes, is not a lot.
// We round up the number of entres, in case of CHAR_BIT != 8. In that case, space will be wasted, but who's ever going to use such a platform anyway?
struct dpa_u_set_uc {
  dpa_u_bitmap_entry_t bitmask[(((size_t)1<<(sizeof(unsigned char)*CHAR_BIT))+(sizeof(dpa_u_bitmap_entry_t)*CHAR_BIT-1))/(sizeof(dpa_u_bitmap_entry_t)*CHAR_BIT)];
};
/**
 * Adds an entry to the set.
 * \returns 1 if the entry was already present, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_set_uc_add(dpa_u_set_uc_t* that, unsigned char key);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_set_uc_remove(dpa_u_set_uc_t* that, unsigned char key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_set_uc_has(const dpa_u_set_uc_t* that, unsigned char key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_set_uc_clear(dpa_u_set_uc_t* that);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_set_uc_count(const dpa_u_set_uc_t* that){
  size_t n = 0;
  const dpa_u_bitmap_entry_t*restrict const bitmask = that->bitmask;
  for(unsigned i=0; i<(((size_t)1<<(sizeof(unsigned char)*CHAR_BIT))+(sizeof(dpa_u_bitmap_entry_t)*CHAR_BIT-1))/(sizeof(dpa_u_bitmap_entry_t)*CHAR_BIT); i++)
    n += dpa_u_count_bits(bitmask[i]);
  return n;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_set_uc_dump_hashmap_key_hashes(dpa_u_set_uc_t* that);


typedef struct dpa_u_set_us dpa_u_set_us_t;
struct dpa_u_set_us {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    unsigned short*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
};
/**
 * Adds an entry to the set.
 * \returns 1 if the entry was already present, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_set_us_add(dpa_u_set_us_t* that, unsigned short key);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_set_us_remove(dpa_u_set_us_t* that, unsigned short key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_set_us_has(const dpa_u_set_us_t* that, unsigned short key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_set_us_clear(dpa_u_set_us_t* that);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_set_us_count(const dpa_u_set_us_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_set_us_dump_hashmap_key_hashes(dpa_u_set_us_t* that);


typedef struct dpa_u_set_u dpa_u_set_u_t;
struct dpa_u_set_u {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    unsigned*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
};
/**
 * Adds an entry to the set.
 * \returns 1 if the entry was already present, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_set_u_add(dpa_u_set_u_t* that, unsigned key);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_set_u_remove(dpa_u_set_u_t* that, unsigned key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_set_u_has(const dpa_u_set_u_t* that, unsigned key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_set_u_clear(dpa_u_set_u_t* that);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_set_u_count(const dpa_u_set_u_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_set_u_dump_hashmap_key_hashes(dpa_u_set_u_t* that);


typedef struct dpa_u_set_lu dpa_u_set_lu_t;
struct dpa_u_set_lu {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    unsigned long*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
};
/**
 * Adds an entry to the set.
 * \returns 1 if the entry was already present, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_set_lu_add(dpa_u_set_lu_t* that, unsigned long key);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_set_lu_remove(dpa_u_set_lu_t* that, unsigned long key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_set_lu_has(const dpa_u_set_lu_t* that, unsigned long key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_set_lu_clear(dpa_u_set_lu_t* that);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_set_lu_count(const dpa_u_set_lu_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_set_lu_dump_hashmap_key_hashes(dpa_u_set_lu_t* that);


typedef struct dpa_u_set_llu dpa_u_set_llu_t;
struct dpa_u_set_llu {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    unsigned long long*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
};
/**
 * Adds an entry to the set.
 * \returns 1 if the entry was already present, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_set_llu_add(dpa_u_set_llu_t* that, unsigned long long key);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_set_llu_remove(dpa_u_set_llu_t* that, unsigned long long key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_set_llu_has(const dpa_u_set_llu_t* that, unsigned long long key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_set_llu_clear(dpa_u_set_llu_t* that);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_set_llu_count(const dpa_u_set_llu_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_set_llu_dump_hashmap_key_hashes(dpa_u_set_llu_t* that);


typedef struct dpa_u_set_z dpa_u_set_z_t;
struct dpa_u_set_z {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    size_t*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
};
/**
 * Adds an entry to the set.
 * \returns 1 if the entry was already present, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_set_z_add(dpa_u_set_z_t* that, size_t key);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_set_z_remove(dpa_u_set_z_t* that, size_t key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_set_z_has(const dpa_u_set_z_t* that, size_t key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_set_z_clear(dpa_u_set_z_t* that);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_set_z_count(const dpa_u_set_z_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_set_z_dump_hashmap_key_hashes(dpa_u_set_z_t* that);


typedef struct dpa_u_set_u8 dpa_u_set_u8_t;
// For CHAR_BIT == 8, for a set containing one of 256 entries, we only need 256 bits.
// That'd be 32 bytes/chars (because 8 bits per char). For larger integer types, we need less entries.
// u8: 32 entries, u16: 16 entries, u32: 8 entries, u64: 4 entries, u128: 2 entries, u256: 1 entry
// This will not safe any space, but it may make the lookup more efficient. And 32 bytes, is not a lot.
// We round up the number of entres, in case of CHAR_BIT != 8. In that case, space will be wasted, but who's ever going to use such a platform anyway?
struct dpa_u_set_u8 {
  dpa_u_bitmap_entry_t bitmask[(((size_t)1<<(sizeof(uint8_t)*CHAR_BIT))+(sizeof(dpa_u_bitmap_entry_t)*CHAR_BIT-1))/(sizeof(dpa_u_bitmap_entry_t)*CHAR_BIT)];
};
/**
 * Adds an entry to the set.
 * \returns 1 if the entry was already present, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_set_u8_add(dpa_u_set_u8_t* that, uint8_t key);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_set_u8_remove(dpa_u_set_u8_t* that, uint8_t key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_set_u8_has(const dpa_u_set_u8_t* that, uint8_t key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_set_u8_clear(dpa_u_set_u8_t* that);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_set_u8_count(const dpa_u_set_u8_t* that){
  size_t n = 0;
  const dpa_u_bitmap_entry_t*restrict const bitmask = that->bitmask;
  for(unsigned i=0; i<(((size_t)1<<(sizeof(uint8_t)*CHAR_BIT))+(sizeof(dpa_u_bitmap_entry_t)*CHAR_BIT-1))/(sizeof(dpa_u_bitmap_entry_t)*CHAR_BIT); i++)
    n += dpa_u_count_bits(bitmask[i]);
  return n;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_set_u8_dump_hashmap_key_hashes(dpa_u_set_u8_t* that);


typedef struct dpa_u_set_u16 dpa_u_set_u16_t;
struct dpa_u_set_u16 {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    uint16_t*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
};
/**
 * Adds an entry to the set.
 * \returns 1 if the entry was already present, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_set_u16_add(dpa_u_set_u16_t* that, uint16_t key);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_set_u16_remove(dpa_u_set_u16_t* that, uint16_t key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_set_u16_has(const dpa_u_set_u16_t* that, uint16_t key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_set_u16_clear(dpa_u_set_u16_t* that);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_set_u16_count(const dpa_u_set_u16_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_set_u16_dump_hashmap_key_hashes(dpa_u_set_u16_t* that);


typedef struct dpa_u_set_u32 dpa_u_set_u32_t;
struct dpa_u_set_u32 {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    uint32_t*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
};
/**
 * Adds an entry to the set.
 * \returns 1 if the entry was already present, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_set_u32_add(dpa_u_set_u32_t* that, uint32_t key);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_set_u32_remove(dpa_u_set_u32_t* that, uint32_t key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_set_u32_has(const dpa_u_set_u32_t* that, uint32_t key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_set_u32_clear(dpa_u_set_u32_t* that);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_set_u32_count(const dpa_u_set_u32_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_set_u32_dump_hashmap_key_hashes(dpa_u_set_u32_t* that);


typedef struct dpa_u_set_u64 dpa_u_set_u64_t;
struct dpa_u_set_u64 {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    uint64_t*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
};
/**
 * Adds an entry to the set.
 * \returns 1 if the entry was already present, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_set_u64_add(dpa_u_set_u64_t* that, uint64_t key);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_set_u64_remove(dpa_u_set_u64_t* that, uint64_t key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_set_u64_has(const dpa_u_set_u64_t* that, uint64_t key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_set_u64_clear(dpa_u_set_u64_t* that);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_set_u64_count(const dpa_u_set_u64_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_set_u64_dump_hashmap_key_hashes(dpa_u_set_u64_t* that);


typedef struct dpa_u_map_pointer dpa_u_map_pointer_t;
struct dpa_u_map_pointer {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    uintptr_t*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
  void**restrict value_list;
};
/**
 * Sets an entry in the map and returns the existing one if one exists.
 * If there was none, the variable will remain unchanged.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_pointer_exchange(dpa_u_map_pointer_t* that, void* key, void** value);
/**
 * Sets an entry in the map.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_pointer_set(dpa_u_map_pointer_t* that, void* key, void* value);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_map_pointer_remove(dpa_u_map_pointer_t* that, void* key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_map_pointer_has(const dpa_u_map_pointer_t* that, void* key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_map_pointer_clear(dpa_u_map_pointer_t* that);
/**
 * Returns the entry.
 */
dpa_u_reproducible dpa__u_api dpa_u_optional_pointer_t dpa_u_map_pointer_get(const dpa_u_map_pointer_t* that, void* key);
/**
 * Removes and returns an entry.
 */
dpa__u_api dpa_u_optional_pointer_t dpa_u_map_pointer_get_and_remove(dpa_u_map_pointer_t* that, void* key);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_map_pointer_count(const dpa_u_map_pointer_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_map_pointer_dump_hashmap_key_hashes(dpa_u_map_pointer_t* that);


typedef struct dpa_u_map_uc dpa_u_map_uc_t;
struct dpa_u_map_uc {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    unsigned char*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
  void**restrict value_list;
};
/**
 * Sets an entry in the map and returns the existing one if one exists.
 * If there was none, the variable will remain unchanged.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_uc_exchange(dpa_u_map_uc_t* that, unsigned char key, void** value);
/**
 * Sets an entry in the map.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_uc_set(dpa_u_map_uc_t* that, unsigned char key, void* value);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_map_uc_remove(dpa_u_map_uc_t* that, unsigned char key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_map_uc_has(const dpa_u_map_uc_t* that, unsigned char key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_map_uc_clear(dpa_u_map_uc_t* that);
/**
 * Returns the entry.
 */
dpa_u_reproducible dpa__u_api dpa_u_optional_pointer_t dpa_u_map_uc_get(const dpa_u_map_uc_t* that, unsigned char key);
/**
 * Removes and returns an entry.
 */
dpa__u_api dpa_u_optional_pointer_t dpa_u_map_uc_get_and_remove(dpa_u_map_uc_t* that, unsigned char key);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_map_uc_count(const dpa_u_map_uc_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_map_uc_dump_hashmap_key_hashes(dpa_u_map_uc_t* that);


typedef struct dpa_u_map_us dpa_u_map_us_t;
struct dpa_u_map_us {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    unsigned short*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
  void**restrict value_list;
};
/**
 * Sets an entry in the map and returns the existing one if one exists.
 * If there was none, the variable will remain unchanged.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_us_exchange(dpa_u_map_us_t* that, unsigned short key, void** value);
/**
 * Sets an entry in the map.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_us_set(dpa_u_map_us_t* that, unsigned short key, void* value);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_map_us_remove(dpa_u_map_us_t* that, unsigned short key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_map_us_has(const dpa_u_map_us_t* that, unsigned short key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_map_us_clear(dpa_u_map_us_t* that);
/**
 * Returns the entry.
 */
dpa_u_reproducible dpa__u_api dpa_u_optional_pointer_t dpa_u_map_us_get(const dpa_u_map_us_t* that, unsigned short key);
/**
 * Removes and returns an entry.
 */
dpa__u_api dpa_u_optional_pointer_t dpa_u_map_us_get_and_remove(dpa_u_map_us_t* that, unsigned short key);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_map_us_count(const dpa_u_map_us_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_map_us_dump_hashmap_key_hashes(dpa_u_map_us_t* that);


typedef struct dpa_u_map_u dpa_u_map_u_t;
struct dpa_u_map_u {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    unsigned*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
  void**restrict value_list;
};
/**
 * Sets an entry in the map and returns the existing one if one exists.
 * If there was none, the variable will remain unchanged.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_u_exchange(dpa_u_map_u_t* that, unsigned key, void** value);
/**
 * Sets an entry in the map.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_u_set(dpa_u_map_u_t* that, unsigned key, void* value);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_map_u_remove(dpa_u_map_u_t* that, unsigned key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_map_u_has(const dpa_u_map_u_t* that, unsigned key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_map_u_clear(dpa_u_map_u_t* that);
/**
 * Returns the entry.
 */
dpa_u_reproducible dpa__u_api dpa_u_optional_pointer_t dpa_u_map_u_get(const dpa_u_map_u_t* that, unsigned key);
/**
 * Removes and returns an entry.
 */
dpa__u_api dpa_u_optional_pointer_t dpa_u_map_u_get_and_remove(dpa_u_map_u_t* that, unsigned key);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_map_u_count(const dpa_u_map_u_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_map_u_dump_hashmap_key_hashes(dpa_u_map_u_t* that);


typedef struct dpa_u_map_lu dpa_u_map_lu_t;
struct dpa_u_map_lu {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    unsigned long*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
  void**restrict value_list;
};
/**
 * Sets an entry in the map and returns the existing one if one exists.
 * If there was none, the variable will remain unchanged.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_lu_exchange(dpa_u_map_lu_t* that, unsigned long key, void** value);
/**
 * Sets an entry in the map.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_lu_set(dpa_u_map_lu_t* that, unsigned long key, void* value);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_map_lu_remove(dpa_u_map_lu_t* that, unsigned long key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_map_lu_has(const dpa_u_map_lu_t* that, unsigned long key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_map_lu_clear(dpa_u_map_lu_t* that);
/**
 * Returns the entry.
 */
dpa_u_reproducible dpa__u_api dpa_u_optional_pointer_t dpa_u_map_lu_get(const dpa_u_map_lu_t* that, unsigned long key);
/**
 * Removes and returns an entry.
 */
dpa__u_api dpa_u_optional_pointer_t dpa_u_map_lu_get_and_remove(dpa_u_map_lu_t* that, unsigned long key);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_map_lu_count(const dpa_u_map_lu_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_map_lu_dump_hashmap_key_hashes(dpa_u_map_lu_t* that);


typedef struct dpa_u_map_llu dpa_u_map_llu_t;
struct dpa_u_map_llu {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    unsigned long long*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
  void**restrict value_list;
};
/**
 * Sets an entry in the map and returns the existing one if one exists.
 * If there was none, the variable will remain unchanged.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_llu_exchange(dpa_u_map_llu_t* that, unsigned long long key, void** value);
/**
 * Sets an entry in the map.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_llu_set(dpa_u_map_llu_t* that, unsigned long long key, void* value);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_map_llu_remove(dpa_u_map_llu_t* that, unsigned long long key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_map_llu_has(const dpa_u_map_llu_t* that, unsigned long long key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_map_llu_clear(dpa_u_map_llu_t* that);
/**
 * Returns the entry.
 */
dpa_u_reproducible dpa__u_api dpa_u_optional_pointer_t dpa_u_map_llu_get(const dpa_u_map_llu_t* that, unsigned long long key);
/**
 * Removes and returns an entry.
 */
dpa__u_api dpa_u_optional_pointer_t dpa_u_map_llu_get_and_remove(dpa_u_map_llu_t* that, unsigned long long key);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_map_llu_count(const dpa_u_map_llu_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_map_llu_dump_hashmap_key_hashes(dpa_u_map_llu_t* that);


typedef struct dpa_u_map_z dpa_u_map_z_t;
struct dpa_u_map_z {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    size_t*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
  void**restrict value_list;
};
/**
 * Sets an entry in the map and returns the existing one if one exists.
 * If there was none, the variable will remain unchanged.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_z_exchange(dpa_u_map_z_t* that, size_t key, void** value);
/**
 * Sets an entry in the map.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_z_set(dpa_u_map_z_t* that, size_t key, void* value);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_map_z_remove(dpa_u_map_z_t* that, size_t key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_map_z_has(const dpa_u_map_z_t* that, size_t key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_map_z_clear(dpa_u_map_z_t* that);
/**
 * Returns the entry.
 */
dpa_u_reproducible dpa__u_api dpa_u_optional_pointer_t dpa_u_map_z_get(const dpa_u_map_z_t* that, size_t key);
/**
 * Removes and returns an entry.
 */
dpa__u_api dpa_u_optional_pointer_t dpa_u_map_z_get_and_remove(dpa_u_map_z_t* that, size_t key);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_map_z_count(const dpa_u_map_z_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_map_z_dump_hashmap_key_hashes(dpa_u_map_z_t* that);


typedef struct dpa_u_map_u8 dpa_u_map_u8_t;
struct dpa_u_map_u8 {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    uint8_t*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
  void**restrict value_list;
};
/**
 * Sets an entry in the map and returns the existing one if one exists.
 * If there was none, the variable will remain unchanged.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_u8_exchange(dpa_u_map_u8_t* that, uint8_t key, void** value);
/**
 * Sets an entry in the map.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_u8_set(dpa_u_map_u8_t* that, uint8_t key, void* value);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_map_u8_remove(dpa_u_map_u8_t* that, uint8_t key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_map_u8_has(const dpa_u_map_u8_t* that, uint8_t key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_map_u8_clear(dpa_u_map_u8_t* that);
/**
 * Returns the entry.
 */
dpa_u_reproducible dpa__u_api dpa_u_optional_pointer_t dpa_u_map_u8_get(const dpa_u_map_u8_t* that, uint8_t key);
/**
 * Removes and returns an entry.
 */
dpa__u_api dpa_u_optional_pointer_t dpa_u_map_u8_get_and_remove(dpa_u_map_u8_t* that, uint8_t key);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_map_u8_count(const dpa_u_map_u8_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_map_u8_dump_hashmap_key_hashes(dpa_u_map_u8_t* that);


typedef struct dpa_u_map_u16 dpa_u_map_u16_t;
struct dpa_u_map_u16 {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    uint16_t*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
  void**restrict value_list;
};
/**
 * Sets an entry in the map and returns the existing one if one exists.
 * If there was none, the variable will remain unchanged.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_u16_exchange(dpa_u_map_u16_t* that, uint16_t key, void** value);
/**
 * Sets an entry in the map.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_u16_set(dpa_u_map_u16_t* that, uint16_t key, void* value);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_map_u16_remove(dpa_u_map_u16_t* that, uint16_t key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_map_u16_has(const dpa_u_map_u16_t* that, uint16_t key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_map_u16_clear(dpa_u_map_u16_t* that);
/**
 * Returns the entry.
 */
dpa_u_reproducible dpa__u_api dpa_u_optional_pointer_t dpa_u_map_u16_get(const dpa_u_map_u16_t* that, uint16_t key);
/**
 * Removes and returns an entry.
 */
dpa__u_api dpa_u_optional_pointer_t dpa_u_map_u16_get_and_remove(dpa_u_map_u16_t* that, uint16_t key);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_map_u16_count(const dpa_u_map_u16_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_map_u16_dump_hashmap_key_hashes(dpa_u_map_u16_t* that);


typedef struct dpa_u_map_u32 dpa_u_map_u32_t;
struct dpa_u_map_u32 {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    uint32_t*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
  void**restrict value_list;
};
/**
 * Sets an entry in the map and returns the existing one if one exists.
 * If there was none, the variable will remain unchanged.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_u32_exchange(dpa_u_map_u32_t* that, uint32_t key, void** value);
/**
 * Sets an entry in the map.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_u32_set(dpa_u_map_u32_t* that, uint32_t key, void* value);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_map_u32_remove(dpa_u_map_u32_t* that, uint32_t key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_map_u32_has(const dpa_u_map_u32_t* that, uint32_t key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_map_u32_clear(dpa_u_map_u32_t* that);
/**
 * Returns the entry.
 */
dpa_u_reproducible dpa__u_api dpa_u_optional_pointer_t dpa_u_map_u32_get(const dpa_u_map_u32_t* that, uint32_t key);
/**
 * Removes and returns an entry.
 */
dpa__u_api dpa_u_optional_pointer_t dpa_u_map_u32_get_and_remove(dpa_u_map_u32_t* that, uint32_t key);
dpa_u_reproducible dpa__u_api inline size_t dpa_u_map_u32_count(const dpa_u_map_u32_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_map_u32_dump_hashmap_key_hashes(dpa_u_map_u32_t* that);


typedef struct dpa_u_map_u64 dpa_u_map_u64_t;
struct dpa_u_map_u64 {
  // After a certain number of entries, it's more efficient to just save the bitmask.
  // The optimal memory usage for a bitmask of a set in bits is `CHAR_BIT**sizeof(DPA__U_SM_KEY_TYPE)`, but see the comment above for real memory usage.
  // The memory usage of a set which actually stores the keys is at least `sizeof(DPA__U_SM_KEY_TYPE) * count`, but a set with open addressing should
  // have a load facter of around 0.75 (75% of allocated entries used), and the memory usage will be that much higher.
  // This implementation will double the memory used by 2 when the load factor reaches 90%.
  // If this type is a map rather than a set, a value, which has type void*, has to be allocated for each entry too.
  // `bitmask` will be used if the amount of memory wasted is <= 50%.
  // Switching if no memory is wasted would also be possible, but since we already always allocate a power of 2 of memory for the key and value lists, there would be no benefits to that.
  size_t count; // This is the number of entries stored in the set.
  unsigned char lbsize; // This is the log 2 of the number of buckets available.
  union {
    // The key entry is a reversible hash of the original key. This way, the hash does not need to be recalculated,
    // even without storing the key and it's hash.
    uint64_t*restrict key_list;
    dpa_u_bitmap_entry_t*restrict bitmask;
  };
  void**restrict value_list;
};
/**
 * Sets an entry in the map and returns the existing one if one exists.
 * If there was none, the variable will remain unchanged.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_u64_exchange(dpa_u_map_u64_t* that, uint64_t key, void** value);
/**
 * Sets an entry in the map.
 * \returns 1 if an existing entry was overwritten, 0 if not, -1 on error.
 */
dpa__u_api int dpa_u_map_u64_set(dpa_u_map_u64_t* that, uint64_t key, void* value);
/**
 * Removes an entry.
 * \returns true if the entry was present, false otherwise.
 */
dpa__u_api bool dpa_u_map_u64_remove(dpa_u_map_u64_t* that, uint64_t key);
/**
 * Checks if an entry is present.
 * \returns true if the entry was present, false otherwise.
 */
dpa_u_reproducible dpa__u_api bool dpa_u_map_u64_has(const dpa_u_map_u64_t* that, uint64_t key);
/**
 * Removes all entries, frees all allocations
 */
dpa__u_api void dpa_u_map_u64_clear(dpa_u_map_u64_t* that);
/**
 * Returns the entry.
 */
dpa_u_reproducible dpa__u_api dpa_u_optional_pointer_t dpa_u_map_u64_get(const dpa_u_map_u64_t* that, uint64_t key);
/**
 * Removes and returns an entry.
 */
dpa__u_api dpa_u_optional_pointer_t dpa_u_map_u64_get_and_remove(dpa_u_map_u64_t* that, uint64_t key);

dpa_u_reproducible dpa__u_api inline size_t dpa_u_map_u64_count(const dpa_u_map_u64_t* that){
  return that->count;
}
/**
 * For debugging purposes only
 */
dpa__u_api void dpa_u_map_u64_dump_hashmap_key_hashes(dpa_u_map_u64_t* that);
