This commit is contained in:
blueloveTH 2023-10-12 19:43:07 +08:00
parent 2cf3bdc097
commit ed26e08704

View File

@ -6,6 +6,100 @@
namespace pkpy{
template<typename T>
constexpr T default_invalid_value(){
if constexpr(std::is_pointer_v<T>) return nullptr;
else if constexpr(std::is_same_v<int, T>) return -1;
else return Discarded();
}
template<typename V>
struct SmallNameDict{
using K = StrName;
static_assert(std::is_pod_v<V>);
static const int kCapacity = 12;
int _size;
std::pair<K, V> _items[kCapacity];
SmallNameDict(): _size(0) {}
void set(K key, V val){
for(int i=0; i<kCapacity; i++){
if(_items[i].first == key){
_items[i].second = val;
return;
}
}
#if PK_DEBUG_EXTRA_CHECK
if(_size == kCapacity){
throw std::runtime_error("SmallDict: capacity exceeded");
}
#endif
_items[_size++] = {key, val};
}
bool try_set(K key, V val){
for(int i=0; i<kCapacity; i++){
if(_items[i].first == key){
_items[i].second = val;
return true;
}
}
return false;
}
V operator[](K key) const {
for(int i=0; i<kCapacity; i++){
if(_items[i].first == key) return _items[i].second;
}
throw std::out_of_range(fmt("SmallDict key not found: ", key));
}
V get(K key) const {
for(int i=0; i<kCapacity; i++){
if(_items[i].first == key) return _items[i].second;
}
return default_invalid_value<V>();
}
bool contains(K key) const {
for(int i=0; i<kCapacity; i++){
if(_items[i].first == key) return true;
}
return false;
}
bool del(K key){
for(int i=0; i<kCapacity; i++){
if(_items[i].first == key){
_items[i].first = StrName();
_size--;
return true;
}
}
return false;
}
template<typename Func>
void apply(Func func) const {
for(int i=0; i<kCapacity; i++){
if(_items[i].first) func(_items[i].first, _items[i].second);
}
}
void clear(){
for(int i=0; i<kCapacity; i++){
_items[i].first = StrName();
}
_size = 0;
}
int size() const { return _size; }
int capacity() const { return kCapacity; }
};
inline const uint16_t kHashSeeds[] = {9629, 43049, 13267, 59509, 39251, 1249, 27689, 9719, 19913};
inline uint16_t _hash(StrName key, uint16_t mask, uint16_t hash_seed){