This commit is contained in:
blueloveTH 2023-10-12 22:17:26 +08:00
parent 17fd51b967
commit 38c0eb6bea
2 changed files with 46 additions and 45 deletions

View File

@ -13,6 +13,8 @@ constexpr T default_invalid_value(){
else return Discarded(); else return Discarded();
} }
#define PK_LOOP_12(B) B(0) B(1) B(2) B(3) B(4) B(5) B(6) B(7) B(8) B(9) B(10) B(11)
template<typename V> template<typename V>
struct SmallNameDict{ struct SmallNameDict{
using K = StrName; using K = StrName;
@ -29,13 +31,14 @@ struct SmallNameDict{
bool try_set(K key, V val){ bool try_set(K key, V val){
int slot = -1; int slot = -1;
for(int i=0; i<kCapacity; i++){
if(_keys[i] == key){ #define BLOCK(i) \
_values[i] = val; if(_keys[i] == key){ _values[i] = val; return true; } \
return true; if(_keys[i].empty()) slot = i; \
}
if(_keys[i].empty()) slot = i; PK_LOOP_12(BLOCK)
} #undef BLOCK
if(slot == -1) return false; if(slot == -1) return false;
_keys[slot] = key; _keys[slot] = key;
_values[slot] = val; _values[slot] = val;
@ -43,56 +46,45 @@ struct SmallNameDict{
return true; return true;
} }
V operator[](K key) const {
for(int i=0; i<kCapacity; i++){
if(_keys[i] == key) return _values[i];
}
throw std::out_of_range(fmt("SmallNameDict key not found: ", key));
}
V try_get(K key) const { V try_get(K key) const {
for(int i=0; i<kCapacity; i++){ #define BLOCK(i) if(_keys[i] == key) return _values[i];
if(_keys[i] == key) return _values[i]; PK_LOOP_12(BLOCK)
} #undef BLOCK
return default_invalid_value<V>(); return default_invalid_value<V>();
} }
V* try_get_2(K key) { V* try_get_2(K key) {
for(int i=0; i<kCapacity; i++){ #define BLOCK(i) if(_keys[i] == key) return &_values[i];
if(_keys[i] == key) return &_values[i]; PK_LOOP_12(BLOCK)
} #undef BLOCK
return nullptr; return nullptr;
} }
bool contains(K key) const { bool contains(K key) const {
for(int i=0; i<kCapacity; i++){ #define BLOCK(i) if(_keys[i] == key) return true;
if(_keys[i] == key) return true; PK_LOOP_12(BLOCK)
} #undef BLOCK
return false; return false;
} }
bool del(K key){ bool del(K key){
for(int i=0; i<kCapacity; i++){ #define BLOCK(i) if(_keys[i] == key){ _keys[i] = StrName(); _size--; return true; }
if(_keys[i] == key){ PK_LOOP_12(BLOCK)
_keys[i] = StrName(); #undef BLOCK
_size--;
return true;
}
}
return false; return false;
} }
template<typename Func> template<typename Func>
void apply(Func func) const { void apply(Func func) const {
for(int i=0; i<kCapacity; i++){ #define BLOCK(i) if(!_keys[i].empty()) func(_keys[i], _values[i]);
if(!_keys[i].empty()) func(_keys[i], _values[i]); PK_LOOP_12(BLOCK)
} #undef BLOCK
} }
void clear(){ void clear(){
for(int i=0; i<kCapacity; i++){ #define BLOCK(i) _keys[i] = StrName();
_keys[i] = StrName(); PK_LOOP_12(BLOCK)
} #undef BLOCK
_size = 0; _size = 0;
} }
@ -167,13 +159,6 @@ while(!_items[i].first.empty()) { \
_mask = val - 1; _mask = val - 1;
} }
T operator[](StrName key) const {
bool ok; uint16_t i;
HASH_PROBE_0(key, ok, i);
if(!ok) throw std::out_of_range(fmt("LargeNameDict key not found: ", key));
return _items[i].second;
}
void set(StrName key, T val){ void set(StrName key, T val){
bool ok; uint16_t i; bool ok; uint16_t i;
HASH_PROBE_1(key, ok, i); HASH_PROBE_1(key, ok, i);
@ -305,12 +290,19 @@ struct NameDictImpl{
uint16_t size() const{ return is_small() ?_small.size() : _large.size(); } uint16_t size() const{ return is_small() ?_small.size() : _large.size(); }
uint16_t capacity() const{ return is_small() ?_small.capacity() : _large.capacity(); } uint16_t capacity() const{ return is_small() ?_small.capacity() : _large.capacity(); }
V operator[](StrName key) const { return is_small() ?_small[key] : _large[key]; }
V try_get(StrName key) const { return is_small() ?_small.try_get(key) : _large.try_get(key); } V try_get(StrName key) const { return is_small() ?_small.try_get(key) : _large.try_get(key); }
V* try_get_2(StrName key) { return is_small() ?_small.try_get_2(key) : _large.try_get_2(key); } V* try_get_2(StrName key) { return is_small() ?_small.try_get_2(key) : _large.try_get_2(key); }
bool contains(StrName key) const { return is_small() ?_small.contains(key) : _large.contains(key); } bool contains(StrName key) const { return is_small() ?_small.contains(key) : _large.contains(key); }
bool del(StrName key){ return is_small() ?_small.del(key) : _large.del(key); } bool del(StrName key){ return is_small() ?_small.del(key) : _large.del(key); }
V operator[](StrName key) const {
V val = try_get(key);
if(val == default_invalid_value<V>()){
throw std::runtime_error(fmt("NameDict key not found: ", key.escape()));
}
return val;
}
void clear(){ void clear(){
if(is_small()) _small.clear(); if(is_small()) _small.clear();
else _large.clear(); else _large.clear();

View File

@ -24,4 +24,13 @@ a %= 3
assert a == 2 assert a == 2
a ^= 0xf0 a ^= 0xf0
assert a == 242 assert a == 242
# incremental set
class A: pass
for i in range(ord('a'), ord('z')+1):
setattr(A, chr(i), i)
assert A.a == ord('a')
assert A.z == ord('z')