# pragma once
//A class that has an initialization lock so that when the lock is activated, any further gets that are missing items in it will report themselves for easier debugging detection.
template < typename T , typename O >
class safemap {
std : : map < T , O > map ;
bool initialized = false ;
public :
O & operator [ ] ( T key ) {
if ( initialized & & map . count ( key ) = = 0 ) {
std : : cout < < " WARNING! Trying to get non-existent key " < < key < < " ! " < < std : : endl ;
throw ;
}
if ( ! initialized ) {
size_t originalSize = map . size ( ) ;
O & val = map [ key ] ;
if ( originalSize = = map . size ( ) ) {
std : : cout < < " WARNING! A previously set value has been overwritten! Key: " < < key < < std : : endl ;
throw ;
}
return val ;
} else {
return map [ key ] ;
}
}
O & at ( T key ) {
return map . at ( key ) ;
}
size_t count ( T key ) {
return map . count ( key ) ;
}
void SetInitialized ( ) {
initialized = true ;
}
size_t size ( ) {
return map . size ( ) ;
}
//Unlocks the map so items can be added to it again. USE WITH CAUTION! And make sure to lock the map again.
void Unlock ( ) {
initialized = false ;
}
//Clears the entire map and unlocks the map so items can be added to it again.
void Reset ( ) {
initialized = false ;
map . clear ( ) ;
}
auto begin ( ) const {
return map . begin ( ) ;
}
auto end ( ) const {
return map . end ( ) ;
}
size_t erase ( const T & key ) {
return map . erase ( key ) ;
}
} ;
//A class that has an initialization lock so that when the lock is activated, any further gets that are missing items in it will report themselves for easier debugging detection.
//This unordered map should return items inserted in order. Therefore internally, it's hosted as a vector. As such, if an item is added to this map it's possible the refernce becomes stale when another item is added due to a vector expanding. BEWARE!
template < typename T , typename O >
class safeunorderedmap {
std : : unordered_map < T , int > map ;
std : : vector < O > items ;
bool initialized = false ;
public :
O & operator [ ] ( T key ) {
if ( initialized & & map . count ( key ) = = 0 ) {
std : : cout < < " WARNING! Trying to get non-existent key " < < key < < " ! " < < std : : endl ;
throw ;
}
if ( ! initialized ) {
size_t originalSize = map . size ( ) ;
map [ key ] = items . size ( ) ;
if ( originalSize = = map . size ( ) ) {
std : : cout < < " WARNING! A previously set value has been overwritten! Key: " < < key < < std : : endl ;
throw ;
}
items . push_back ( { } ) ;
return items [ map [ key ] ] ;
} else {
return items [ map [ key ] ] ;
}
}
O & at ( T key ) {
return items [ map . at ( key ) ] ;
}
size_t count ( T key ) {
return map . count ( key ) ;
}
void SetInitialized ( ) {
initialized = true ;
}
size_t size ( ) {
return map . size ( ) ;
}
//Clears the entire map and unlocks the map so items can be added to it again.
void Reset ( ) {
initialized = false ;
map . clear ( ) ;
items . clear ( ) ;
}
auto begin ( ) const {
return items . begin ( ) ;
}
auto end ( ) const {
return items . end ( ) ;
}
} ;