GenerateCopyConstructors.refscript

This page describes the GenerateCopyConstructors RefactorScript shipped with VisualGDB.

Overview

This script iterates over all the fields of a class and generates copy/move constructors.
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' variable 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 copy/move constructors"), SuggestFor(Record)]
generator GenerateConstructor(Record class, bool inline = true, bool isMove = false)
{
    if (inline)
        DoGenerateConstructor(class, false, false, isMove);
    else
    {
        DoGenerateConstructor(class, true, false, isMove);
>    
        DoGenerateConstructor(class, false, true, isMove);
    }
}

generator DoGenerateConstructor(Record class, bool declarationOnly, bool qualifyName, bool isMove)
{
    set argName = "another";

    if (qualifyName)
>>$class.QualifiedName::$class.ShortName(
    else
>>$class.ShortName(
if (!isMove)
>>const $class.ShortName &$argName
else
>>$class.ShortName &&$argName
    if (declarationOnly)
    {
>);
        return;
    }

>)
    MakeInitializerList(class.NonStaticFields, argName, isMove);
>{
>}
}

function ShouldMoveType(TypeRef type)
{
    if (type.Resolved.IsPointerOrReference)
        return false;
    if (type.Resolved.IsBuiltin)
        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;
};

Sample Output

SimpleClass(SimpleClass &&another)
        : IntField(another.IntField)
        , PointerField(another.PointerField)
{
}
A detailed reference on RefactorScript syntax and data model is available here.
See this page for a full list of RefactorScripts shipped with VisualGDB.