// see also C++ investigation in ~/plg2/cfa2/mycode/string/raii/ctor-calls.cpp #include #include /* call_substrOfPart: In all cases, of both HL and LL, there is a temporary object. It represents narrowing the range, from full-string, to [1..3]. The only matter to control is whether that temporary shares edits with the string from which it was created. In HL, two knobs control it, and the */ void calltest_HL() { #define HELPER_BODY(param) \ sout | "early in helper with " | param; \ param[0] = '+'; \ sout | "late in helper with " | param; void helper1( string q ) { HELPER_BODY(q) } void helper2( string & q ) { HELPER_BODY(q) } #undef HELPER_BODY string fred; sout | "==="; sout | "HL: substring of part"; sout | "---"; // Calling a by-val function, the only way it supports, in which it gets a private logical copy. fred = "abcd"; sout | "before helper with " | fred; helper1( fred(1,3) ); sout | "after helper with " | fred; sout | "---"; // Calling a by-ref function, sys-style, in which we want to gets its changes as side effects. fred = "abcd"; sout | "before helper with " | fred; helper2( fred(1,3) ); sout | "after helper with " | fred; sout | "---"; // Calling a by-ref function, trans-style, in which we give it a logical copy, to prevent it from pulluting our gold one. fred = "abcd"; sout | "before helper with " | fred; helper2( (string){ fred(1,3) } ); sout | "after helper with " | fred; sout | "==="; sout | "HL: substring of whole"; sout | "---"; // Calling a by-val function, the only way it supports, in which it gets a private logical copy. fred = "abcd"; sout | "before helper with " | fred; helper1( fred(0,4) ); sout | "after helper with " | fred; sout | "---"; // Calling a by-ref function, sys-style, in which we want to gets its changes as side effects. fred = "abcd"; sout | "before helper with " | fred; helper2( fred(0,4) ); sout | "after helper with " | fred; sout | "---"; // Calling a by-ref function, trans-style, in which we give it a logical copy, to prevent it from pulluting our gold one. fred = "abcd"; sout | "before helper with " | fred; helper2( (string){ fred(0,4) } ); sout | "after helper with " | fred; sout | "==="; sout | "HL: whole original string"; sout | "---"; // Calling a by-val function, the only way it supports, in which it gets a private logical copy. fred = "abcd"; sout | "before helper with " | fred; helper1( fred ); sout | "after helper with " | fred; sout | "---"; // Calling a by-ref function, sys-style, in which we want to gets its changes as side effects. fred = "abcd"; sout | "before helper with " | fred; helper2( fred ); sout | "after helper with " | fred; sout | "---"; // Calling a by-ref function, trans-style, in which we give it a logical copy, to prevent it from pulluting our gold one. fred = "abcd"; sout | "before helper with " | fred; helper2( (string){ fred } ); sout | "after helper with " | fred; } void calltest_LL() { #define HELPER_BODY(param) \ sout | "early in helper with " | param; \ assignAt(param, 0, '+'); \ sout | "late in helper with " | param; void helper1( string_res & q ) { HELPER_BODY(q) } // arg should always be a temporary constructed with COPY_VALUE void helper2( string_res & q ) { HELPER_BODY(q) } // arg can refer to whatever you want #undef HELPER_BODY /* In LL, both functions are translated to the same thing. "The only allowed call of #1" becomes respecting the restriction of the comment at helper1. A sys call of #2 is different from the only allowed call of #1. A trans call of #2 is the same as the only allowed call of #1. */ string_res fred; sout | "==="; sout | "LL: substring of part"; sout | "---"; // Calling a by-val function, the only way it supports, in which it gets a private logical copy. fred = "abcd"; sout | "before helper with " | fred; helper1( (string_res){ fred, COPY_VALUE, 1, 3 } ); sout | "after helper with " | fred; sout | "---"; // Calling a by-ref function, sys-style, in which we want to gets its changes as side effects. fred = "abcd"; sout | "before helper with " | fred; helper2( (string_res){ fred, SHARE_EDITS, 1, 3 } ); sout | "after helper with " | fred; sout | "---"; // Calling a by-ref function, trans-style, in which we give it a logical copy, to prevent it from pulluting our gold one. fred = "abcd"; sout | "before helper with " | fred; helper2( (string_res){ fred, COPY_VALUE, 1, 3 } ); sout | "after helper with " | fred; sout | "==="; sout | "LL: substring of whole"; sout | "---"; // Calling a by-val function, the only way it supports, in which it gets a private logical copy. fred = "abcd"; sout | "before helper with " | fred; helper1( (string_res){ fred, COPY_VALUE, 0, 4 } ); sout | "after helper with " | fred; sout | "---"; // Calling a by-ref function, sys-style, in which we want to gets its changes as side effects. fred = "abcd"; sout | "before helper with " | fred; helper2( (string_res){ fred, SHARE_EDITS, 0, 4 } ); sout | "after helper with " | fred; sout | "---"; // Calling a by-ref function, trans-style, in which we give it a logical copy, to prevent it from pulluting our gold one. fred = "abcd"; sout | "before helper with " | fred; helper2( (string_res){ fred, COPY_VALUE, 0, 4 } ); sout | "after helper with " | fred; sout | "==="; sout | "LL: whole original string"; sout | "---"; // Calling a by-val function, the only way it supports, in which it gets a private logical copy. fred = "abcd"; sout | "before helper with " | fred; helper1( (string_res){ fred, COPY_VALUE } ); sout | "after helper with " | fred; sout | "---"; // Calling a by-ref function, sys-style, in which we want to gets its changes as side effects. fred = "abcd"; sout | "before helper with " | fred; helper2( fred ); sout | "after helper with " | fred; sout | "---"; // Calling a by-ref function, trans-style, in which we give it a logical copy, to prevent it from pulluting our gold one. fred = "abcd"; sout | "before helper with " | fred; helper2( (string_res){ fred, COPY_VALUE } ); sout | "after helper with " | fred; } int main() { calltest_HL(); calltest_LL(); }