#pragma once typedef unsigned char u8;typedef unsigned short u16;typedef unsigned int u32;typedef unsigned long long u64;typedef signed long long s64; union Value64 { s64 i; double d;}; struct Pair_Int { int first; int second;}; void clear_word(char* word);char *advance_word(char *p); Pair_Int next_power_of_2(int num); struct Arena { std::vector<char*> pools; std::vector<char*> big_pools; int pool_size = 1024 * 1024; int idx = 0; int rewind_pool = -1; int rewind_idx = -1; void set_rewind_point() { rewind_pool = pools.size() - 1; if (rewind_pool < 0) rewind_pool = 0; rewind_idx = idx; } void add_pool() { pools.push_back(new char[pool_size]); idx = 0; } void *add_big_pool(int size) { big_pools.push_back(new char[size]); return (void*)big_pools.back(); } Arena() = default; ~Arena() { for (auto& p : pools) { delete[] p; p = nullptr; } for (auto& p : big_pools) { delete[] p; p = nullptr; } } void *allocate(int size, int align = 0); char *alloc_string(char *str); void *store_buffer(void *buf, int size, u64 align = 4); void rewind(); template<class T> T *allocate_object() { T *t = (T*)allocate(sizeof(T), sizeof(void*)); new(t) T(); return t; }}; struct String_Vector { char *pool = nullptr; int pool_size = 32; int head = 0; ~String_Vector() { if (pool) delete[] pool; } char *at(int idx); void try_expand(int new_size = 0); int add_string(const char *str); int add_buffer(const char *buf, int size); char *allocate(int size); void append_extra_zero(); void clear();}; struct Bucket { u32 flags = 0; int name_idx = 0; int parent_name_idx = 0; union { u64 value = 0; void *pointer; };}; struct Map { String_Vector default_sv; String_Vector *sv = nullptr; Bucket *data = nullptr; int log2_slots = 7; int n_entries = 0; float max_load = 0.75; const u32 seed = 331; Map() { data = new Bucket[1 << log2_slots](); sv = &default_sv; } Map(int n_slots) { log2_slots = next_power_of_2(n_slots).second; data = new Bucket[1 << log2_slots](); sv = &default_sv; } ~Map() { delete[] data; } Bucket& operator[](const char *str) { return data[get(str, 0)]; } int size() const { return 1 << log2_slots; } char *key_from_index(int idx) { return sv->at(data[idx].name_idx); } int get(const char *str, int len = 0); Bucket& insert(const char *str, int len = 0); void remove(const char *str, int len = 0); void erase_all(); void erase_all_of_type(u32 flags); void erase_all_of_exact_type(u32 flags); void erase_all_similar_to(u32 flags); void next_level(); void next_level_maybe(); void release();}; Arena& get_default_arena();