199e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten// Copyright 2016 PDFium Authors. All rights reserved.
289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Use of this source code is governed by a BSD-style license that can be
389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// found in the LICENSE file.
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#ifndef CORE_FXCRT_STRING_VIEW_TEMPLATE_H_
889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define CORE_FXCRT_STRING_VIEW_TEMPLATE_H_
989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <algorithm>
1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <iterator>
1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <type_traits>
1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utility>
1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <vector>
1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "core/fxcrt/fx_system.h"
1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "core/fxcrt/unowned_ptr.h"
1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "third_party/base/optional.h"
1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "third_party/base/stl_util.h"
2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2134fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzynnamespace fxcrt {
22c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten
2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// An immutable string with caller-provided storage which must outlive the
2434fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn// string itself. These are not necessarily nul-terminated, so that substring
252b01f009428797ee9154649411a64b522946e966Andy Hung// extraction (via the Mid(), Left(), and Right() methods) is copy-free.
269f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastentemplate <typename T>
279f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenclass StringViewTemplate {
2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project public:
2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  using CharType = T;
309f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten  using UnsignedType = typename std::make_unsigned<CharType>::type;
311ab85ec401801ef9a9184650d0f5a1639b45eeb9Glenn Kasten  using const_iterator = const CharType*;
32a70eef730d7665c9f4b2dfd25faf072785f80a2dDean Wheatley  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
33e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
34cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung  StringViewTemplate() : m_Ptr(nullptr), m_Length(0) {}
35ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick
36ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  // Deliberately implicit to avoid calling on every string literal.
37fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin  // NOLINTNEXTLINE(runtime/explicit)
38b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald  StringViewTemplate(const CharType* ptr)
39b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald      : m_Ptr(reinterpret_cast<const UnsignedType*>(ptr)),
4053c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        m_Length(ptr ? FXSYS_len(ptr) : 0) {}
41511754b5839fd9b09fc56b89ae007fbc39084a33Glenn Kasten
4289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  StringViewTemplate(const CharType* ptr, size_t len)
4333005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh      : m_Ptr(reinterpret_cast<const UnsignedType*>(ptr)), m_Length(len) {}
4433005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh
458cf3a0788df2ee184b498086b1b8da322eeadccaIvan Lozano  template <typename U = UnsignedType>
468cf3a0788df2ee184b498086b1b8da322eeadccaIvan Lozano  StringViewTemplate(
47a7f03353d5f172016f324e2a01f301cca6794152Andy Hung      const UnsignedType* ptr,
48a7f03353d5f172016f324e2a01f301cca6794152Andy Hung      size_t size,
494ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung      typename std::enable_if<!std::is_same<U, CharType>::value>::type* = 0)
50a7f03353d5f172016f324e2a01f301cca6794152Andy Hung      : m_Ptr(ptr), m_Length(size) {}
514ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung
524ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung  // Deliberately implicit to avoid calling on every string literal.
534ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung  // |ch| must be an lvalue that outlives the StringViewTemplate.
54a7f03353d5f172016f324e2a01f301cca6794152Andy Hung  // NOLINTNEXTLINE(runtime/explicit)
55a7f03353d5f172016f324e2a01f301cca6794152Andy Hung  StringViewTemplate(CharType& ch) {
56a7f03353d5f172016f324e2a01f301cca6794152Andy Hung    m_Ptr = reinterpret_cast<const UnsignedType*>(&ch);
57a7f03353d5f172016f324e2a01f301cca6794152Andy Hung    m_Length = 1;
58a7f03353d5f172016f324e2a01f301cca6794152Andy Hung  }
59a7f03353d5f172016f324e2a01f301cca6794152Andy Hung
60a7f03353d5f172016f324e2a01f301cca6794152Andy Hung  StringViewTemplate(const StringViewTemplate& src) {
61a7f03353d5f172016f324e2a01f301cca6794152Andy Hung    m_Ptr = src.m_Ptr;
62a7f03353d5f172016f324e2a01f301cca6794152Andy Hung    m_Length = src.m_Length;
63a7f03353d5f172016f324e2a01f301cca6794152Andy Hung  }
647f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung
657f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung  // Any changes to |vec| invalidate the string.
667f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung  explicit StringViewTemplate(const std::vector<UnsignedType>& vec) {
677f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung    m_Length = vec.size();
687f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung    m_Ptr = m_Length ? vec.data() : nullptr;
69ffa3695a012d22c6c81cf311232c5c84c06f9219Andy Hung  }
70ffa3695a012d22c6c81cf311232c5c84c06f9219Andy Hung
71ffa3695a012d22c6c81cf311232c5c84c06f9219Andy Hung  StringViewTemplate& operator=(const CharType* src) {
72ffa3695a012d22c6c81cf311232c5c84c06f9219Andy Hung    m_Ptr = reinterpret_cast<const UnsignedType*>(src);
73ffa3695a012d22c6c81cf311232c5c84c06f9219Andy Hung    m_Length = src ? FXSYS_len(src) : 0;
74ffa3695a012d22c6c81cf311232c5c84c06f9219Andy Hung    return *this;
75ffa3695a012d22c6c81cf311232c5c84c06f9219Andy Hung  }
76ffa3695a012d22c6c81cf311232c5c84c06f9219Andy Hung
777f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung  StringViewTemplate& operator=(const StringViewTemplate& src) {
787f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung    m_Ptr = src.m_Ptr;
797f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung    m_Length = src.m_Length;
807f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung    return *this;
817f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung  }
827f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung
837f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung  const_iterator begin() const {
847f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung    return reinterpret_cast<const CharType*>(m_Ptr.Get());
8526145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung  }
8626145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung  const_iterator end() const {
8726145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung    return m_Ptr ? reinterpret_cast<const CharType*>(m_Ptr.Get()) + m_Length
8826145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung                 : nullptr;
8926145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung  }
9026145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung
9126145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung  const_reverse_iterator rbegin() const {
9226145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung    return const_reverse_iterator(end());
9326145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung  }
9426145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung  const_reverse_iterator rend() const {
956c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia    return const_reverse_iterator(begin());
9626145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung  }
9726145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung
9826145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung  bool operator==(const CharType* ptr) const {
9926145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung    return FXSYS_len(ptr) == m_Length &&
10026145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung           FXSYS_cmp(ptr, reinterpret_cast<const CharType*>(m_Ptr.Get()),
10126145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung                     m_Length) == 0;
10226145643ce22d797b3b1675c82c47a2d8c79ecaaAndy Hung  }
10333005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh  bool operator==(const StringViewTemplate& other) const {
10433005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    return other.m_Length == m_Length &&
105e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten           FXSYS_cmp(reinterpret_cast<const CharType*>(other.m_Ptr.Get()),
106fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten                     reinterpret_cast<const CharType*>(m_Ptr.Get()),
10733005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh                     m_Length) == 0;
10833005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh  }
109d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten  bool operator!=(const CharType* ptr) const { return !(*this == ptr); }
110d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten  bool operator!=(const StringViewTemplate& other) const {
111d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    return !(*this == other);
11204cd0186305e2b59d23c9147787046c6662029ccGlenn Kasten  }
1130e48d25606c82def035ad10a5b3923767a765cddAndy Hung
114e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten  uint32_t GetID() const {
115e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    if (m_Length == 0)
116e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten      return 0;
1170e48d25606c82def035ad10a5b3923767a765cddAndy Hung
1183b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten    uint32_t strid = 0;
11966a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten    size_t size = std::min(static_cast<size_t>(4), m_Length);
12066a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten    for (size_t i = 0; i < size; i++)
12166a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten      strid = strid * 256 + m_Ptr.Get()[i];
12270c0bfbe5ec88dcc3efa2bd8df26f36cff1cf03aGlenn Kasten
12370c0bfbe5ec88dcc3efa2bd8df26f36cff1cf03aGlenn Kasten    return strid << ((4 - size) * 8);
12466a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten  }
12533005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh
126e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten  const UnsignedType* raw_str() const { return m_Ptr.Get(); }
12766a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten  const CharType* unterminated_c_str() const {
12866a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten    return reinterpret_cast<const CharType*>(m_Ptr.Get());
12970c0bfbe5ec88dcc3efa2bd8df26f36cff1cf03aGlenn Kasten  }
13070c0bfbe5ec88dcc3efa2bd8df26f36cff1cf03aGlenn Kasten
13166a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten  size_t GetLength() const { return m_Length; }
13233005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh  bool IsEmpty() const { return m_Length == 0; }
13333005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh  bool IsValidIndex(size_t index) const { return index < GetLength(); }
13466a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten  bool IsValidLength(size_t length) const { return length <= GetLength(); }
13566a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten
13670c0bfbe5ec88dcc3efa2bd8df26f36cff1cf03aGlenn Kasten  const UnsignedType& operator[](const size_t index) const {
13770c0bfbe5ec88dcc3efa2bd8df26f36cff1cf03aGlenn Kasten    ASSERT(IsValidIndex(index));
13866a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten    return m_Ptr.Get()[index];
13933005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh  }
14033005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh
1418edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung  UnsignedType First() const { return GetLength() ? (*this)[0] : 0; }
1428edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung
14321da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent  UnsignedType Last() const {
14421da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent    return GetLength() ? (*this)[GetLength() - 1] : 0;
14533005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh  }
1460e48d25606c82def035ad10a5b3923767a765cddAndy Hung
1470e48d25606c82def035ad10a5b3923767a765cddAndy Hung  const CharType CharAt(const size_t index) const {
1480e48d25606c82def035ad10a5b3923767a765cddAndy Hung    ASSERT(IsValidIndex(index));
14966a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten    return static_cast<CharType>(m_Ptr.Get()[index]);
1500e48d25606c82def035ad10a5b3923767a765cddAndy Hung  }
15166a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten
15266a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten  Optional<size_t> Find(CharType ch) const {
15366a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten    const auto* found = reinterpret_cast<const UnsignedType*>(FXSYS_chr(
1548edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung        reinterpret_cast<const CharType*>(m_Ptr.Get()), ch, m_Length));
1558edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung
15633005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    return found ? Optional<size_t>(found - m_Ptr.Get()) : Optional<size_t>();
15733005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh  }
15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
15989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  bool Contains(CharType ch) const { return Find(ch).has_value(); }
16089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
161ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  StringViewTemplate Mid(size_t first, size_t count) const {
162ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    if (!m_Ptr.Get())
163ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick      return StringViewTemplate();
164ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick
165ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    if (!IsValidIndex(first))
166ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick      return StringViewTemplate();
167ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick
168ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    if (count == 0 || !IsValidLength(count))
169ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick      return StringViewTemplate();
170ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick
171ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    if (!IsValidIndex(first + count - 1))
172ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick      return StringViewTemplate();
173ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick
174ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    return StringViewTemplate(m_Ptr.Get() + first, count);
175ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  }
176ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick
177ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  StringViewTemplate Left(size_t count) const {
178ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    if (count == 0 || !IsValidLength(count))
179ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick      return StringViewTemplate();
180ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    return Mid(0, count);
181ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  }
182ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick
183ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  StringViewTemplate Right(size_t count) const {
184ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    if (count == 0 || !IsValidLength(count))
185ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick      return StringViewTemplate();
186de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essick    return Mid(GetLength() - count, count);
187de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essick  }
188de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essick
189ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  StringViewTemplate TrimmedRight(CharType ch) const {
190ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    if (IsEmpty())
191ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick      return StringViewTemplate();
192ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick
193ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    size_t pos = GetLength();
194de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essick    while (pos && CharAt(pos - 1) == ch)
195de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essick      pos--;
196ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick
197ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    if (pos == 0)
198ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick      return StringViewTemplate();
1998839430158e22382f0f6450c9274071eca945989Ray Essick
2008839430158e22382f0f6450c9274071eca945989Ray Essick    return StringViewTemplate(m_Ptr.Get(), pos);
2018839430158e22382f0f6450c9274071eca945989Ray Essick  }
2028839430158e22382f0f6450c9274071eca945989Ray Essick
2038839430158e22382f0f6450c9274071eca945989Ray Essick  bool operator<(const StringViewTemplate& that) const {
2048839430158e22382f0f6450c9274071eca945989Ray Essick    int result = FXSYS_cmp(reinterpret_cast<const CharType*>(m_Ptr.Get()),
2058839430158e22382f0f6450c9274071eca945989Ray Essick                           reinterpret_cast<const CharType*>(that.m_Ptr.Get()),
2068839430158e22382f0f6450c9274071eca945989Ray Essick                           std::min(m_Length, that.m_Length));
207ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    return result < 0 || (result == 0 && m_Length < that.m_Length);
208ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  }
209ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick
210ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  bool operator>(const StringViewTemplate& that) const {
211ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    int result = FXSYS_cmp(reinterpret_cast<const CharType*>(m_Ptr.Get()),
212ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick                           reinterpret_cast<const CharType*>(that.m_Ptr.Get()),
213ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick                           std::min(m_Length, that.m_Length));
214ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick    return result > 0 || (result == 0 && m_Length > that.m_Length);
215ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  }
216ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick
217ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick protected:
218ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  UnownedPtr<const UnsignedType> m_Ptr;
219ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  size_t m_Length;
220ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick
221ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick private:
222ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  void* operator new(size_t) throw() { return nullptr; }
223ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick};
224ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick
225ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essicktemplate <typename T>
226ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essickinline bool operator==(const T* lhs, const StringViewTemplate<T>& rhs) {
227ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick  return rhs == lhs;
228ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essick}
229ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essicktemplate <typename T>
230ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essickinline bool operator!=(const T* lhs, const StringViewTemplate<T>& rhs) {
2318839430158e22382f0f6450c9274071eca945989Ray Essick  return rhs != lhs;
2328839430158e22382f0f6450c9274071eca945989Ray Essick}
2338839430158e22382f0f6450c9274071eca945989Ray Essicktemplate <typename T>
2348839430158e22382f0f6450c9274071eca945989Ray Essickinline bool operator<(const T* lhs, const StringViewTemplate<T>& rhs) {
2358839430158e22382f0f6450c9274071eca945989Ray Essick  return rhs > lhs;
2368839430158e22382f0f6450c9274071eca945989Ray Essick}
2378839430158e22382f0f6450c9274071eca945989Ray Essick
2388839430158e22382f0f6450c9274071eca945989Ray Essickextern template class StringViewTemplate<char>;
2398839430158e22382f0f6450c9274071eca945989Ray Essickextern template class StringViewTemplate<wchar_t>;
2408839430158e22382f0f6450c9274071eca945989Ray Essick
2418839430158e22382f0f6450c9274071eca945989Ray Essickusing ByteStringView = StringViewTemplate<char>;
242ed30470cf0a20c0c1edb2b82075985ccaa6c75c1Ray Essickusing WideStringView = StringViewTemplate<wchar_t>;
24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
244879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten}  // namespace fxcrt
2459b3359feabbf138bb965da5173434da78bfe0929Haynes Mathew George
2464ff14bae91075eb274eb1c2975982358946e7e63John Grossmanusing ByteStringView = fxcrt::ByteStringView;
2477064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew Georgeusing WideStringView = fxcrt::WideStringView;
248aa9811945f575614b3482d09e4d969792701cebbPaul McLean
24920b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent#endif  // CORE_FXCRT_STRING_VIEW_TEMPLATE_H_
25021da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent