Add reverse iterators to CFX String classes.

Reverse iteration with signed lengths and indices is kinda icky
without this abstraction, and STL provides this pretty much "for
free" given the existing forward iterator.

Change-Id: I97c36c8bd23c0aa48195bc17da7c672292b4cde2
Reviewed-on: https://pdfium-review.googlesource.com/13770
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcrt/cfx_bytestring.h b/core/fxcrt/cfx_bytestring.h
index 432f28a..b976287 100644
--- a/core/fxcrt/cfx_bytestring.h
+++ b/core/fxcrt/cfx_bytestring.h
@@ -8,6 +8,7 @@
 #define CORE_FXCRT_CFX_BYTESTRING_H_
 
 #include <functional>
+#include <iterator>
 #include <sstream>
 #include <utility>
 
@@ -25,6 +26,7 @@
  public:
   using CharType = char;
   using const_iterator = const CharType*;
+  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
   CFX_ByteString();
   CFX_ByteString(const CFX_ByteString& other);
@@ -77,6 +79,14 @@
     return m_pData ? m_pData->m_String + m_pData->m_nDataLength : nullptr;
   }
 
+  // Note: Any subsequent modification of |this| will invalidate iterators.
+  const_reverse_iterator rbegin() const {
+    return const_reverse_iterator(end());
+  }
+  const_reverse_iterator rend() const {
+    return const_reverse_iterator(begin());
+  }
+
   FX_STRSIZE GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; }
   FX_STRSIZE GetStringLength() const {
     return m_pData ? FXSYS_strlen(m_pData->m_String) : 0;
diff --git a/core/fxcrt/cfx_bytestring_unittest.cpp b/core/fxcrt/cfx_bytestring_unittest.cpp
index a4c5187..6bbe305 100644
--- a/core/fxcrt/cfx_bytestring_unittest.cpp
+++ b/core/fxcrt/cfx_bytestring_unittest.cpp
@@ -833,6 +833,73 @@
   }
 }
 
+TEST(fxcrt, ByteStringEmptyReverseIterator) {
+  CFX_ByteString empty;
+  auto iter = empty.rbegin();
+  EXPECT_TRUE(iter == empty.rend());
+  EXPECT_FALSE(iter != empty.rend());
+  EXPECT_FALSE(iter < empty.rend());
+}
+
+TEST(fxcrt, ByteStringOneCharReverseIterator) {
+  CFX_ByteString one_str("a");
+  auto iter = one_str.rbegin();
+  EXPECT_FALSE(iter == one_str.rend());
+  EXPECT_TRUE(iter != one_str.rend());
+  EXPECT_TRUE(iter < one_str.rend());
+
+  char ch = *iter++;
+  EXPECT_EQ('a', ch);
+  EXPECT_TRUE(iter == one_str.rend());
+  EXPECT_FALSE(iter != one_str.rend());
+  EXPECT_FALSE(iter < one_str.rend());
+}
+
+TEST(fxcrt, ByteStringMultiCharReverseIterator) {
+  CFX_ByteString multi_str("abcd");
+  auto iter = multi_str.rbegin();
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  char ch = *iter++;
+  EXPECT_EQ('d', ch);
+  EXPECT_EQ('c', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *(++iter);
+  EXPECT_EQ('b', ch);
+  EXPECT_EQ('b', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter++;
+  EXPECT_EQ('b', ch);
+  EXPECT_EQ('a', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter++;
+  EXPECT_EQ('a', ch);
+  EXPECT_TRUE(iter == multi_str.rend());
+
+  ch = *(--iter);
+  EXPECT_EQ('a', ch);
+  EXPECT_EQ('a', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter--;
+  EXPECT_EQ('a', ch);
+  EXPECT_EQ('b', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter--;
+  EXPECT_EQ('b', ch);
+  EXPECT_EQ('c', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *(--iter);
+  EXPECT_EQ('d', ch);
+  EXPECT_EQ('d', *iter);
+  EXPECT_TRUE(iter == multi_str.rbegin());
+}
+
 TEST(fxcrt, ByteStringCNotNull) {
   CFX_ByteStringC string3("abc");
   CFX_ByteStringC string6("abcdef");
@@ -1200,6 +1267,73 @@
   EXPECT_EQ('a' + 'b' + 'c', sum);
 }
 
+TEST(fxcrt, ByteStringCEmptyReverseIterator) {
+  CFX_ByteStringC empty;
+  auto iter = empty.rbegin();
+  EXPECT_TRUE(iter == empty.rend());
+  EXPECT_FALSE(iter != empty.rend());
+  EXPECT_FALSE(iter < empty.rend());
+}
+
+TEST(fxcrt, ByteStringCOneCharReverseIterator) {
+  CFX_ByteStringC one_str("a");
+  auto iter = one_str.rbegin();
+  EXPECT_FALSE(iter == one_str.rend());
+  EXPECT_TRUE(iter != one_str.rend());
+  EXPECT_TRUE(iter < one_str.rend());
+
+  char ch = *iter++;
+  EXPECT_EQ('a', ch);
+  EXPECT_TRUE(iter == one_str.rend());
+  EXPECT_FALSE(iter != one_str.rend());
+  EXPECT_FALSE(iter < one_str.rend());
+}
+
+TEST(fxcrt, ByteStringCMultiCharReverseIterator) {
+  CFX_ByteStringC multi_str("abcd");
+  auto iter = multi_str.rbegin();
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  char ch = *iter++;
+  EXPECT_EQ('d', ch);
+  EXPECT_EQ('c', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *(++iter);
+  EXPECT_EQ('b', ch);
+  EXPECT_EQ('b', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter++;
+  EXPECT_EQ('b', ch);
+  EXPECT_EQ('a', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter++;
+  EXPECT_EQ('a', ch);
+  EXPECT_TRUE(iter == multi_str.rend());
+
+  ch = *(--iter);
+  EXPECT_EQ('a', ch);
+  EXPECT_EQ('a', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter--;
+  EXPECT_EQ('a', ch);
+  EXPECT_EQ('b', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter--;
+  EXPECT_EQ('b', ch);
+  EXPECT_EQ('c', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *(--iter);
+  EXPECT_EQ('d', ch);
+  EXPECT_EQ('d', *iter);
+  EXPECT_TRUE(iter == multi_str.rbegin());
+}
+
 TEST(fxcrt, ByteStringCAnyAllNoneOf) {
   CFX_ByteStringC str("aaaaaaaaaaaaaaaaab");
   EXPECT_FALSE(std::all_of(str.begin(), str.end(),
diff --git a/core/fxcrt/cfx_string_c_template.h b/core/fxcrt/cfx_string_c_template.h
index b0e17a1..9123fc2 100644
--- a/core/fxcrt/cfx_string_c_template.h
+++ b/core/fxcrt/cfx_string_c_template.h
@@ -8,6 +8,7 @@
 #define CORE_FXCRT_CFX_STRING_C_TEMPLATE_H_
 
 #include <algorithm>
+#include <iterator>
 #include <type_traits>
 #include <utility>
 #include <vector>
@@ -26,6 +27,7 @@
   using CharType = T;
   using UnsignedType = typename std::make_unsigned<CharType>::type;
   using const_iterator = const CharType*;
+  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
   CFX_StringCTemplate() : m_Ptr(nullptr), m_Length(0) {}
 
@@ -84,6 +86,13 @@
                  : nullptr;
   }
 
+  const_reverse_iterator rbegin() const {
+    return const_reverse_iterator(end());
+  }
+  const_reverse_iterator rend() const {
+    return const_reverse_iterator(begin());
+  }
+
   bool operator==(const CharType* ptr) const {
     return FXSYS_len(ptr) == m_Length &&
            FXSYS_cmp(ptr, reinterpret_cast<const CharType*>(m_Ptr.Get()),
diff --git a/core/fxcrt/cfx_widestring.h b/core/fxcrt/cfx_widestring.h
index 9922e42..595615a 100644
--- a/core/fxcrt/cfx_widestring.h
+++ b/core/fxcrt/cfx_widestring.h
@@ -8,6 +8,7 @@
 #define CORE_FXCRT_CFX_WIDESTRING_H_
 
 #include <functional>
+#include <iterator>
 #include <utility>
 
 #include "core/fxcrt/cfx_retain_ptr.h"
@@ -25,6 +26,7 @@
  public:
   using CharType = wchar_t;
   using const_iterator = const CharType*;
+  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
   CFX_WideString();
   CFX_WideString(const CFX_WideString& other);
@@ -73,6 +75,14 @@
     return m_pData ? m_pData->m_String + m_pData->m_nDataLength : nullptr;
   }
 
+  // Note: Any subsequent modification of |this| will invalidate iterators.
+  const_reverse_iterator rbegin() const {
+    return const_reverse_iterator(end());
+  }
+  const_reverse_iterator rend() const {
+    return const_reverse_iterator(begin());
+  }
+
   void clear() { m_pData.Reset(); }
 
   FX_STRSIZE GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; }
diff --git a/core/fxcrt/cfx_widestring_unittest.cpp b/core/fxcrt/cfx_widestring_unittest.cpp
index 1c8aca9..6f3bc08 100644
--- a/core/fxcrt/cfx_widestring_unittest.cpp
+++ b/core/fxcrt/cfx_widestring_unittest.cpp
@@ -756,6 +756,73 @@
   }
 }
 
+TEST(fxcrt, WideStringEmptyReverseIterator) {
+  CFX_WideString empty;
+  auto iter = empty.rbegin();
+  EXPECT_TRUE(iter == empty.rend());
+  EXPECT_FALSE(iter != empty.rend());
+  EXPECT_FALSE(iter < empty.rend());
+}
+
+TEST(fxcrt, WideStringOneCharReverseIterator) {
+  CFX_WideString one_str(L"a");
+  auto iter = one_str.rbegin();
+  EXPECT_FALSE(iter == one_str.rend());
+  EXPECT_TRUE(iter != one_str.rend());
+  EXPECT_TRUE(iter < one_str.rend());
+
+  char ch = *iter++;
+  EXPECT_EQ('a', ch);
+  EXPECT_TRUE(iter == one_str.rend());
+  EXPECT_FALSE(iter != one_str.rend());
+  EXPECT_FALSE(iter < one_str.rend());
+}
+
+TEST(fxcrt, WideStringMultiCharReverseIterator) {
+  CFX_WideString multi_str(L"abcd");
+  auto iter = multi_str.rbegin();
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  char ch = *iter++;
+  EXPECT_EQ('d', ch);
+  EXPECT_EQ('c', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *(++iter);
+  EXPECT_EQ('b', ch);
+  EXPECT_EQ('b', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter++;
+  EXPECT_EQ('b', ch);
+  EXPECT_EQ('a', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter++;
+  EXPECT_EQ('a', ch);
+  EXPECT_TRUE(iter == multi_str.rend());
+
+  ch = *(--iter);
+  EXPECT_EQ('a', ch);
+  EXPECT_EQ('a', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter--;
+  EXPECT_EQ('a', ch);
+  EXPECT_EQ('b', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter--;
+  EXPECT_EQ('b', ch);
+  EXPECT_EQ('c', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *(--iter);
+  EXPECT_EQ('d', ch);
+  EXPECT_EQ('d', *iter);
+  EXPECT_TRUE(iter == multi_str.rbegin());
+}
+
 TEST(fxcrt, WideStringUTF16LE_Encode) {
   struct UTF16LEEncodeCase {
     CFX_WideString ws;
@@ -1022,6 +1089,73 @@
   EXPECT_EQ(static_cast<int32_t>(L'a' + L'b' + L'c'), sum);
 }
 
+TEST(fxcrt, WideStringCEmptyReverseIterator) {
+  CFX_WideStringC empty;
+  auto iter = empty.rbegin();
+  EXPECT_TRUE(iter == empty.rend());
+  EXPECT_FALSE(iter != empty.rend());
+  EXPECT_FALSE(iter < empty.rend());
+}
+
+TEST(fxcrt, WideStringCOneCharReverseIterator) {
+  CFX_WideStringC one_str(L"a");
+  auto iter = one_str.rbegin();
+  EXPECT_FALSE(iter == one_str.rend());
+  EXPECT_TRUE(iter != one_str.rend());
+  EXPECT_TRUE(iter < one_str.rend());
+
+  char ch = *iter++;
+  EXPECT_EQ('a', ch);
+  EXPECT_TRUE(iter == one_str.rend());
+  EXPECT_FALSE(iter != one_str.rend());
+  EXPECT_FALSE(iter < one_str.rend());
+}
+
+TEST(fxcrt, WideStringCMultiCharReverseIterator) {
+  CFX_WideStringC multi_str(L"abcd");
+  auto iter = multi_str.rbegin();
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  char ch = *iter++;
+  EXPECT_EQ('d', ch);
+  EXPECT_EQ('c', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *(++iter);
+  EXPECT_EQ('b', ch);
+  EXPECT_EQ('b', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter++;
+  EXPECT_EQ('b', ch);
+  EXPECT_EQ('a', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter++;
+  EXPECT_EQ('a', ch);
+  EXPECT_TRUE(iter == multi_str.rend());
+
+  ch = *(--iter);
+  EXPECT_EQ('a', ch);
+  EXPECT_EQ('a', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter--;
+  EXPECT_EQ('a', ch);
+  EXPECT_EQ('b', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *iter--;
+  EXPECT_EQ('b', ch);
+  EXPECT_EQ('c', *iter);
+  EXPECT_FALSE(iter == multi_str.rend());
+
+  ch = *(--iter);
+  EXPECT_EQ('d', ch);
+  EXPECT_EQ('d', *iter);
+  EXPECT_TRUE(iter == multi_str.rbegin());
+}
+
 TEST(fxcrt, WideStringCAnyAllNoneOf) {
   CFX_WideStringC str(L"aaaaaaaaaaaaaaaaab");
   EXPECT_FALSE(std::all_of(str.begin(), str.end(),