<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, Oct 5, 2016 at 10:03 AM Zachary Turner via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: zturner<br class="gmail_msg"><br>Date: Wed Oct  5 11:54:09 2016<br class="gmail_msg"><br>New Revision: 283337<br class="gmail_msg"><br><br class="gmail_msg"><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=283337&view=rev" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project?rev=283337&view=rev</a><br class="gmail_msg"><br>Log:<br class="gmail_msg"><br>Add llvm::enumerate() range adapter.<br class="gmail_msg"><br><br class="gmail_msg"><br>This allows you to enumerate over a range using a range-based<br class="gmail_msg"><br>for while the return type contains the index of the enumeration.<br class="gmail_msg"><br><br class="gmail_msg"><br>Differential revision: <a href="https://reviews.llvm.org/D25124" rel="noreferrer" class="gmail_msg" target="_blank">https://reviews.llvm.org/D25124</a><br class="gmail_msg"><br><br class="gmail_msg"><br>Modified:<br class="gmail_msg"><br>    llvm/trunk/include/llvm/ADT/STLExtras.h<br class="gmail_msg"><br>    llvm/trunk/unittests/ADT/STLExtrasTest.cpp<br class="gmail_msg"><br><br class="gmail_msg"><br>Modified: llvm/trunk/include/llvm/ADT/STLExtras.h<br class="gmail_msg"><br>URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=283337&r1=283336&r2=283337&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=283337&r1=283336&r2=283337&view=diff</a><br class="gmail_msg"><br>==============================================================================<br class="gmail_msg"><br>--- llvm/trunk/include/llvm/ADT/STLExtras.h (original)<br class="gmail_msg"><br>+++ llvm/trunk/include/llvm/ADT/STLExtras.h Wed Oct  5 11:54:09 2016<br class="gmail_msg"><br>@@ -35,7 +35,7 @@ namespace llvm {<br class="gmail_msg"><br> namespace detail {<br class="gmail_msg"><br><br class="gmail_msg"><br> template <typename RangeT><br class="gmail_msg"><br>-using IterOfRange = decltype(std::begin(std::declval<RangeT>()));<br class="gmail_msg"><br>+using IterOfRange = decltype(std::begin(std::declval<RangeT &>()));<br class="gmail_msg"><br><br class="gmail_msg"><br> } // End detail namespace<br class="gmail_msg"><br><br class="gmail_msg"><br>@@ -627,7 +627,7 @@ template <typename T> struct deref {<br class="gmail_msg"><br> };<br class="gmail_msg"><br><br class="gmail_msg"><br> namespace detail {<br class="gmail_msg"><br>-template <typename I, typename V> class enumerator_impl {<br class="gmail_msg"><br>+template <typename R> class enumerator_impl {<br class="gmail_msg"><br> public:<br class="gmail_msg"><br>   template <typename X> struct result_pair {<br class="gmail_msg"><br>     result_pair(std::size_t Index, X Value) : Index(Index), Value(Value) {}<br class="gmail_msg"><br>@@ -636,13 +636,16 @@ public:<br class="gmail_msg"><br>     X Value;<br class="gmail_msg"><br>   };<br class="gmail_msg"><br><br class="gmail_msg"><br>-  struct iterator {<br class="gmail_msg"><br>-    iterator(I Iter, std::size_t Index) : Iter(Iter), Index(Index) {}<br class="gmail_msg"><br>+  class iterator {<br class="gmail_msg"><br>+    typedef<br class="gmail_msg"><br>+        typename std::iterator_traits<IterOfRange<R>>::reference iter_reference;<br class="gmail_msg"><br>+    typedef result_pair<iter_reference> result_type;<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+  public:<br class="gmail_msg"><br>+    iterator(IterOfRange<R> &&Iter, std::size_t Index)<br class="gmail_msg"><br>+        : Iter(Iter), Index(Index) {}<br class="gmail_msg"><br><br class="gmail_msg"><br>-    result_pair<const V> operator*() const {<br class="gmail_msg"><br>-      return result_pair<const V>(Index, *Iter);<br class="gmail_msg"><br>-    }<br class="gmail_msg"><br>-    result_pair<V> operator*() { return result_pair<V>(Index, *Iter); }<br class="gmail_msg"><br>+    result_type operator*() const { return result_type(Index, *Iter); }<br class="gmail_msg"><br><br class="gmail_msg"><br>     iterator &operator++() {<br class="gmail_msg"><br>       ++Iter;<br class="gmail_msg"><br>@@ -653,28 +656,19 @@ public:<br class="gmail_msg"><br>     bool operator!=(const iterator &RHS) const { return Iter != RHS.Iter; }<br class="gmail_msg"><br><br class="gmail_msg"><br>   private:<br class="gmail_msg"><br>-    I Iter;<br class="gmail_msg"><br>+    IterOfRange<R> Iter;<br class="gmail_msg"><br>     std::size_t Index;<br class="gmail_msg"><br>   };<br class="gmail_msg"><br><br class="gmail_msg"><br>-  enumerator_impl(I Begin, I End)<br class="gmail_msg"><br>-      : Begin(std::move(Begin)), End(std::move(End)) {}<br class="gmail_msg"><br>-<br class="gmail_msg"><br>-  iterator begin() { return iterator(Begin, 0); }<br class="gmail_msg"><br>-  iterator end() { return iterator(End, std::size_t(-1)); }<br class="gmail_msg"><br>+public:<br class="gmail_msg"><br>+  explicit enumerator_impl(R &&Range) : Range(std::forward<R>(Range)) {}<br class="gmail_msg"><br><br class="gmail_msg"><br>-  iterator begin() const { return iterator(Begin, 0); }<br class="gmail_msg"><br>-  iterator end() const { return iterator(End, std::size_t(-1)); }<br class="gmail_msg"><br>+  iterator begin() { return iterator(std::begin(Range), 0); }<br class="gmail_msg"><br>+  iterator end() { return iterator(std::end(Range), std::size_t(-1)); }<br class="gmail_msg"><br><br class="gmail_msg"><br> private:<br class="gmail_msg"><br>-  I Begin;<br class="gmail_msg"><br>-  I End;<br class="gmail_msg"><br>+  R Range;<br class="gmail_msg"><br> };<br class="gmail_msg"><br>-<br class="gmail_msg"><br>-template <typename I><br class="gmail_msg"><br>-auto make_enumerator(I Begin, I End) -> enumerator_impl<I, decltype(*Begin)> {<br class="gmail_msg"><br>-  return enumerator_impl<I, decltype(*Begin)>(std::move(Begin), std::move(End));<br class="gmail_msg"><br>-}<br class="gmail_msg"><br> }<br class="gmail_msg"><br><br class="gmail_msg"><br> /// Given an input range, returns a new range whose values are are pair (A,B)<br class="gmail_msg"><br>@@ -692,10 +686,8 @@ auto make_enumerator(I Begin, I End) -><br class="gmail_msg"><br> ///   Item 2 - C<br class="gmail_msg"><br> ///   Item 3 - D<br class="gmail_msg"><br> ///<br class="gmail_msg"><br>-template <typename R><br class="gmail_msg"><br>-auto enumerate(R &&Range)<br class="gmail_msg"><br>-    -> decltype(detail::make_enumerator(std::begin(Range), std::end(Range))) {<br class="gmail_msg"><br>-  return detail::make_enumerator(std::begin(Range), std::end(Range));<br class="gmail_msg"><br>+template <typename R> detail::enumerator_impl<R> enumerate(R &&Range) {<br class="gmail_msg"><br>+  return detail::enumerator_impl<R>(std::forward<R>(Range));<br class="gmail_msg"><br> }<br class="gmail_msg"><br><br class="gmail_msg"><br> } // End llvm namespace<br class="gmail_msg"><br><br class="gmail_msg"><br>Modified: llvm/trunk/unittests/ADT/STLExtrasTest.cpp<br class="gmail_msg"><br>URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/STLExtrasTest.cpp?rev=283337&r1=283336&r2=283337&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/STLExtrasTest.cpp?rev=283337&r1=283336&r2=283337&view=diff</a><br class="gmail_msg"><br>==============================================================================<br class="gmail_msg"><br>--- llvm/trunk/unittests/ADT/STLExtrasTest.cpp (original)<br class="gmail_msg"><br>+++ llvm/trunk/unittests/ADT/STLExtrasTest.cpp Wed Oct  5 11:54:09 2016<br class="gmail_msg"><br>@@ -39,51 +39,152 @@ TEST(STLExtrasTest, Rank) {<br class="gmail_msg"><br>   EXPECT_EQ(4, f(rank<6>()));<br class="gmail_msg"><br> }<br class="gmail_msg"><br><br class="gmail_msg"><br>-TEST(STLExtrasTest, Enumerate) {<br class="gmail_msg"><br>+TEST(STLExtrasTest, EnumerateLValue) {<br class="gmail_msg"></blockquote><div><br>This seems like a long/complex test function - could it be simpler/clearer what's being tested?<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>+  // Test that a simple LValue can be enumerated and gives correct results with<br class="gmail_msg"><br>+  // multiple types, including the empty container.<br class="gmail_msg"><br>   std::vector<char> foo = {'a', 'b', 'c'};<br class="gmail_msg"></blockquote><div><br>Might be worth using an array rather than a vector for simplicity of code/etc?<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>-<br class="gmail_msg"><br>-  std::vector<std::pair<std::size_t, char>> results;<br class="gmail_msg"><br>+  std::vector<std::pair<std::size_t, char>> CharResults;<br class="gmail_msg"><br><br class="gmail_msg"><br>   for (auto X : llvm::enumerate(foo)) {<br class="gmail_msg"><br>-    results.push_back(std::make_pair(X.Index, X.Value));<br class="gmail_msg"><br>+    CharResults.emplace_back(X.Index, X.Value);<br class="gmail_msg"><br>   }<br class="gmail_msg"><br>-  ASSERT_EQ(3u, results.size());<br class="gmail_msg"><br>-  EXPECT_EQ(0u, results[0].first);<br class="gmail_msg"><br>-  EXPECT_EQ('a', results[0].second);<br class="gmail_msg"><br>-  EXPECT_EQ(1u, results[1].first);<br class="gmail_msg"><br>-  EXPECT_EQ('b', results[1].second);<br class="gmail_msg"><br>-  EXPECT_EQ(2u, results[2].first);<br class="gmail_msg"><br>-  EXPECT_EQ('c', results[2].second);<br class="gmail_msg"><br>-<br class="gmail_msg"><br>-  results.clear();<br class="gmail_msg"><br>-  const std::vector<int> bar = {'1', '2', '3'};<br class="gmail_msg"><br>+  ASSERT_EQ(3u, CharResults.size());<br class="gmail_msg"><br>+  EXPECT_EQ(std::make_pair(0u, 'a'), CharResults[0]);<br class="gmail_msg"><br>+  EXPECT_EQ(std::make_pair(1u, 'b'), CharResults[1]);<br class="gmail_msg"><br>+  EXPECT_EQ(std::make_pair(2u, 'c'), CharResults[2]);<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+  // Test a const range of a different type.<br class="gmail_msg"></blockquote><div><br></div><div>Looks like this should begin a separate test function? (& then you wouldn't need to use different names for the result vectors)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>+  std::vector<std::pair<std::size_t, int>> IntResults;<br class="gmail_msg"><br>+  const std::vector<int> bar = {1, 2, 3};<br class="gmail_msg"><br>   for (auto X : llvm::enumerate(bar)) {<br class="gmail_msg"><br>-    results.push_back(std::make_pair(X.Index, X.Value));<br class="gmail_msg"><br>+    IntResults.emplace_back(X.Index, X.Value);<br class="gmail_msg"><br>   }<br class="gmail_msg"><br>-  EXPECT_EQ(0u, results[0].first);<br class="gmail_msg"><br>-  EXPECT_EQ('1', results[0].second);<br class="gmail_msg"><br>-  EXPECT_EQ(1u, results[1].first);<br class="gmail_msg"><br>-  EXPECT_EQ('2', results[1].second);<br class="gmail_msg"><br>-  EXPECT_EQ(2u, results[2].first);<br class="gmail_msg"><br>-  EXPECT_EQ('3', results[2].second);<br class="gmail_msg"><br>+  ASSERT_EQ(3u, IntResults.size());<br class="gmail_msg"><br>+  EXPECT_EQ(std::make_pair(0u, 1), IntResults[0]);<br class="gmail_msg"><br>+  EXPECT_EQ(std::make_pair(1u, 2), IntResults[1]);<br class="gmail_msg"><br>+  EXPECT_EQ(std::make_pair(2u, 3), IntResults[2]);<br class="gmail_msg"><br><br class="gmail_msg"><br>-  results.clear();<br class="gmail_msg"><br>+  // Test an empty range.<br class="gmail_msg"></blockquote><div><br>And here<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>+  IntResults.clear();<br class="gmail_msg"><br>   const std::vector<int> baz;<br class="gmail_msg"><br>   for (auto X : llvm::enumerate(baz)) {<br class="gmail_msg"></blockquote><div><br>This test case should perhaps be more like:<br><br>const std::vector<int> baz; (I was going to suggest an array, but you can't have zero length arrays... )<br>auto R = llvm::enumerate(baz);<br>CHECK_EQ(R.begin(), R.end());<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>-    results.push_back(std::make_pair(X.Index, X.Value));<br class="gmail_msg"><br>+    IntResults.emplace_back(X.Index, X.Value);<br class="gmail_msg"><br>   }<br class="gmail_msg"><br>-  EXPECT_TRUE(baz.empty());<br class="gmail_msg"><br>+  EXPECT_TRUE(IntResults.empty());<br class="gmail_msg"><br> }<br class="gmail_msg"><br><br class="gmail_msg"><br>-TEST(STLExtrasTest, EnumerateModify) {<br class="gmail_msg"><br>+TEST(STLExtrasTest, EnumerateModifyLValue) {<br class="gmail_msg"><br>+  // Test that you can modify the underlying entries of an lvalue range through<br class="gmail_msg"><br>+  // the enumeration iterator.<br class="gmail_msg"><br>   std::vector<char> foo = {'a', 'b', 'c'};<br class="gmail_msg"><br><br class="gmail_msg"><br>   for (auto X : llvm::enumerate(foo)) {<br class="gmail_msg"><br>     ++X.Value;<br class="gmail_msg"></blockquote><div><br>(as with feedback later (wrote this out of order) for EnumerateModifyRValue, this might be simpler and just test a single case)<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>   }<br class="gmail_msg"><br>-<br class="gmail_msg"><br>   EXPECT_EQ('b', foo[0]);<br class="gmail_msg"><br>   EXPECT_EQ('c', foo[1]);<br class="gmail_msg"><br>   EXPECT_EQ('d', foo[2]);<br class="gmail_msg"><br> }<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+TEST(STLExtrasTest, EnumerateRValueRef) {<br class="gmail_msg"><br>+  // Test that an rvalue can be enumerated.<br class="gmail_msg"><br>+  std::vector<std::pair<std::size_t, int>> Results;<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+  auto Enumerator = llvm::enumerate(std::vector<int>{1, 2, 3});<br class="gmail_msg"></blockquote><div><br>Dead code ^ ?<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>+<br class="gmail_msg"><br>+  for (auto X : llvm::enumerate(std::vector<unsigned>{1, 2, 3})) {<br class="gmail_msg"><br>+    Results.emplace_back(X.Index, X.Value);<br class="gmail_msg"></blockquote><div><br>might be more compact to skip the extra data structure (Results):<br><br>  unsigned i = 0;<br>  for ...<br>    EXPECT_EQ(i, X.Index);<br>    EXPECT_EQ(++i, X.Value);<br>  }<br>  EXPECT_EQ(i, 3);<br><br>perhaps? (similarly for other tests)<br><br>Though there's something to be said for having the EXPECTs not inside the loop to make them distinct lines to fail on so the diagnostics from gtest are more legible, etc. Just avoiding extra data structures, etc, seems good too... *ponders*<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>+  }<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+  ASSERT_EQ(3u, Results.size());<br class="gmail_msg"><br>+  EXPECT_EQ(std::make_pair(0u, 1), Results[0]);<br class="gmail_msg"><br>+  EXPECT_EQ(std::make_pair(1u, 2), Results[1]);<br class="gmail_msg"><br>+  EXPECT_EQ(std::make_pair(2u, 3), Results[2]);<br class="gmail_msg"><br>+}<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+TEST(STLExtrasTest, EnumerateModifyRValue) {<br class="gmail_msg"><br>+  // Test that when enumerating an rvalue, modification still works (even if<br class="gmail_msg"><br>+  // this isn't terribly useful, it at least shows that we haven't snuck an<br class="gmail_msg"><br>+  // extra const in there somewhere.<br class="gmail_msg"><br>+  std::vector<std::pair<std::size_t, char>> Results;<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+  for (auto X : llvm::enumerate(std::vector<char>{'1', '2', '3'})) {<br class="gmail_msg"></blockquote><div><br>This probably only needs one value, and maybe not a range-for loop. Something like this, perhaps:<br><br>  auto I = llvm::enumerate(std::vector<int>{1}).begin();<br>  ++I.Value;</div><div>  EXPECT_EQ(2, I.Value);<br><br>(It could check that the sequence isn't empty when given a single element, but other tests should cover that anyway)<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>+    ++X.Value;<br class="gmail_msg"><br>+    Results.emplace_back(X.Index, X.Value);<br class="gmail_msg"><br>+  }<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+  ASSERT_EQ(3u, Results.size());<br class="gmail_msg"><br>+  EXPECT_EQ(std::make_pair(0u, '2'), Results[0]);<br class="gmail_msg"><br>+  EXPECT_EQ(std::make_pair(1u, '3'), Results[1]);<br class="gmail_msg"><br>+  EXPECT_EQ(std::make_pair(2u, '4'), Results[2]);<br class="gmail_msg"><br>+}<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+template <bool B> struct CanMove {};<br class="gmail_msg"><br>+template <> struct CanMove<false> {<br class="gmail_msg"><br>+  CanMove(CanMove &&) = delete;<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+  CanMove() = default;<br class="gmail_msg"><br>+  CanMove(const CanMove &) = default;<br class="gmail_msg"><br>+};<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+template <bool B> struct CanCopy {};<br class="gmail_msg"><br>+template <> struct CanCopy<false> {<br class="gmail_msg"><br>+  CanCopy(const CanCopy &) = delete;<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+  CanCopy() = default;<br class="gmail_msg"><br>+  CanCopy(CanCopy &&) = default;<br class="gmail_msg"><br>+};<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+template <bool Moveable, bool Copyable><br class="gmail_msg"><br>+struct Range : CanMove<Moveable>, CanCopy<Copyable> {<br class="gmail_msg"><br>+  explicit Range(int &C, int &M, int &D) : C(C), M(M), D(D) {}<br class="gmail_msg"><br>+  Range(const Range &R) : CanCopy<Copyable>(R), C(R.C), M(R.M), D(R.D) { ++C; }<br class="gmail_msg"><br>+  Range(Range &&R) : CanMove<Moveable>(std::move(R)), C(R.C), M(R.M), D(R.D) {<br class="gmail_msg"><br>+    ++M;<br class="gmail_msg"><br>+  }<br class="gmail_msg"><br>+  ~Range() { ++D; }<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+  int &C;<br class="gmail_msg"><br>+  int &M;<br class="gmail_msg"><br>+  int &D;<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+  int *begin() { return nullptr; }<br class="gmail_msg"><br>+  int *end() { return nullptr; }<br class="gmail_msg"><br>+};<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+TEST(STLExtrasTest, EnumerateLifetimeSemantics) {<br class="gmail_msg"><br>+  // Test that when enumerating lvalues and rvalues, there are no surprise<br class="gmail_msg"><br>+  // copies or moves.<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+  // With an rvalue, it should not be destroyed until the end of the scope.<br class="gmail_msg"><br>+  int Copies = 0;<br class="gmail_msg"><br>+  int Moves = 0;<br class="gmail_msg"><br>+  int Destructors = 0;<br class="gmail_msg"><br>+  {<br class="gmail_msg"><br>+    auto E1 = enumerate(Range<true, false>(Copies, Moves, Destructors));<br class="gmail_msg"><br>+    // Doesn't compile.  rvalue ranges must be moveable.<br class="gmail_msg"><br>+    // auto E2 = enumerate(Range<false, true>(Copies, Moves, Destructors));<br class="gmail_msg"><br>+    EXPECT_EQ(0, Copies);<br class="gmail_msg"><br>+    EXPECT_EQ(1, Moves);<br class="gmail_msg"><br>+    EXPECT_EQ(1, Destructors);<br class="gmail_msg"><br>+  }<br class="gmail_msg"><br>+  EXPECT_EQ(0, Copies);<br class="gmail_msg"><br>+  EXPECT_EQ(1, Moves);<br class="gmail_msg"><br>+  EXPECT_EQ(2, Destructors);<br class="gmail_msg"><br>+<br class="gmail_msg"><br>+  Copies = Moves = Destructors = 0;<br class="gmail_msg"><br>+  // With an lvalue, it should not be destroyed even after the end of the scope.<br class="gmail_msg"><br>+  // lvalue ranges need be neither copyable nor moveable.<br class="gmail_msg"><br>+  Range<false, false> R(Copies, Moves, Destructors);<br class="gmail_msg"><br>+  {<br class="gmail_msg"><br>+    auto Enumerator = enumerate(R);<br class="gmail_msg"><br>+    (void)Enumerator;<br class="gmail_msg"><br>+    EXPECT_EQ(0, Copies);<br class="gmail_msg"><br>+    EXPECT_EQ(0, Moves);<br class="gmail_msg"><br>+    EXPECT_EQ(0, Destructors);<br class="gmail_msg"><br>+  }<br class="gmail_msg"><br>+  EXPECT_EQ(0, Copies);<br class="gmail_msg"><br>+  EXPECT_EQ(0, Moves);<br class="gmail_msg"><br>+  EXPECT_EQ(0, Destructors);<br class="gmail_msg"><br>+}<br class="gmail_msg"><br> }<br class="gmail_msg"><br><br class="gmail_msg"><br><br class="gmail_msg"><br>_______________________________________________<br class="gmail_msg"><br>llvm-commits mailing list<br class="gmail_msg"><br><a href="mailto:llvm-commits@lists.llvm.org" class="gmail_msg" target="_blank">llvm-commits@lists.llvm.org</a><br class="gmail_msg"><br><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" class="gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br class="gmail_msg"><br></blockquote></div></div>