[C++] The first commit for C++ version

16 tests out of 169 are passing.
diff --git a/dep.cc b/dep.cc
new file mode 100644
index 0000000..426b1a2
--- /dev/null
+++ b/dep.cc
@@ -0,0 +1,193 @@
+#include "dep.h"
+
+#include <memory>
+
+#include "log.h"
+#include "rule.h"
+#include "var.h"
+
+static vector<DepNode*>* g_dep_node_pool;
+
+DepNode::DepNode(StringPiece o, bool p)
+    : output(o),
+      has_rule(false),
+      is_order_only(false),
+      is_phony(p),
+      target_specific_vars(NULL) {
+  g_dep_node_pool->push_back(this);
+}
+
+class DepBuilder {
+ public:
+  DepBuilder(const vector<Rule*>& rules,
+             const Vars& vars,
+             const unordered_map<StringPiece, Vars*>& rule_vars)
+      : vars_(vars),
+        rule_vars_(rule_vars),
+        first_rule_(NULL) {
+    PopulateRules(rules);
+  }
+
+  void Build(vector<StringPiece> targets,
+             vector<DepNode*>* nodes) {
+    if (targets.empty()) {
+      if (!first_rule_) {
+        ERROR("*** No targets.");
+      }
+      CHECK(!first_rule_->outputs.empty());
+      targets.push_back(first_rule_->outputs[0]);
+    }
+
+    // TODO: LogStats?
+
+    for (StringPiece target : targets) {
+      unique_ptr<Vars> tsvs(new Vars);
+      DepNode* n = BuildPlan(target, "", tsvs.get());
+      nodes->push_back(n);
+    }
+  }
+
+ private:
+  void PopulateRules(const vector<Rule*>& rules) {
+    for (Rule* rule : rules) {
+      if (rule->outputs.empty()) {
+        PopulateImplicitRule(rule);
+      } else {
+        PopulateExplicitRule(rule);
+      }
+    }
+  }
+
+  void PopulateExplicitRule(Rule* rule) {
+    for (StringPiece output : rule->outputs) {
+      // isSuffixRule := db.populateSuffixRule(rule, output)
+
+
+      /*
+          if oldRule, present := db.rules[output]; present {
+     r := mergeRules(oldRule, rule, output, isSuffixRule)
+                                                         db.rules[output] = r
+                                                         } else {
+        db.rules[output] = rule
+            if db.firstRule == nil && !strings.HasPrefix(output, ".") {
+                db.firstRule = rule
+              }
+      }
+      */
+
+      auto p = rules_.insert(make_pair(output, rule));
+      if (p.second) {
+        if (!first_rule_ && output.get(0) != '.') {
+          first_rule_ = rule;
+        }
+      } else {
+        // TODO: merge
+        CHECK(false);
+      }
+    }
+  }
+
+  void PopulateImplicitRule(Rule*) {
+    CHECK(false);
+  }
+
+  Rule* LookupRule(StringPiece o) {
+    auto found = rules_.find(o);
+    if (found != rules_.end())
+      return found->second;
+    return NULL;
+  }
+
+  Vars* LookupRuleVars(StringPiece o) {
+    auto found = rule_vars_.find(o);
+    if (found != rule_vars_.end())
+      return found->second;
+    return NULL;
+  }
+
+  bool PickRule(StringPiece output, Rule** r, Vars** v) {
+    Rule* rule = LookupRule(output);
+    Vars* vars = LookupRuleVars(output);
+    *r = rule;
+    *v = vars;
+    if (rule) {
+      if (!rule->cmds.empty()) {
+        return true;
+      }
+    }
+    return rule;
+  }
+
+  DepNode* BuildPlan(StringPiece output, StringPiece needed_by, Vars* tsvs) {
+    LOG("BuildPlan: %s for %s",
+        output.as_string().c_str(),
+        needed_by.as_string().c_str());
+
+    auto found = done_.find(output);
+    if (found != done_.end()) {
+      return found->second;
+    }
+
+    DepNode* n = new DepNode(output, phony_[output]);
+    done_[output] = n;
+
+    Rule* rule;
+    Vars* vars;
+    if (!PickRule(output, &rule, &vars)) {
+      return n;
+    }
+
+    // TODO: Handle TSVs
+
+    for (StringPiece input : rule->inputs) {
+      if (rule->output_patterns.size() > 0) {
+        if (rule->output_patterns.size() > 1) {
+          ERROR("TODO: multiple output pattern is not supported yet");
+        }
+        ERROR("TODO");
+      }
+
+      n->actual_inputs.push_back(input);
+      DepNode* c = BuildPlan(input, output, tsvs);
+      n->deps.push_back(c);
+    }
+
+    // TODO: order only
+    n->has_rule = true;
+    n->cmds = rule->cmds;
+
+    return n;
+  }
+
+  unordered_map<StringPiece, Rule*> rules_;
+  const Vars& vars_;
+  const unordered_map<StringPiece, Vars*>& rule_vars_;
+
+  vector<Rule*> implicit_rules_;   // pattern=%. no prefix,suffix.
+  //vector<Rule*> iprefix_rules_;   // pattern=prefix%..  may have suffix
+  //vector<Rule*> isuffix_rules_;   // pattern=%suffix  no prefix
+
+  unordered_map<StringPiece, vector<Rule*>> suffix_rules_;
+  Rule* first_rule_;
+  unordered_map<StringPiece, DepNode*> done_;
+  unordered_map<StringPiece, bool> phony_;
+};
+
+void MakeDep(const vector<Rule*>& rules,
+             const Vars& vars,
+             const unordered_map<StringPiece, Vars*>& rule_vars,
+             const vector<StringPiece>& targets,
+             vector<DepNode*>* nodes) {
+  DepBuilder db(rules, vars, rule_vars);
+  db.Build(targets, nodes);
+}
+
+void InitDepNodePool() {
+  g_dep_node_pool = new vector<DepNode*>;
+}
+
+void QuitDepNodePool() {
+  for (DepNode* n : *g_dep_node_pool)
+    delete n;
+  delete g_dep_node_pool;
+}