[C++] Remove all shared_ptr<string>
diff --git a/func.cc b/func.cc
index fa078f4..20e1226 100644
--- a/func.cc
+++ b/func.cc
@@ -42,11 +42,11 @@
 
 // TODO: This code is very similar to
 // NinjaGenerator::TranslateCommand. Factor them out.
-shared_ptr<string> StripShellComment(shared_ptr<string> cmd) {
+void StripShellComment(string* cmd) {
   if (cmd->find('#') == string::npos)
-    return cmd;
+    return;
 
-  shared_ptr<string> res = make_shared<string>();
+  string res;
   bool prev_backslash = false;
   // Set space as an initial value so the leading comment will be
   // stripped out.
@@ -72,15 +72,15 @@
         } else if (!prev_backslash) {
           quote = *in;
         }
-        *res += *in;
+        res += *in;
         break;
 
       case '\\':
-        *res += '\\';
+        res += '\\';
         break;
 
       default:
-        *res += *in;
+        res += *in;
     }
 
     if (*in == '\\') {
@@ -91,66 +91,66 @@
 
     prev_char = *in;
   }
-  return res;
+  cmd->swap(res);
 }
 
 void PatsubstFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> pat_str = args[0]->Eval(ev);
-  shared_ptr<string> repl = args[1]->Eval(ev);
-  shared_ptr<string> str = args[2]->Eval(ev);
+  const string&& pat_str = args[0]->Eval(ev);
+  const string&& repl = args[1]->Eval(ev);
+  const string&& str = args[2]->Eval(ev);
   WordWriter ww(s);
-  Pattern pat(*pat_str);
-  for (StringPiece tok : WordScanner(*str)) {
+  Pattern pat(pat_str);
+  for (StringPiece tok : WordScanner(str)) {
     ww.MaybeAddWhitespace();
-    pat.AppendSubst(tok, *repl, s);
+    pat.AppendSubst(tok, repl, s);
   }
 }
 
 void StripFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> str = args[0]->Eval(ev);
+  const string&& str = args[0]->Eval(ev);
   WordWriter ww(s);
-  for (StringPiece tok : WordScanner(*str)) {
+  for (StringPiece tok : WordScanner(str)) {
     ww.Write(tok);
   }
 }
 
 void SubstFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> pat = args[0]->Eval(ev);
-  shared_ptr<string> repl = args[1]->Eval(ev);
-  shared_ptr<string> str = args[2]->Eval(ev);
-  if (pat->empty()) {
-    *s += *str;
-    *s += *repl;
+  const string&& pat = args[0]->Eval(ev);
+  const string&& repl = args[1]->Eval(ev);
+  const string&& str = args[2]->Eval(ev);
+  if (pat.empty()) {
+    *s += str;
+    *s += repl;
     return;
   }
   size_t index = 0;
-  while (index < str->size()) {
-    size_t found = str->find(*pat, index);
+  while (index < str.size()) {
+    size_t found = str.find(pat, index);
     if (found == string::npos)
       break;
-    AppendString(StringPiece(*str).substr(index, found - index), s);
-    AppendString(*repl, s);
-    index = found + pat->size();
+    AppendString(StringPiece(str).substr(index, found - index), s);
+    AppendString(repl, s);
+    index = found + pat.size();
   }
-  AppendString(StringPiece(*str).substr(index), s);
+  AppendString(StringPiece(str).substr(index), s);
 }
 
 void FindstringFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> find = args[0]->Eval(ev);
-  shared_ptr<string> in = args[1]->Eval(ev);
-  if (in->find(*find) != string::npos)
-    AppendString(*find, s);
+  const string&& find = args[0]->Eval(ev);
+  const string&& in = args[1]->Eval(ev);
+  if (in.find(find) != string::npos)
+    AppendString(find, s);
 }
 
 void FilterFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> pat_buf = args[0]->Eval(ev);
-  shared_ptr<string> text = args[1]->Eval(ev);
+  const string&& pat_buf = args[0]->Eval(ev);
+  const string&& text = args[1]->Eval(ev);
   vector<Pattern> pats;
-  for (StringPiece pat : WordScanner(*pat_buf)) {
+  for (StringPiece pat : WordScanner(pat_buf)) {
     pats.push_back(Pattern(pat));
   }
   WordWriter ww(s);
-  for (StringPiece tok : WordScanner(*text)) {
+  for (StringPiece tok : WordScanner(text)) {
     for (const Pattern& pat : pats) {
       if (pat.Match(tok)) {
         ww.Write(tok);
@@ -161,14 +161,14 @@
 }
 
 void FilterOutFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> pat_buf = args[0]->Eval(ev);
-  shared_ptr<string> text = args[1]->Eval(ev);
+  const string&& pat_buf = args[0]->Eval(ev);
+  const string&& text = args[1]->Eval(ev);
   vector<Pattern> pats;
-  for (StringPiece pat : WordScanner(*pat_buf)) {
+  for (StringPiece pat : WordScanner(pat_buf)) {
     pats.push_back(Pattern(pat));
   }
   WordWriter ww(s);
-  for (StringPiece tok : WordScanner(*text)) {
+  for (StringPiece tok : WordScanner(text)) {
     bool matched = false;
     for (const Pattern& pat : pats) {
       if (pat.Match(tok)) {
@@ -182,9 +182,9 @@
 }
 
 void SortFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> list = args[0]->Eval(ev);
+  const string&& list = args[0]->Eval(ev);
   vector<StringPiece> toks;
-  WordScanner(*list).Split(&toks);
+  WordScanner(list).Split(&toks);
   sort(toks.begin(), toks.end());
   WordWriter ww(s);
   StringPiece prev;
@@ -207,19 +207,19 @@
 }
 
 void WordFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> n_str = args[0]->Eval(ev);
-  int n = GetNumericValueForFunc(*n_str);
+  const string&& n_str = args[0]->Eval(ev);
+  int n = GetNumericValueForFunc(n_str);
   if (n < 0) {
     ev->Error(StringPrintf(
         "*** non-numeric first argument to `word' function: '%s'.",
-        n_str->c_str()));
+        n_str.c_str()));
   }
   if (n == 0) {
     ev->Error("*** first argument to `word' function must be greater than 0.");
   }
 
-  shared_ptr<string> text = args[1]->Eval(ev);
-  for (StringPiece tok : WordScanner(*text)) {
+  const string&& text = args[1]->Eval(ev);
+  for (StringPiece tok : WordScanner(text)) {
     n--;
     if (n == 0) {
       AppendString(tok, s);
@@ -229,31 +229,31 @@
 }
 
 void WordlistFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> s_str = args[0]->Eval(ev);
-  int si = GetNumericValueForFunc(*s_str);
+  const string&& s_str = args[0]->Eval(ev);
+  int si = GetNumericValueForFunc(s_str);
   if (si < 0) {
     ev->Error(StringPrintf(
         "*** non-numeric first argument to `wordlist' function: '%s'.",
-        s_str->c_str()));
+        s_str.c_str()));
   }
   if (si == 0) {
     ev->Error(StringPrintf(
         "*** invalid first argument to `wordlist' function: %s`",
-        s_str->c_str()));
+        s_str.c_str()));
   }
 
-  shared_ptr<string> e_str = args[1]->Eval(ev);
-  int ei = GetNumericValueForFunc(*e_str);
+  const string&& e_str = args[1]->Eval(ev);
+  int ei = GetNumericValueForFunc(e_str);
   if (ei < 0) {
     ev->Error(StringPrintf(
         "*** non-numeric second argument to `wordlist' function: '%s'.",
-        e_str->c_str()));
+        e_str.c_str()));
   }
 
-  shared_ptr<string> text = args[2]->Eval(ev);
+  const string&& text = args[2]->Eval(ev);
   int i = 0;
   WordWriter ww(s);
-  for (StringPiece tok : WordScanner(*text)) {
+  for (StringPiece tok : WordScanner(text)) {
     i++;
     if (si <= i && i <= ei) {
       ww.Write(tok);
@@ -262,8 +262,8 @@
 }
 
 void WordsFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> text = args[0]->Eval(ev);
-  WordScanner ws(*text);
+  const string&& text = args[0]->Eval(ev);
+  WordScanner ws(text);
   int n = 0;
   for (auto iter = ws.begin(); iter != ws.end(); ++iter)
     n++;
@@ -273,27 +273,27 @@
 }
 
 void FirstwordFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> text = args[0]->Eval(ev);
-  for (StringPiece tok : WordScanner(*text)) {
+  const string&& text = args[0]->Eval(ev);
+  for (StringPiece tok : WordScanner(text)) {
     AppendString(tok, s);
     return;
   }
 }
 
 void LastwordFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> text = args[0]->Eval(ev);
+  const string&& text = args[0]->Eval(ev);
   StringPiece last;
-  for (StringPiece tok : WordScanner(*text)) {
+  for (StringPiece tok : WordScanner(text)) {
     last = tok;
   }
   AppendString(last, s);
 }
 
 void JoinFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> list1 = args[0]->Eval(ev);
-  shared_ptr<string> list2 = args[1]->Eval(ev);
-  WordScanner ws1(*list1);
-  WordScanner ws2(*list2);
+  const string&& list1 = args[0]->Eval(ev);
+  const string&& list2 = args[1]->Eval(ev);
+  WordScanner ws1(list1);
+  WordScanner ws2(list2);
   WordWriter ww(s);
   for (WordScanner::Iterator iter1 = ws1.begin(), iter2 = ws2.begin();
        iter1 != ws1.end() && iter2 != ws2.end();
@@ -306,12 +306,12 @@
 
 void WildcardFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
   COLLECT_STATS("func wildcard time");
-  shared_ptr<string> pat = args[0]->Eval(ev);
+  const string&& pat = args[0]->Eval(ev);
   // Note GNU make does not delay the execution of $(wildcard) so we
   // do not need to check avoid_io here.
   WordWriter ww(s);
   vector<string>* files;
-  for (StringPiece tok : WordScanner(*pat)) {
+  for (StringPiece tok : WordScanner(pat)) {
     ScopedTerminator st(tok);
     Glob(tok.data(), &files);
     sort(files->begin(), files->end());
@@ -322,18 +322,18 @@
 }
 
 void DirFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> text = args[0]->Eval(ev);
+  const string&& text = args[0]->Eval(ev);
   WordWriter ww(s);
-  for (StringPiece tok : WordScanner(*text)) {
+  for (StringPiece tok : WordScanner(text)) {
     ww.Write(Dirname(tok));
     s->push_back('/');
   }
 }
 
 void NotdirFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> text = args[0]->Eval(ev);
+  const string&& text = args[0]->Eval(ev);
   WordWriter ww(s);
-  for (StringPiece tok : WordScanner(*text)) {
+  for (StringPiece tok : WordScanner(text)) {
     if (tok == "/") {
       ww.Write(StringPiece(""));
     } else {
@@ -343,9 +343,9 @@
 }
 
 void SuffixFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> text = args[0]->Eval(ev);
+  const string&& text = args[0]->Eval(ev);
   WordWriter ww(s);
-  for (StringPiece tok : WordScanner(*text)) {
+  for (StringPiece tok : WordScanner(text)) {
     StringPiece suf = GetExt(tok);
     if (!suf.empty())
       ww.Write(suf);
@@ -353,44 +353,44 @@
 }
 
 void BasenameFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> text = args[0]->Eval(ev);
+  const string&& text = args[0]->Eval(ev);
   WordWriter ww(s);
-  for (StringPiece tok : WordScanner(*text)) {
+  for (StringPiece tok : WordScanner(text)) {
     ww.Write(StripExt(tok));
   }
 }
 
 void AddsuffixFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> suf = args[0]->Eval(ev);
-  shared_ptr<string> text = args[1]->Eval(ev);
+  const string&& suf = args[0]->Eval(ev);
+  const string&& text = args[1]->Eval(ev);
   WordWriter ww(s);
-  for (StringPiece tok : WordScanner(*text)) {
+  for (StringPiece tok : WordScanner(text)) {
     ww.Write(tok);
-    *s += *suf;
+    *s += suf;
   }
 }
 
 void AddprefixFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> pre = args[0]->Eval(ev);
-  shared_ptr<string> text = args[1]->Eval(ev);
+  const string&& pre = args[0]->Eval(ev);
+  const string&& text = args[1]->Eval(ev);
   WordWriter ww(s);
-  for (StringPiece tok : WordScanner(*text)) {
-    ww.Write(*pre);
+  for (StringPiece tok : WordScanner(text)) {
+    ww.Write(pre);
     AppendString(tok, s);
   }
 }
 
 void RealpathFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> text = args[0]->Eval(ev);
+  const string&& text = args[0]->Eval(ev);
   if (ev->avoid_io()) {
     *s += "$(realpath ";
-    *s += *text;
+    *s += text;
     *s += " 2> /dev/null)";
     return;
   }
 
   WordWriter ww(s);
-  for (StringPiece tok : WordScanner(*text)) {
+  for (StringPiece tok : WordScanner(text)) {
     ScopedTerminator st(tok);
     char buf[PATH_MAX];
     if (realpath(tok.data(), buf))
@@ -399,18 +399,18 @@
 }
 
 void AbspathFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> text = args[0]->Eval(ev);
+  const string&& text = args[0]->Eval(ev);
   WordWriter ww(s);
   string buf;
-  for (StringPiece tok : WordScanner(*text)) {
+  for (StringPiece tok : WordScanner(text)) {
     AbsPath(tok, &buf);
     ww.Write(buf);
   }
 }
 
 void IfFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> cond = args[0]->Eval(ev);
-  if (cond->empty()) {
+  const string&& cond = args[0]->Eval(ev);
+  if (cond.empty()) {
     if (args.size() > 2)
       args[2]->Eval(ev, s);
   } else {
@@ -419,36 +419,36 @@
 }
 
 void AndFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> cond;
+  string cond;
   for (Value* a : args) {
     cond = a->Eval(ev);
-    if (cond->empty())
+    if (cond.empty())
       return;
   }
-  if (cond.get()) {
-    *s += *cond;
+  if (!cond.empty()) {
+    *s += cond;
   }
 }
 
 void OrFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
   for (Value* a : args) {
-    shared_ptr<string> cond = a->Eval(ev);
-    if (!cond->empty()) {
-      *s += *cond;
+    const string&& cond = a->Eval(ev);
+    if (!cond.empty()) {
+      *s += cond;
       return;
     }
   }
 }
 
 void ValueFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> var_name = args[0]->Eval(ev);
-  Var* var = ev->LookupVar(Intern(*var_name));
+  const string&& var_name = args[0]->Eval(ev);
+  Var* var = ev->LookupVar(Intern(var_name));
   AppendString(var->String().as_string(), s);
 }
 
 void EvalFunc(const vector<Value*>& args, Evaluator* ev, string*) {
   // TODO: eval leaks everything... for now.
-  //shared_ptr<string> text = args[0]->Eval(ev);
+  //const string text = args[0]->Eval(ev);
   string* text = new string;
   args[0]->Eval(ev, text);
   vector<AST*> asts;
@@ -530,22 +530,23 @@
 }
 
 void ShellFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> cmd = args[0]->Eval(ev);
-  if (ev->avoid_io() && !HasNoIoInShellScript(*cmd)) {
+  string cmd = args[0]->Eval(ev);
+  if (ev->avoid_io() && !HasNoIoInShellScript(cmd)) {
+    StripShellComment(&cmd);
     *s += "$(";
-    *s += *StripShellComment(cmd);
+    *s += cmd;
     *s += ")";
     return;
   }
 
-  shared_ptr<string> shell = ev->EvalVar(kShellSym);
+  const string&& shell = ev->EvalVar(kShellSym);
 
   string out;
   FindCommand* fc = NULL;
-  ShellFuncImpl(*shell, *cmd, &out, &fc);
-  if (ShouldStoreCommandResult(*cmd)) {
+  ShellFuncImpl(shell, cmd, &out, &fc);
+  if (ShouldStoreCommandResult(cmd)) {
     CommandResult* cr = new CommandResult();
-    cr->cmd = *cmd;
+    cr->cmd = cmd;
     cr->find.reset(fc);
     cr->result = out;
     g_command_results.push_back(cr);
@@ -558,12 +559,12 @@
     "0", "1",  "2",  "3",  "4",  "5",  "6",  "7",  "8",  "9"
   };
 
-  shared_ptr<string> func_name = args[0]->Eval(ev);
-  Var* func = ev->LookupVar(Intern(*func_name));
+  const string&& func_name = args[0]->Eval(ev);
+  Var* func = ev->LookupVar(Intern(func_name));
   vector<unique_ptr<SimpleVar>> av;
   for (size_t i = 1; i < args.size(); i++) {
     unique_ptr<SimpleVar> s(
-        new SimpleVar(*args[i]->Eval(ev), VarOrigin::AUTOMATIC));
+        new SimpleVar(args[i]->Eval(ev), VarOrigin::AUTOMATIC));
     av.push_back(move(s));
   }
   vector<unique_ptr<ScopedVar>> sv;
@@ -597,60 +598,60 @@
 }
 
 void ForeachFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> varname = args[0]->Eval(ev);
-  shared_ptr<string> list = args[1]->Eval(ev);
+  const string&& varname = args[0]->Eval(ev);
+  const string&& list = args[1]->Eval(ev);
   WordWriter ww(s);
-  for (StringPiece tok : WordScanner(*list)) {
+  for (StringPiece tok : WordScanner(list)) {
     unique_ptr<SimpleVar> v(new SimpleVar(
         tok.as_string(), VarOrigin::AUTOMATIC));
-    ScopedVar sv(ev->mutable_vars(), Intern(*varname), v.get());
+    ScopedVar sv(ev->mutable_vars(), Intern(varname), v.get());
     ww.MaybeAddWhitespace();
     args[2]->Eval(ev, s);
   }
 }
 
 void OriginFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> var_name = args[0]->Eval(ev);
-  Var* var = ev->LookupVar(Intern(*var_name));
+  const string&& var_name = args[0]->Eval(ev);
+  Var* var = ev->LookupVar(Intern(var_name));
   *s += GetOriginStr(var->Origin());
 }
 
 void FlavorFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
-  shared_ptr<string> var_name = args[0]->Eval(ev);
-  Var* var = ev->LookupVar(Intern(*var_name));
+  const string&& var_name = args[0]->Eval(ev);
+  Var* var = ev->LookupVar(Intern(var_name));
   *s += var->Flavor();
 }
 
 void InfoFunc(const vector<Value*>& args, Evaluator* ev, string*) {
-  shared_ptr<string> a = args[0]->Eval(ev);
+  const string&& a = args[0]->Eval(ev);
   if (ev->avoid_io()) {
-    ev->add_delayed_output_command(StringPrintf("echo '%s'", a->c_str()));
+    ev->add_delayed_output_command(StringPrintf("echo '%s'", a.c_str()));
     return;
   }
-  printf("%s\n", a->c_str());
+  printf("%s\n", a.c_str());
   fflush(stdout);
 }
 
 void WarningFunc(const vector<Value*>& args, Evaluator* ev, string*) {
-  shared_ptr<string> a = args[0]->Eval(ev);
+  const string&& a = args[0]->Eval(ev);
   if (ev->avoid_io()) {
     ev->add_delayed_output_command(
-        StringPrintf("echo '%s:%d: %s' 2>&1", LOCF(ev->loc()), a->c_str()));
+        StringPrintf("echo '%s:%d: %s' 2>&1", LOCF(ev->loc()), a.c_str()));
     return;
   }
-  printf("%s:%d: %s\n", LOCF(ev->loc()), a->c_str());
+  printf("%s:%d: %s\n", LOCF(ev->loc()), a.c_str());
   fflush(stdout);
 }
 
 void ErrorFunc(const vector<Value*>& args, Evaluator* ev, string*) {
-  shared_ptr<string> a = args[0]->Eval(ev);
+  const string&& a = args[0]->Eval(ev);
   if (ev->avoid_io()) {
     ev->add_delayed_output_command(
         StringPrintf("echo '%s:%d: *** %s.' 2>&1 && false",
-                     LOCF(ev->loc()), a->c_str()));
+                     LOCF(ev->loc()), a.c_str()));
     return;
   }
-  ev->Error(StringPrintf("*** %s.", a->c_str()));
+  ev->Error(StringPrintf("*** %s.", a.c_str()));
 }
 
 FuncInfo g_func_infos[] = {