mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Reworked ref enumerators to support non-pointer refs
This commit is contained in:
parent
70d32885b1
commit
d5073e810c
10 changed files with 82 additions and 24 deletions
|
@ -13,9 +13,13 @@ namespace System.Collections
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics.Contracts;
|
using System.Diagnostics.Contracts;
|
||||||
|
|
||||||
public class Dictionary<TKey, TValue> : ICollection<(TKey key, TValue value)>, IEnumerable<(TKey key, TValue value)> where TKey : IHashable
|
public class Dictionary<TKey, TValue> :
|
||||||
|
ICollection<(TKey key, TValue value)>,
|
||||||
|
IEnumerable<(TKey key, TValue value)>,
|
||||||
|
IRefEnumerable<(TKey key, TValue* valueRef)> where TKey : IHashable
|
||||||
{
|
{
|
||||||
typealias KeyValuePair=(TKey key, TValue value);
|
typealias KeyValuePair=(TKey key, TValue value);
|
||||||
|
typealias KeyRefValuePair=(TKey key, TValue* valueRef);
|
||||||
|
|
||||||
private struct Entry
|
private struct Entry
|
||||||
{
|
{
|
||||||
|
@ -606,7 +610,7 @@ namespace System.Collections
|
||||||
return (key is TKey);
|
return (key is TKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct Enumerator : IEnumerator<KeyValuePair>//, IDictionaryEnumerator
|
public struct Enumerator : IEnumerator<KeyValuePair>, IRefEnumerator<KeyRefValuePair>
|
||||||
{
|
{
|
||||||
private Dictionary<TKey, TValue> mDictionary;
|
private Dictionary<TKey, TValue> mDictionary;
|
||||||
#if VERSION_DICTIONARY
|
#if VERSION_DICTIONARY
|
||||||
|
@ -687,6 +691,11 @@ namespace System.Collections
|
||||||
get { return (mDictionary.mEntries[mCurrentIndex].mKey, mDictionary.mEntries[mCurrentIndex].mValue); }
|
get { return (mDictionary.mEntries[mCurrentIndex].mKey, mDictionary.mEntries[mCurrentIndex].mValue); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KeyRefValuePair CurrentRef
|
||||||
|
{
|
||||||
|
get { return (mDictionary.mEntries[mCurrentIndex].mKey, &mDictionary.mEntries[mCurrentIndex].mValue); }
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -753,9 +762,16 @@ namespace System.Collections
|
||||||
return .Err;
|
return .Err;
|
||||||
return Current;
|
return Current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Result<KeyRefValuePair> GetNextRef() mut
|
||||||
|
{
|
||||||
|
if (!MoveNext())
|
||||||
|
return .Err;
|
||||||
|
return CurrentRef;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ValueEnumerator : IRefEnumerator<TValue>, IResettable
|
public struct ValueEnumerator : IRefEnumerator<TValue*>, IEnumerator<TValue>, IResettable
|
||||||
{
|
{
|
||||||
private Dictionary<TKey, TValue> mDictionary;
|
private Dictionary<TKey, TValue> mDictionary;
|
||||||
#if VERSION_DICTIONARY
|
#if VERSION_DICTIONARY
|
||||||
|
|
|
@ -12,13 +12,18 @@ namespace System.Collections
|
||||||
void Reset() mut;
|
void Reset() mut;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IRefEnumerator<T> : IEnumerator<T>
|
interface IRefEnumerator<T>
|
||||||
{
|
{
|
||||||
Result<T*> GetNextRef() mut;
|
Result<T> GetNextRef() mut;
|
||||||
}
|
}
|
||||||
|
|
||||||
concrete interface IEnumerable<T>
|
concrete interface IEnumerable<T>
|
||||||
{
|
{
|
||||||
concrete IEnumerator<T> GetEnumerator();
|
concrete IEnumerator<T> GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
concrete interface IRefEnumerable<T>
|
||||||
|
{
|
||||||
|
concrete IRefEnumerator<T> GetEnumerator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -623,7 +623,7 @@ namespace System.Collections
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct Enumerator : IRefEnumerator<T>, IResettable
|
public struct Enumerator : IRefEnumerator<T*>, IEnumerator<T>, IResettable
|
||||||
{
|
{
|
||||||
private List<T> mList;
|
private List<T> mList;
|
||||||
private int mIndex;
|
private int mIndex;
|
||||||
|
|
|
@ -351,7 +351,7 @@ namespace System.Collections
|
||||||
/// Implements an enumerator for a Queue. The enumerator uses the
|
/// Implements an enumerator for a Queue. The enumerator uses the
|
||||||
/// internal version number of the list to ensure that no modifications are
|
/// internal version number of the list to ensure that no modifications are
|
||||||
/// made to the list while an enumeration is in progress.
|
/// made to the list while an enumeration is in progress.
|
||||||
public struct Enumerator : IRefEnumerator<T>
|
public struct Enumerator : IRefEnumerator<T*>, IEnumerator<T>
|
||||||
{
|
{
|
||||||
private Queue<T> mQueue;
|
private Queue<T> mQueue;
|
||||||
private int32 mIndex; // -1 = not started, -2 = ended/disposed
|
private int32 mIndex; // -1 = not started, -2 = ended/disposed
|
||||||
|
|
|
@ -184,7 +184,7 @@ namespace System
|
||||||
return Enumerator(this);
|
return Enumerator(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct Enumerator : IEnumerator<T>, IRefEnumerator<T>
|
public struct Enumerator : IEnumerator<T>, IRefEnumerator<T*>
|
||||||
{
|
{
|
||||||
private Span<T> mList;
|
private Span<T> mList;
|
||||||
private int mIndex;
|
private int mIndex;
|
||||||
|
|
|
@ -2360,7 +2360,7 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct RawEnumerator : IRefEnumerator<char8>
|
public struct RawEnumerator : IRefEnumerator<char8*>, IEnumerator<char8>
|
||||||
{
|
{
|
||||||
char8* mPtr;
|
char8* mPtr;
|
||||||
int_strsize mIdx;
|
int_strsize mIdx;
|
||||||
|
|
|
@ -12150,7 +12150,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL))
|
if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL))
|
||||||
{
|
{
|
||||||
errorNode = invocationExpr->mGenericArgs->mGenericArgs[(int)methodDef->mGenericParams.size()];
|
errorNode = invocationExpr->mGenericArgs->mGenericArgs[(int)methodDef->mGenericParams.size()];
|
||||||
if (errorNode == NULL)
|
if ((errorNode == NULL) && (!invocationExpr->mGenericArgs->mCommas.IsEmpty()))
|
||||||
errorNode = invocationExpr->mGenericArgs->mCommas[(int)methodDef->mGenericParams.size() - 1];
|
errorNode = invocationExpr->mGenericArgs->mCommas[(int)methodDef->mGenericParams.size() - 1];
|
||||||
}
|
}
|
||||||
mModule->Fail(StrFormat("Too many generic arguments, expected %d fewer", genericArgCountDiff), errorNode);
|
mModule->Fail(StrFormat("Too many generic arguments, expected %d fewer", genericArgCountDiff), errorNode);
|
||||||
|
|
|
@ -906,9 +906,7 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
||||||
if (typeAliasDecl->mAliasToType != NULL)
|
if (typeAliasDecl->mAliasToType != NULL)
|
||||||
aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias);
|
aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias);
|
||||||
}
|
}
|
||||||
//typeAlias->mModule = mContext->mScratchModule;
|
|
||||||
typeAlias->mTypeIncomplete = false;
|
|
||||||
typeAlias->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
|
|
||||||
if (aliasToType != NULL)
|
if (aliasToType != NULL)
|
||||||
{
|
{
|
||||||
AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom);
|
AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom);
|
||||||
|
@ -951,7 +949,7 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
||||||
resolvedTypeRef->mRebuildFlags = BfTypeRebuildFlag_None;
|
resolvedTypeRef->mRebuildFlags = BfTypeRebuildFlag_None;
|
||||||
typeAlias->mCustomAttributes = GetCustomAttributes(typeDef->mTypeDeclaration->mAttributes, BfAttributeTargets_Alias);
|
typeAlias->mCustomAttributes = GetCustomAttributes(typeDef->mTypeDeclaration->mAttributes, BfAttributeTargets_Alias);
|
||||||
|
|
||||||
return true;
|
// Fall through so generic params are populated in DoPopulateType
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolvedTypeRef->IsSizedArray())
|
if (resolvedTypeRef->IsSizedArray())
|
||||||
|
@ -1159,6 +1157,7 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
||||||
case BfTypeCode_Struct:
|
case BfTypeCode_Struct:
|
||||||
case BfTypeCode_Interface:
|
case BfTypeCode_Interface:
|
||||||
case BfTypeCode_Enum:
|
case BfTypeCode_Enum:
|
||||||
|
case BfTypeCode_TypeAlias:
|
||||||
// Implemented below
|
// Implemented below
|
||||||
break;
|
break;
|
||||||
case BfTypeCode_Extension:
|
case BfTypeCode_Extension:
|
||||||
|
@ -1518,6 +1517,13 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
BuildGenericParams(resolvedTypeRef);
|
BuildGenericParams(resolvedTypeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resolvedTypeRef->IsTypeAlias())
|
||||||
|
{
|
||||||
|
typeInstance->mTypeIncomplete = false;
|
||||||
|
resolvedTypeRef->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (_CheckTypeDone())
|
if (_CheckTypeDone())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
@ -3768,7 +3768,28 @@ String BfTypeUtils::TypeToString(BfTypeReference* typeRef)
|
||||||
}
|
}
|
||||||
if (auto directStrTypeName = BfNodeDynCast<BfDirectStrTypeReference>(typeRef))
|
if (auto directStrTypeName = BfNodeDynCast<BfDirectStrTypeReference>(typeRef))
|
||||||
return directStrTypeName->mTypeName;
|
return directStrTypeName->mTypeName;
|
||||||
BF_FATAL("Not implemented");
|
|
||||||
|
if (auto tupleTypeRef = BfNodeDynCast<BfTupleTypeRef>(typeRef))
|
||||||
|
{
|
||||||
|
String name = "(";
|
||||||
|
|
||||||
|
for (int i = 0; i < tupleTypeRef->mFieldTypes.size(); i++)
|
||||||
|
{
|
||||||
|
if (i > 0)
|
||||||
|
name += ", ";
|
||||||
|
name += TypeToString(tupleTypeRef->mFieldTypes[i]);
|
||||||
|
if ((i < tupleTypeRef->mFieldNames.size()) && (tupleTypeRef->mFieldNames[i] != NULL))
|
||||||
|
{
|
||||||
|
name += " ";
|
||||||
|
name += tupleTypeRef->mFieldNames[i]->ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
name += ")";
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_DBG_FATAL("Not implemented");
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3696,6 +3696,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
|
||||||
if (checkType->IsPointer())
|
if (checkType->IsPointer())
|
||||||
{
|
{
|
||||||
auto innerType = checkType->GetUnderlyingType();
|
auto innerType = checkType->GetUnderlyingType();
|
||||||
|
PopulateType(innerType);
|
||||||
if (innerType->IsValuelessType())
|
if (innerType->IsValuelessType())
|
||||||
mayBeSentinel = true;
|
mayBeSentinel = true;
|
||||||
}
|
}
|
||||||
|
@ -5715,7 +5716,6 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
if (genericItrInterface != NULL)
|
if (genericItrInterface != NULL)
|
||||||
{
|
{
|
||||||
Fail(StrFormat("Type '%s' implements multiple %s<T> interfaces", TypeToString(itr.mType).c_str(), isRefExpression ? "IRefEnumerator" : "IEnumerator"), forEachStmt->mCollectionExpression);
|
Fail(StrFormat("Type '%s' implements multiple %s<T> interfaces", TypeToString(itr.mType).c_str(), isRefExpression ? "IRefEnumerator" : "IEnumerator"), forEachStmt->mCollectionExpression);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
itrInterface = interface;
|
itrInterface = interface;
|
||||||
|
@ -5724,7 +5724,11 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
{
|
{
|
||||||
varType = genericItrInterface->mTypeGenericArguments[0];
|
varType = genericItrInterface->mTypeGenericArguments[0];
|
||||||
if (isRefExpression)
|
if (isRefExpression)
|
||||||
varType = CreateRefType(varType);
|
{
|
||||||
|
if (varType->IsPointer())
|
||||||
|
varType = CreateRefType(varType->GetUnderlyingType());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5737,10 +5741,13 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
{
|
{
|
||||||
varType = genericItrInterface->mTypeGenericArguments[0];
|
varType = genericItrInterface->mTypeGenericArguments[0];
|
||||||
if (isRefExpression)
|
if (isRefExpression)
|
||||||
|
{
|
||||||
|
if (varType->IsPointer())
|
||||||
varType = CreateRefType(varType);
|
varType = CreateRefType(varType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (genericItrInterface == NULL)
|
if (genericItrInterface == NULL)
|
||||||
{
|
{
|
||||||
|
@ -5761,9 +5768,9 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
refItrInterface = itrInterface;
|
refItrInterface = itrInterface;
|
||||||
PopulateType(refItrInterface);
|
PopulateType(refItrInterface);
|
||||||
// Must IRefEnumeratorf<T> must include only IEnumerator<T>
|
// Must IRefEnumeratorf<T> must include only IEnumerator<T>
|
||||||
BF_ASSERT(refItrInterface->mInterfaces.size() == 1);
|
// BF_ASSERT(refItrInterface->mInterfaces.size() == 1);
|
||||||
if (refItrInterface->mInterfaces.size() == 1)
|
// if (refItrInterface->mInterfaces.size() == 1)
|
||||||
itrInterface = refItrInterface->mInterfaces[0].mInterfaceType;
|
// itrInterface = refItrInterface->mInterfaces[0].mInterfaceType;
|
||||||
}
|
}
|
||||||
itr = MakeAddressable(itr);
|
itr = MakeAddressable(itr);
|
||||||
itr = RemoveReadOnly(itr);
|
itr = RemoveReadOnly(itr);
|
||||||
|
@ -6220,7 +6227,10 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
{
|
{
|
||||||
auto nextVal = BfTypedValue(mBfIRBuilder->CreateBitCast(nextResult.mValue, mBfIRBuilder->MapType(CreatePointerType(nextEmbeddedType))), nextEmbeddedType, true);
|
auto nextVal = BfTypedValue(mBfIRBuilder->CreateBitCast(nextResult.mValue, mBfIRBuilder->MapType(CreatePointerType(nextEmbeddedType))), nextEmbeddedType, true);
|
||||||
if (isRefExpression)
|
if (isRefExpression)
|
||||||
|
{
|
||||||
|
if (nextVal.mType->IsPointer())
|
||||||
nextVal = BfTypedValue(nextVal.mValue, CreateRefType(nextVal.mType->GetUnderlyingType()), true);
|
nextVal = BfTypedValue(nextVal.mValue, CreateRefType(nextVal.mType->GetUnderlyingType()), true);
|
||||||
|
}
|
||||||
nextVal = Cast(forEachStmt->mCollectionExpression, nextVal, varType, BfCastFlags_Explicit);
|
nextVal = Cast(forEachStmt->mCollectionExpression, nextVal, varType, BfCastFlags_Explicit);
|
||||||
nextVal = LoadValue(nextVal);
|
nextVal = LoadValue(nextVal);
|
||||||
if (nextVal)
|
if (nextVal)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue