Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[fix] cpp-bin 多维容器反序列化时为循环变量命名加上深度信息。 #129

Merged
merged 1 commit into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/Luban.Core/TypeVisitors/ITypeFuncVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,36 @@ public interface ITypeFuncVisitor<T, T2, T3, TR>

TR Accept(TMap type, T x, T2 y, T3 z);
}

public interface ITypeFuncVisitor<T, T2, T3, T4, TR>
{
TR Accept(TBool type, T x, T2 y, T3 z, T4 w);

TR Accept(TByte type, T x, T2 y, T3 z, T4 w);

TR Accept(TShort type, T x, T2 y, T3 z, T4 w);

TR Accept(TInt type, T x, T2 y, T3 z, T4 w);

TR Accept(TLong type, T x, T2 y, T3 z, T4 w);

TR Accept(TFloat type, T x, T2 y, T3 z, T4 w);

TR Accept(TDouble type, T x, T2 y, T3 z, T4 w);

TR Accept(TEnum type, T x, T2 y, T3 z, T4 w);

TR Accept(TString type, T x, T2 y, T3 z, T4 w);

TR Accept(TDateTime type, T x, T2 y, T3 z, T4 w);

TR Accept(TBean type, T x, T2 y, T3 z, T4 w);

TR Accept(TArray type, T x, T2 y, T3 z, T4 w);

TR Accept(TList type, T x, T2 y, T3 z, T4 w);

TR Accept(TSet type, T x, T2 y, T3 z, T4 w);

TR Accept(TMap type, T x, T2 y, T3 z, T4 w);
}
5 changes: 5 additions & 0 deletions src/Luban.Core/Types/TArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,9 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
{
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
5 changes: 5 additions & 0 deletions src/Luban.Core/Types/TBean.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,9 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
{
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
5 changes: 5 additions & 0 deletions src/Luban.Core/Types/TBool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,9 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
{
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
5 changes: 5 additions & 0 deletions src/Luban.Core/Types/TByte.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,9 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
{
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
4 changes: 4 additions & 0 deletions src/Luban.Core/Types/TDateTime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,8 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
5 changes: 5 additions & 0 deletions src/Luban.Core/Types/TDouble.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,9 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
{
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
5 changes: 5 additions & 0 deletions src/Luban.Core/Types/TEnum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,9 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
{
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
5 changes: 5 additions & 0 deletions src/Luban.Core/Types/TFloat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,9 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
{
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
5 changes: 5 additions & 0 deletions src/Luban.Core/Types/TInt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,9 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
{
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
5 changes: 5 additions & 0 deletions src/Luban.Core/Types/TList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,9 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
{
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
5 changes: 5 additions & 0 deletions src/Luban.Core/Types/TLong.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,9 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
{
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
5 changes: 5 additions & 0 deletions src/Luban.Core/Types/TMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,9 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
{
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
5 changes: 5 additions & 0 deletions src/Luban.Core/Types/TSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,9 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
{
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
5 changes: 5 additions & 0 deletions src/Luban.Core/Types/TShort.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,9 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
{
return visitor.Accept(this, x, y, z);
}

public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
5 changes: 4 additions & 1 deletion src/Luban.Core/Types/TString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,8 @@ public override TR Apply<TR>(ITypeFuncVisitor<TR> visitor)
return visitor.Accept(this, x, y, z);
}


public override TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w)
{
return visitor.Accept(this, x, y, z, w);
}
}
2 changes: 2 additions & 0 deletions src/Luban.Core/Types/TType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,6 @@ public virtual void PostCompile(DefField field)
public abstract TR Apply<T1, T2, TR>(ITypeFuncVisitor<T1, T2, TR> visitor, T1 x, T2 y);

public abstract TR Apply<T1, T2, T3, TR>(ITypeFuncVisitor<T1, T2, T3, TR> visitor, T1 x, T2 y, T3 z);

public abstract TR Apply<T1, T2, T3, T4, TR>(ITypeFuncVisitor<T1, T2, T3, T4, TR> visitor, T1 x, T2 y, T3 z, T4 w);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class CppRawptrBinTemplateExtension : ScriptObject
{
public static string Deserialize(string bufName, string fieldName, TType type)
{
return type.Apply(CppRawptrDeserializeVisitor.Ins, bufName, fieldName);
return type.Apply(CppRawptrDeserializeVisitor.Ins, bufName, fieldName, 0);
}

public static string DeclaringTypeName(TType type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class CppSharedptrBinTemplateExtension : ScriptObject
{
public static string Deserialize(string bufName, string fieldName, TType type)
{
return type.Apply(CppSharedptrDeserializeVisitor.Ins, bufName, fieldName);
return type.Apply(CppSharedptrDeserializeVisitor.Ins, bufName, fieldName,0);
}

public static string DeclaringTypeName(TType type)
Expand Down
8 changes: 4 additions & 4 deletions src/Luban.Cpp/TypeVisitors/CppRawptrDeserializeVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@

namespace Luban.Cpp.TypeVisitors;

public class CppRawptrDeserializeVisitor : DecoratorFuncVisitor<string, string, string>
public class CppRawptrDeserializeVisitor : DecoratorFuncVisitor<string, string, int, string>
{
public static CppRawptrDeserializeVisitor Ins { get; } = new CppRawptrDeserializeVisitor();

public override string DoAccept(TType type, string bufName, string fieldName)
public override string DoAccept(TType type, string bufName, string fieldName, int depth)
{
if (type.IsNullable)
{
return $"{{ bool _has_value_; if(!{bufName}.readBool(_has_value_)){{return false;}} if(_has_value_) {{ {fieldName} = {(type.IsBean ? "nullptr" : $"new {type.Apply(CppUnderlyingDeclaringTypeNameVisitor.Ins)}{{}}")}; {type.Apply(CppRawptrUnderlyingDeserializeVisitor.Ins, bufName, type.IsBean ? fieldName : $"*{fieldName}", CppRawptrDeclaringTypeNameVisitor.Ins)} }} else {{ {fieldName} = nullptr; }} }}";
return $"{{ bool _has_value_; if(!{bufName}.readBool(_has_value_)){{return false;}} if(_has_value_) {{ {fieldName} = {(type.IsBean ? "nullptr" : $"new {type.Apply(CppUnderlyingDeclaringTypeNameVisitor.Ins)}{{}}")}; {type.Apply(CppRawptrUnderlyingDeserializeVisitor.Ins, bufName, type.IsBean ? fieldName : $"*{fieldName}",depth + 1, CppRawptrDeclaringTypeNameVisitor.Ins)} }} else {{ {fieldName} = nullptr; }} }}";
}
else
{
return type.Apply(CppRawptrUnderlyingDeserializeVisitor.Ins, bufName, fieldName, CppRawptrDeclaringTypeNameVisitor.Ins);
return type.Apply(CppRawptrUnderlyingDeserializeVisitor.Ins, bufName, fieldName, depth, CppRawptrDeclaringTypeNameVisitor.Ins);
}
}
}
8 changes: 4 additions & 4 deletions src/Luban.Cpp/TypeVisitors/CppSharedptrDeserializeVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@

namespace Luban.Cpp.TypeVisitors;

public class CppSharedptrDeserializeVisitor : DecoratorFuncVisitor<string, string, string>
public class CppSharedptrDeserializeVisitor : DecoratorFuncVisitor<string, string, int, string>
{
public static CppSharedptrDeserializeVisitor Ins { get; } = new CppSharedptrDeserializeVisitor();

public override string DoAccept(TType type, string bufName, string fieldName)
public override string DoAccept(TType type, string bufName, string fieldName, int depth)
{
if (type.IsNullable)
{
return $"{{ bool _has_value_; if(!{bufName}.readBool(_has_value_)){{return false;}} if(_has_value_) {{ {fieldName}.reset({(type.IsBean ? "" : $"new {type.Apply(CppUnderlyingDeclaringTypeNameVisitor.Ins)}()")}); {type.Apply(CppSharedptrUnderlyingDeserializeVisitor.Ins, bufName, $"{(type.IsBean ? "" : "*")}{fieldName}", CppSharedptrDeclaringTypeNameVisitor.Ins)} }} else {{ {fieldName}.reset(); }} }}";
return $"{{ bool _has_value_; if(!{bufName}.readBool(_has_value_)){{return false;}} if(_has_value_) {{ {fieldName}.reset({(type.IsBean ? "" : $"new {type.Apply(CppUnderlyingDeclaringTypeNameVisitor.Ins)}()")}); {type.Apply(CppSharedptrUnderlyingDeserializeVisitor.Ins, bufName, $"{(type.IsBean ? "" : "*")}{fieldName}",depth+1, CppSharedptrDeclaringTypeNameVisitor.Ins)} }} else {{ {fieldName}.reset(); }} }}";
}
else
{
return type.Apply(CppSharedptrUnderlyingDeserializeVisitor.Ins, bufName, fieldName, CppSharedptrDeclaringTypeNameVisitor.Ins);
return type.Apply(CppSharedptrUnderlyingDeserializeVisitor.Ins, bufName, fieldName, depth ,CppSharedptrDeclaringTypeNameVisitor.Ins);
}
}
}
44 changes: 24 additions & 20 deletions src/Luban.Cpp/TypeVisitors/CppUnderlyingDeserializeVisitorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,80 +4,84 @@

namespace Luban.Cpp.TypeVisitors;

public abstract class CppUnderlyingDeserializeVisitorBase : ITypeFuncVisitor<string, string, ITypeFuncVisitor<string>, string>
public abstract class CppUnderlyingDeserializeVisitorBase : ITypeFuncVisitor<string, string, int, ITypeFuncVisitor<string>, string>
{
public string Accept(TBool type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TBool type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"if (!{bufName}.readBool({fieldName})) return false;";
}

public string Accept(TByte type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TByte type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"if(!{bufName}.readByte({fieldName})) return false;";
}

public string Accept(TShort type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TShort type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"if(!{bufName}.readShort({fieldName})) return false;";
}

public string Accept(TInt type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TInt type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"if(!{bufName}.readInt({fieldName})) return false;";
}

public string Accept(TLong type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TLong type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"if(!{bufName}.readLong({fieldName})) return false;";
}

public string Accept(TFloat type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TFloat type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"if(!{bufName}.readFloat({fieldName})) return false;";
}

public string Accept(TDouble type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TDouble type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"if(!{bufName}.readDouble({fieldName})) return false;";
}

public string Accept(TEnum type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TEnum type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"{{int __enum_temp__; if(!{bufName}.readInt(__enum_temp__)) return false; {fieldName} = {CppTemplateExtension.MakeTypeCppName(type.DefEnum)}(__enum_temp__); }}";
}

public string Accept(TString type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TString type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"if(!{bufName}.readString({fieldName})) return false;";
}

public string Accept(TBean type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TBean type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"if(!{CppTemplateExtension.MakeTypeCppName(type.DefBean)}::deserialize{type.DefBean.Name}({bufName}, {fieldName})) return false;";
}

public string Accept(TDateTime type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TDateTime type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"if(!{bufName}.readLong({fieldName})) return false;";
}

public string Accept(TArray type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TArray type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, ::luban::int32({bufName}.size()));{fieldName}.reserve(n);for(int i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(typeVisitor)} _e; {type.ElementType.Apply(this, bufName, "_e", typeVisitor)} {fieldName}.push_back(_e);}}}}";
var suffix = depth == 0 ? "" : $"_{depth}";
return $"{{::luban::int32 n{suffix}; if(!{bufName}.readSize(n{suffix})) return false; n{suffix} = std::min(n{suffix}, ::luban::int32({bufName}.size())); {fieldName}.reserve(n{suffix});for(int i{suffix} = 0 ; i{suffix} < n{suffix} ; i{suffix}++) {{ {type.ElementType.Apply(typeVisitor)} _e{suffix}; {type.ElementType.Apply(this, bufName, $"_e{suffix}", depth + 1, typeVisitor)} {fieldName}.push_back(_e{suffix});}}}}";
}

public string Accept(TList type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TList type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, ::luban::int32({bufName}.size())); {fieldName}.reserve(n);for(int i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(typeVisitor)} _e; {type.ElementType.Apply(this, bufName, "_e", typeVisitor)} {fieldName}.push_back(_e);}}}}";
var suffix = depth == 0 ? "" : $"_{depth}";
return $"{{::luban::int32 n{suffix}; if(!{bufName}.readSize(n{suffix})) return false; n{suffix} = std::min(n{suffix}, ::luban::int32({bufName}.size())); {fieldName}.reserve(n{suffix});for(int i{suffix} = 0 ; i{suffix} < n{suffix} ; i{suffix}++) {{ {type.ElementType.Apply(typeVisitor)} _e{suffix}; {type.ElementType.Apply(this, bufName, $"_e{suffix}", depth + 1, typeVisitor)} {fieldName}.push_back(_e{suffix});}}}}";
}

public string Accept(TSet type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TSet type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, ::luban::int32({bufName}.size())); {fieldName}.reserve(n * 3 / 2);for(int i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(typeVisitor)} _e; {type.ElementType.Apply(this, bufName, "_e", typeVisitor)} {fieldName}.insert(_e);}}}}";
var suffix = depth == 0 ? "" : $"_{depth}";
return $"{{::luban::int32 n{suffix}; if(!{bufName}.readSize(n{suffix})) return false; n{suffix} = std::min(n{suffix}, ::luban::int32({bufName}.size())); {fieldName}.reserve(n{suffix} * 3 / 2);for(int i{suffix} = 0 ; i{suffix} < n{suffix} ; i{suffix}++) {{ {type.ElementType.Apply(typeVisitor)} _e{suffix}; {type.ElementType.Apply(this, bufName, $"_e{suffix}", depth + 1, typeVisitor)} {fieldName}.insert(_e{suffix});}}}}";
}

public string Accept(TMap type, string bufName, string fieldName, ITypeFuncVisitor<string> typeVisitor)
public string Accept(TMap type, string bufName, string fieldName, int depth, ITypeFuncVisitor<string> typeVisitor)
{
return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, (::luban::int32){bufName}.size()); {fieldName}.reserve(n * 3 / 2);for(int i = 0 ; i < n ; i++) {{ {type.KeyType.Apply(typeVisitor)} _k; {type.KeyType.Apply(this, bufName, "_k", typeVisitor)} {type.ValueType.Apply(typeVisitor)} _v; {type.ValueType.Apply(this, bufName, "_v", typeVisitor)} {fieldName}[_k] = _v;}}}}";
var suffix = depth == 0 ? "" : $"_{depth}";
return $"{{::luban::int32 n{suffix}; if(!{bufName}.readSize(n{suffix})) return false; n{suffix} = std::min(n{suffix}, (::luban::int32){bufName}.size()); {fieldName}.reserve(n{suffix} * 3 / 2);for(int i{suffix} = 0 ; i{suffix} < n{suffix} ; i{suffix}++) {{ {type.KeyType.Apply(typeVisitor)} _k{suffix}; {type.KeyType.Apply(this, bufName, $"_k{suffix}", depth + 1, typeVisitor)} {type.ValueType.Apply(typeVisitor)} _v{suffix}; {type.ValueType.Apply(this, bufName, $"_v{suffix}",depth + 1, typeVisitor)} {fieldName}[_k{suffix}] = _v{suffix};}}}}";
}
}