Merge "profiling: interner: do not construct temporary objects."
diff --git a/src/profiling/memory/interner.h b/src/profiling/memory/interner.h
index 5de578f..379b197 100644
--- a/src/profiling/memory/interner.h
+++ b/src/profiling/memory/interner.h
@@ -20,6 +20,8 @@
 #include <stddef.h>
 #include <set>
 
+#include "perfetto/base/logging.h"
+
 namespace perfetto {
 namespace profiling {
 
@@ -29,7 +31,10 @@
 class Interner {
  private:
   struct Entry {
-    Entry(T d, Interner<T>* in) : data(std::move(d)), interner(in) {}
+    template <typename... U>
+    Entry(Interner<T>* in, U... args)
+        : data(std::forward<U...>(args...)), interner(in) {}
+
     bool operator<(const Entry& other) const { return data < other.data; }
 
     const T data;
@@ -85,12 +90,16 @@
     Interner::Entry* entry_;
   };
 
-  Interned Intern(const T& data) {
-    auto itr = entries_.emplace(data, this);
+  template <typename... U>
+  Interned Intern(U... args) {
+    auto itr = entries_.emplace(this, std::forward<U...>(args...));
     Entry& entry = const_cast<Entry&>(*itr.first);
     entry.ref_count++;
     return Interned(&entry);
   }
+
+  ~Interner() { PERFETTO_DCHECK(entries_.empty()); }
+
   size_t entry_count_for_testing() { return entries_.size(); }
 
  private:
diff --git a/src/profiling/memory/interner_unittest.cc b/src/profiling/memory/interner_unittest.cc
index d94fa17..b282ce4 100644
--- a/src/profiling/memory/interner_unittest.cc
+++ b/src/profiling/memory/interner_unittest.cc
@@ -109,6 +109,25 @@
   }
 }
 
+class NoCopyOrMove {
+ public:
+  NoCopyOrMove(const NoCopyOrMove&) = delete;
+  NoCopyOrMove& operator=(const NoCopyOrMove&) = delete;
+  NoCopyOrMove(const NoCopyOrMove&&) = delete;
+  NoCopyOrMove& operator=(const NoCopyOrMove&&) = delete;
+  NoCopyOrMove(int d) : data(d) {}
+  ~NoCopyOrMove() {}
+  bool operator<(const NoCopyOrMove& other) const { return data < other.data; }
+
+ private:
+  int data;
+};
+
+TEST(InternerStringTest, NoCopyOrMove) {
+  Interner<NoCopyOrMove> interner;
+  Interner<NoCopyOrMove>::Interned interned_str = interner.Intern(1);
+}
+
 }  // namespace
 }  // namespace profiling
 }  // namespace perfetto