Union with shared_ptr caused a memory leak. Prevent this using std::variant
This commit is contained in:
parent
458274f370
commit
6c6d977000
|
@ -16,14 +16,25 @@ namespace Porygon{
|
|||
Dictionary
|
||||
};
|
||||
|
||||
bool _isContentAware;
|
||||
using ContentTypes = unordered_map<Utilities::HashedString, shared_ptr<const ScriptType>>*;
|
||||
using KeyValueType = std::pair<shared_ptr<const ScriptType>, shared_ptr<const ScriptType>>;
|
||||
|
||||
bool _isContentAware = false;
|
||||
TableType _tableType;
|
||||
|
||||
union{
|
||||
shared_ptr<const ScriptType> _valueType; // numerical
|
||||
unordered_map<Utilities::HashedString, shared_ptr<const ScriptType>>* _contentTypes = nullptr; // string keyed
|
||||
std::pair<shared_ptr<const ScriptType>, shared_ptr<const ScriptType>> _keyValueType; // dictionary
|
||||
};
|
||||
std::variant<
|
||||
shared_ptr<const ScriptType>,
|
||||
ContentTypes,
|
||||
KeyValueType
|
||||
> _valueType, _contentTypes, _keyValueType;
|
||||
|
||||
[[nodiscard]] inline shared_ptr<const ScriptType> GetValueType() const{
|
||||
return std::get<shared_ptr<const ScriptType>>(_valueType);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline KeyValueType GetKeyValueTypes() const{
|
||||
return std::get<KeyValueType>(_keyValueType);
|
||||
}
|
||||
|
||||
public:
|
||||
explicit TableScriptType()
|
||||
|
@ -41,7 +52,7 @@ namespace Porygon{
|
|||
|
||||
~TableScriptType() override {
|
||||
if (_tableType == TableType::StringKeyed)
|
||||
delete _contentTypes;
|
||||
delete GetContentTypes();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool CanBeIterated() const final {
|
||||
|
@ -71,7 +82,7 @@ namespace Porygon{
|
|||
return indexer->GetClass() == TypeClass::Number;
|
||||
}
|
||||
else{
|
||||
auto keyType = _keyValueType.first;
|
||||
auto keyType = GetKeyValueTypes().first;
|
||||
return indexer->CastableTo(keyType, false) != CastResult ::InvalidCast;
|
||||
}
|
||||
}
|
||||
|
@ -89,25 +100,25 @@ namespace Porygon{
|
|||
auto stringType = dynamic_pointer_cast<const StringScriptType>(indexer);
|
||||
if (stringType->IsKnownAtBind() && _isContentAware){
|
||||
auto h = stringType->GetHashValue();
|
||||
return _contentTypes->at(h);
|
||||
return GetContentTypes()->at(h);
|
||||
}
|
||||
return ScriptType::AnyType;
|
||||
}
|
||||
else if (_tableType == TableType::Numerical){
|
||||
return _valueType;
|
||||
return GetValueType();
|
||||
}
|
||||
else{
|
||||
return _keyValueType.second;
|
||||
return GetKeyValueTypes().second;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] shared_ptr<const ScriptType> GetIndexedType(uint32_t hash) const override {
|
||||
auto lookup = Utilities::HashedString::CreateLookup(hash);
|
||||
return _contentTypes->at(lookup);
|
||||
return GetContentTypes()->at(lookup);
|
||||
}
|
||||
|
||||
unordered_map<Utilities::HashedString, shared_ptr<const ScriptType>>* GetContentTypes() const{
|
||||
return _contentTypes;
|
||||
[[nodiscard]] inline ContentTypes GetContentTypes() const{
|
||||
return std::get<ContentTypes>(_contentTypes);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
|
@ -117,12 +128,12 @@ namespace Porygon{
|
|||
case Unknown: return true;
|
||||
case Numerical:
|
||||
return indexer->GetClass() == TypeClass ::Number &&
|
||||
val->CastableTo(_valueType, false) != CastResult ::InvalidCast;
|
||||
val->CastableTo(GetValueType(), false) != CastResult ::InvalidCast;
|
||||
case StringKeyed:
|
||||
return indexer->GetClass() == TypeClass ::String;
|
||||
case Dictionary:
|
||||
return indexer->CastableTo(_keyValueType.first, false) != CastResult ::InvalidCast &&
|
||||
val->CastableTo(_keyValueType.second, false) != CastResult ::InvalidCast;
|
||||
return indexer->CastableTo(GetKeyValueTypes().first, false) != CastResult ::InvalidCast &&
|
||||
val->CastableTo(GetKeyValueTypes().second, false) != CastResult ::InvalidCast;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,14 +155,14 @@ namespace Porygon{
|
|||
auto s = dynamic_pointer_cast<const StringScriptType>(indexer);
|
||||
if (s->IsKnownAtBind()){
|
||||
auto key = s->GetHashValue();
|
||||
_contentTypes->insert({key, val});
|
||||
GetContentTypes()->insert({key, val});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetIndexValue(Utilities::HashedString indexer, shared_ptr<const ScriptType> val) const override {
|
||||
if (_tableType == TableType::StringKeyed){
|
||||
_contentTypes->insert({indexer, val});
|
||||
GetContentTypes()->insert({indexer, val});
|
||||
}
|
||||
else if (_tableType == TableType::Unknown){
|
||||
auto t = const_cast<TableScriptType*>(this);
|
||||
|
|
Loading…
Reference in New Issue