// see also C++ investigation in ~/plg2/cfa2/mycode/string/raii/ctor-calls.cpp

#include <string>
#include <iostream>

using namespace std;

#define HELPER_BODY(param) \
    cout << "early in helper with " << param << endl; \
    param[0] = '+'; \
    cout << "late in helper with " << param << endl;

void helper1( string   q ) { HELPER_BODY(q) }
void helper2( string & q ) { HELPER_BODY(q) }
#undef HELPER_BODY


void calltest_HL() {

    string fred;


    cout << "===" << endl;
    cout << "HL: substring of part" << endl;

    cout << "---" << endl;
    // Calling a by-val function, the only way it supports, in which it gets a private logical copy.
    fred = "abcd";
    cout << "before helper with " << fred << endl;
    helper1( fred.substr(1,3) );
    cout << "after helper with " << fred << endl;

    cout << "---" << endl;
    // Calling a by-ref function, catching side effects the only place STL-string gives them, in an explicit copy.
    fred = "abcd";
    cout << "before helper with " << fred << endl;
    {
        string fred_sub = fred.substr(1,3);
        helper2( fred_sub );
        cout << "after helper with temp having " << fred_sub << endl;
    }
    cout << "after helper with original having " << fred << endl;


    cout << "===" << endl;
    cout << "HL: substring of whole" << endl;

    cout << "---" << endl;
    // Calling a by-val function, the only way it supports, in which it gets a private logical copy.
    fred = "abcd";
    cout << "before helper with " << fred << endl;
    helper1( fred.substr(0,4) );
    cout << "after helper with " << fred << endl;

    cout << "---" << endl;
    // Calling a by-ref function, catching side effects the only place STL-string gives them, in an explicit copy.
    fred = "abcd";
    cout << "before helper with " << fred << endl;
    {
        string fred_sub = fred.substr(0,4);
        helper2( fred_sub );
        cout << "after helper with temp having " << fred_sub << endl;
    }
    cout << "after helper with original having " << fred << endl;



    cout << "===" << endl;
    cout << "HL: whole original string" << endl;

    cout << "---" << endl;
    // Calling a by-val function, the only way it supports, in which it gets a private logical copy.
    fred = "abcd";
    cout << "before helper with " << fred << endl;
    helper1( fred );
    cout << "after helper with " << fred << endl;

    cout << "---" << endl;
    // Calling a by-ref function, sys-style, in which we want to gets its changes as side effects.
    fred = "abcd";
    cout << "before helper with " << fred << endl;
    helper2( fred );
    cout << "after helper with " << fred << endl;

    cout << "---" << endl;
    // Calling a by-ref function, trans-style, in which we give it a logical copy, to prevent it from pulluting our gold one; copy needs explicit variable.
    fred = "abcd";
    cout << "before helper with " << fred << endl;
    {
        string fred_cpy = fred;
        helper2( fred_cpy );
    }
    cout << "after helper with " << fred << endl;
}



int main() {

    calltest_HL();

}
