Bug 1595750 - Add MakeBackInserter function to create a back-inserting output iterator for nsTArray. r=froydnj
authorSimon Giesecke <sgiesecke@mozilla.com>
Wed, 13 Nov 2019 09:06:42 +0000
changeset 501724 351b6e9f017b4587adaaf4de0d2b209338f1a4a6
parent 501723 4d4982e04e4d1dd63b18b8b35bba555ec62c4e38
child 501725 eec2b47cdc07333154fc07c0576d200076d4f3de
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1595750
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1595750 - Add MakeBackInserter function to create a back-inserting output iterator for nsTArray. r=froydnj Differential Revision: https://phabricator.services.mozilla.com/D52685
xpcom/ds/nsTArray.h
xpcom/tests/gtest/TestTArray.cpp
--- a/xpcom/ds/nsTArray.h
+++ b/xpcom/ds/nsTArray.h
@@ -2725,16 +2725,40 @@ Span<ElementType> MakeSpan(nsTArray_Impl
 }
 
 template <class ElementType, class TArrayAlloc>
 Span<const ElementType> MakeSpan(
     const nsTArray_Impl<ElementType, TArrayAlloc>& aTArray) {
   return aTArray;
 }
 
+template <typename T>
+class nsTArrayBackInserter
+    : public std::iterator<std::output_iterator_tag, void, void, void, void> {
+  nsTArray<T>* mArray;
+
+ public:
+  explicit nsTArrayBackInserter(nsTArray<T>& aArray) : mArray{&aArray} {}
+
+  template <typename O>
+  nsTArrayBackInserter& operator=(O&& aValue) {
+    mArray->EmplaceBack(std::forward<O>(aValue));
+    return *this;
+  }
+
+  nsTArrayBackInserter& operator*() { return *this; }
+
+  void operator++() {}
+};
+
+template <typename T>
+auto MakeBackInserter(nsTArray<T>& aArray) {
+  return nsTArrayBackInserter<T>{aArray};
+}
+
 }  // namespace mozilla
 
 // MOZ_DBG support
 
 template <class E, class Alloc>
 std::ostream& operator<<(std::ostream& aOut,
                          const nsTArray_Impl<E, Alloc>& aTArray) {
   return aOut << mozilla::MakeSpan(aTArray);
--- a/xpcom/tests/gtest/TestTArray.cpp
+++ b/xpcom/tests/gtest/TestTArray.cpp
@@ -438,9 +438,27 @@ TEST(TArray, RemoveElementsAt_ByIterator
   // Based on the implementation of the iterator, we could compare it and
   // itAfter, but we should not rely on such implementation details.
 
   ASSERT_EQ(2, std::distance(array.cbegin(), itAfter));
   const nsTArray<int> expected{1, 2};
   ASSERT_EQ(expected, array);
 }
 
+static_assert(std::is_copy_assignable<decltype(
+                  MakeBackInserter(std::declval<nsTArray<int>&>()))>::value,
+              "output iteraror must be copy-assignable");
+static_assert(std::is_copy_constructible<decltype(
+                  MakeBackInserter(std::declval<nsTArray<int>&>()))>::value,
+              "output iterator must be copy-constructible");
+
+TEST(TArray, MakeBackInserter)
+{
+  const std::vector<int> src{1, 2, 3, 4};
+  nsTArray<int> dst;
+
+  std::copy(src.begin(), src.end(), MakeBackInserter(dst));
+
+  const nsTArray<int> expected{1, 2, 3, 4};
+  ASSERT_EQ(expected, dst);
+}
+
 }  // namespace TestTArray