GenerateAssignmentOperator.refscript
This page describes the GenerateAssignmentOperator RefactorScript shipped with VisualGDB.
Overview
This script iterates over all the fields of a class and generates assignment operators (const reference and rvalue).
You can use it by selecting a class in Code Explorer -> Outline, or via Smart Tags in the code editor.
You can easily customize the script by saving it under %LOCALAPPDATA% via the "Save As" button and changing the parts listed below:
1. The 'inline' argument determines whether to an inline constructor vs. a separate declaration and implementation.
2. The ShouldMoveType() function determines whether to wrap that field with "std::move"
Script
[Main, Description("Generate '=' operator"), SuggestFor(Record)]
generator GenerateAssignmentOperator(Record class,
bool inline = true,
bool isMove = false)
{
if (inline)
DoGenerateAssignmentOperator(class, false, false, isMove);
else
{
DoGenerateAssignmentOperator(class, true, false, isMove);
>
DoGenerateAssignmentOperator(class, false, true, isMove);
}
}
generator DoGenerateAssignmentOperator(Record class,
bool declarationOnly,
bool qualifyName,
bool isMove)
{
set argName = "another";
if (qualifyName)
>>$class.QualifiedName &$class.QualifiedName::operator=(
else
>>$class.ShortName &operator=(
if (isMove)
>>$class.ShortName &&$argName
else
>>const $class.ShortName &$argName
if (declarationOnly)
{
>);
return;
}
>)
>{
foreach(decl in class.NonStaticFields)
{
set init = MakeFieldReference(decl, argName, isMove);
> $decl.ShortName = $init;
}
>
> return *this;
>}
}
function ShouldMoveType(TypeRef type)
{
if (type.Resolved.IsPointerOrReference)
return false;
return true;
}
function MakeFieldReference(Field decl, string argName, bool isMove)
{
set ref = argName + "." + decl.ShortName;
if (isMove && ShouldMoveType(decl.Type))
set ref = "std::move(" + ref + ")";
return ref;
}
generator MakeInitializerList(Array decls, string argName, bool isMove)
{
foreach(decl in decls)
{
if (decl.IsFirst)
>> :
else
>> ,
set init = MakeFieldReference(decl, argName, isMove);
> $decl.ShortName($init)
}
}
Sample Input
class SimpleClass
{
public:
int IntField;
void *PointerField;
};
{
public:
int IntField;
void *PointerField;
};
Sample Output
SimpleClass &operator=(SimpleClass &&another)
{
IntField = std::move(another.IntField);
PointerField = another.PointerField;
return *this;
}
A detailed reference on RefactorScript syntax and data model is available here.{
IntField = std::move(another.IntField);
PointerField = another.PointerField;
return *this;
}
See this page for a full list of RefactorScripts shipped with VisualGDB.