| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097 | // Copyright 2017 The Abseil Authors.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at////      http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.#include "absl/strings/string_view.h"#include <stdlib.h>#include <iomanip>#include <iterator>#include <limits>#include <map>#include <sstream>#include <stdexcept>#include <string>#include <type_traits>#include <utility>#include "gtest/gtest.h"#include "absl/base/config.h"#include "absl/base/dynamic_annotations.h"namespace {// A minimal allocator that uses malloc().template <typename T>struct Mallocator {  typedef T value_type;  typedef size_t size_type;  typedef ptrdiff_t difference_type;  typedef T* pointer;  typedef const T* const_pointer;  typedef T& reference;  typedef const T& const_reference;  size_type max_size() const {    return size_t(std::numeric_limits<size_type>::max()) / sizeof(value_type);  }  template <typename U>  struct rebind {    typedef Mallocator<U> other;  };  Mallocator() = default;  T* allocate(size_t n) { return static_cast<T*>(std::malloc(n * sizeof(T))); }  void deallocate(T* p, size_t) { std::free(p); }};template <typename T, typename U>bool operator==(const Mallocator<T>&, const Mallocator<U>&) {  return true;}template <typename T, typename U>bool operator!=(const Mallocator<T>&, const Mallocator<U>&) {  return false;}TEST(StringViewTest, Ctor) {  {    // Null.    absl::string_view s10;    EXPECT_TRUE(s10.data() == nullptr);    EXPECT_EQ(0, s10.length());  }  {    // const char* without length.    const char* hello = "hello";    absl::string_view s20(hello);    EXPECT_TRUE(s20.data() == hello);    EXPECT_EQ(5, s20.length());    // const char* with length.    absl::string_view s21(hello, 4);    EXPECT_TRUE(s21.data() == hello);    EXPECT_EQ(4, s21.length());    // Not recommended, but valid C++    absl::string_view s22(hello, 6);    EXPECT_TRUE(s22.data() == hello);    EXPECT_EQ(6, s22.length());  }  {    // std::string.    std::string hola = "hola";    absl::string_view s30(hola);    EXPECT_TRUE(s30.data() == hola.data());    EXPECT_EQ(4, s30.length());    // std::string with embedded '\0'.    hola.push_back('\0');    hola.append("h2");    hola.push_back('\0');    absl::string_view s31(hola);    EXPECT_TRUE(s31.data() == hola.data());    EXPECT_EQ(8, s31.length());  }  {    using mstring =        std::basic_string<char, std::char_traits<char>, Mallocator<char>>;    mstring str1("BUNGIE-JUMPING!");    const mstring str2("SLEEPING!");    absl::string_view s1(str1);    s1.remove_prefix(strlen("BUNGIE-JUM"));    absl::string_view s2(str2);    s2.remove_prefix(strlen("SLEE"));    EXPECT_EQ(s1, s2);    EXPECT_EQ(s1, "PING!");  }  // TODO(mec): absl::string_view(const absl::string_view&);}TEST(StringViewTest, Swap) {  absl::string_view a("a");  absl::string_view b("bbb");  EXPECT_TRUE(noexcept(a.swap(b)));  a.swap(b);  EXPECT_EQ(a, "bbb");  EXPECT_EQ(b, "a");  a.swap(b);  EXPECT_EQ(a, "a");  EXPECT_EQ(b, "bbb");}TEST(StringViewTest, STLComparator) {  std::string s1("foo");  std::string s2("bar");  std::string s3("baz");  absl::string_view p1(s1);  absl::string_view p2(s2);  absl::string_view p3(s3);  typedef std::map<absl::string_view, int> TestMap;  TestMap map;  map.insert(std::make_pair(p1, 0));  map.insert(std::make_pair(p2, 1));  map.insert(std::make_pair(p3, 2));  EXPECT_EQ(map.size(), 3);  TestMap::const_iterator iter = map.begin();  EXPECT_EQ(iter->second, 1);  ++iter;  EXPECT_EQ(iter->second, 2);  ++iter;  EXPECT_EQ(iter->second, 0);  ++iter;  EXPECT_TRUE(iter == map.end());  TestMap::iterator new_iter = map.find("zot");  EXPECT_TRUE(new_iter == map.end());  new_iter = map.find("bar");  EXPECT_TRUE(new_iter != map.end());  map.erase(new_iter);  EXPECT_EQ(map.size(), 2);  iter = map.begin();  EXPECT_EQ(iter->second, 2);  ++iter;  EXPECT_EQ(iter->second, 0);  ++iter;  EXPECT_TRUE(iter == map.end());}#define COMPARE(result, op, x, y)                                      \  EXPECT_EQ(result, absl::string_view((x)) op absl::string_view((y))); \  EXPECT_EQ(result, absl::string_view((x)).compare(absl::string_view((y))) op 0)TEST(StringViewTest, ComparisonOperators) {  COMPARE(true, ==, "",   "");  COMPARE(true, ==, "", absl::string_view());  COMPARE(true, ==, absl::string_view(), "");  COMPARE(true, ==, "a",  "a");  COMPARE(true, ==, "aa", "aa");  COMPARE(false, ==, "a",  "");  COMPARE(false, ==, "",   "a");  COMPARE(false, ==, "a",  "b");  COMPARE(false, ==, "a",  "aa");  COMPARE(false, ==, "aa", "a");  COMPARE(false, !=, "",   "");  COMPARE(false, !=, "a",  "a");  COMPARE(false, !=, "aa", "aa");  COMPARE(true, !=, "a",  "");  COMPARE(true, !=, "",   "a");  COMPARE(true, !=, "a",  "b");  COMPARE(true, !=, "a",  "aa");  COMPARE(true, !=, "aa", "a");  COMPARE(true, <, "a",  "b");  COMPARE(true, <, "a",  "aa");  COMPARE(true, <, "aa", "b");  COMPARE(true, <, "aa", "bb");  COMPARE(false, <, "a",  "a");  COMPARE(false, <, "b",  "a");  COMPARE(false, <, "aa", "a");  COMPARE(false, <, "b",  "aa");  COMPARE(false, <, "bb", "aa");  COMPARE(true, <=, "a",  "a");  COMPARE(true, <=, "a",  "b");  COMPARE(true, <=, "a",  "aa");  COMPARE(true, <=, "aa", "b");  COMPARE(true, <=, "aa", "bb");  COMPARE(false, <=, "b",  "a");  COMPARE(false, <=, "aa", "a");  COMPARE(false, <=, "b",  "aa");  COMPARE(false, <=, "bb", "aa");  COMPARE(false, >=, "a",  "b");  COMPARE(false, >=, "a",  "aa");  COMPARE(false, >=, "aa", "b");  COMPARE(false, >=, "aa", "bb");  COMPARE(true, >=, "a",  "a");  COMPARE(true, >=, "b",  "a");  COMPARE(true, >=, "aa", "a");  COMPARE(true, >=, "b",  "aa");  COMPARE(true, >=, "bb", "aa");  COMPARE(false, >, "a",  "a");  COMPARE(false, >, "a",  "b");  COMPARE(false, >, "a",  "aa");  COMPARE(false, >, "aa", "b");  COMPARE(false, >, "aa", "bb");  COMPARE(true, >, "b",  "a");  COMPARE(true, >, "aa", "a");  COMPARE(true, >, "b",  "aa");  COMPARE(true, >, "bb", "aa");}TEST(StringViewTest, ComparisonOperatorsByCharacterPosition) {  std::string x;  for (int i = 0; i < 256; i++) {    x += 'a';    std::string y = x;    COMPARE(true, ==, x, y);    for (int j = 0; j < i; j++) {      std::string z = x;      z[j] = 'b';       // Differs in position 'j'      COMPARE(false, ==, x, z);      COMPARE(true, <, x, z);      COMPARE(true, >, z, x);      if (j + 1 < i) {        z[j + 1] = 'A';  // Differs in position 'j+1' as well        COMPARE(false, ==, x, z);        COMPARE(true, <, x, z);        COMPARE(true, >, z, x);        z[j + 1] = 'z';  // Differs in position 'j+1' as well        COMPARE(false, ==, x, z);        COMPARE(true, <, x, z);        COMPARE(true, >, z, x);      }    }  }}#undef COMPARE// Sadly, our users often confuse std::string::npos with absl::string_view::npos;// So much so that we test here that they are the same.  They need to// both be unsigned, and both be the maximum-valued integer of their type.template <typename T>struct is_type {  template <typename U>  static bool same(U) {    return false;  }  static bool same(T) { return true; }};TEST(StringViewTest, NposMatchesStdStringView) {  EXPECT_EQ(absl::string_view::npos, std::string::npos);  EXPECT_TRUE(is_type<size_t>::same(absl::string_view::npos));  EXPECT_FALSE(is_type<size_t>::same(""));  // Make sure absl::string_view::npos continues to be a header constant.  char test[absl::string_view::npos & 1] = {0};  EXPECT_EQ(0, test[0]);}TEST(StringViewTest, STL1) {  const absl::string_view a("abcdefghijklmnopqrstuvwxyz");  const absl::string_view b("abc");  const absl::string_view c("xyz");  const absl::string_view d("foobar");  const absl::string_view e;  std::string temp("123");  temp += '\0';  temp += "456";  const absl::string_view f(temp);  EXPECT_EQ(a[6], 'g');  EXPECT_EQ(b[0], 'a');  EXPECT_EQ(c[2], 'z');  EXPECT_EQ(f[3], '\0');  EXPECT_EQ(f[5], '5');  EXPECT_EQ(*d.data(), 'f');  EXPECT_EQ(d.data()[5], 'r');  EXPECT_TRUE(e.data() == nullptr);  EXPECT_EQ(*a.begin(), 'a');  EXPECT_EQ(*(b.begin() + 2), 'c');  EXPECT_EQ(*(c.end() - 1), 'z');  EXPECT_EQ(*a.rbegin(), 'z');  EXPECT_EQ(*(b.rbegin() + 2), 'a');  EXPECT_EQ(*(c.rend() - 1), 'x');  EXPECT_TRUE(a.rbegin() + 26 == a.rend());  EXPECT_EQ(a.size(), 26);  EXPECT_EQ(b.size(), 3);  EXPECT_EQ(c.size(), 3);  EXPECT_EQ(d.size(), 6);  EXPECT_EQ(e.size(), 0);  EXPECT_EQ(f.size(), 7);  EXPECT_TRUE(!d.empty());  EXPECT_TRUE(d.begin() != d.end());  EXPECT_TRUE(d.begin() + 6 == d.end());  EXPECT_TRUE(e.empty());  EXPECT_TRUE(e.begin() == e.end());  char buf[4] = { '%', '%', '%', '%' };  EXPECT_EQ(a.copy(buf, 4), 4);  EXPECT_EQ(buf[0], a[0]);  EXPECT_EQ(buf[1], a[1]);  EXPECT_EQ(buf[2], a[2]);  EXPECT_EQ(buf[3], a[3]);  EXPECT_EQ(a.copy(buf, 3, 7), 3);  EXPECT_EQ(buf[0], a[7]);  EXPECT_EQ(buf[1], a[8]);  EXPECT_EQ(buf[2], a[9]);  EXPECT_EQ(buf[3], a[3]);  EXPECT_EQ(c.copy(buf, 99), 3);  EXPECT_EQ(buf[0], c[0]);  EXPECT_EQ(buf[1], c[1]);  EXPECT_EQ(buf[2], c[2]);  EXPECT_EQ(buf[3], a[3]);}// Separated from STL1() because some compilers produce an overly// large stack frame for the combined function.TEST(StringViewTest, STL2) {  const absl::string_view a("abcdefghijklmnopqrstuvwxyz");  const absl::string_view b("abc");  const absl::string_view c("xyz");  absl::string_view d("foobar");  const absl::string_view e;  const absl::string_view f(      "123"      "\0"      "456",      7);  d = absl::string_view();  EXPECT_EQ(d.size(), 0);  EXPECT_TRUE(d.empty());  EXPECT_TRUE(d.data() == nullptr);  EXPECT_TRUE(d.begin() == d.end());  EXPECT_EQ(a.find(b), 0);  EXPECT_EQ(a.find(b, 1), absl::string_view::npos);  EXPECT_EQ(a.find(c), 23);  EXPECT_EQ(a.find(c, 9), 23);  EXPECT_EQ(a.find(c, absl::string_view::npos), absl::string_view::npos);  EXPECT_EQ(b.find(c), absl::string_view::npos);  EXPECT_EQ(b.find(c, absl::string_view::npos), absl::string_view::npos);  EXPECT_EQ(a.find(d), 0);  EXPECT_EQ(a.find(e), 0);  EXPECT_EQ(a.find(d, 12), 12);  EXPECT_EQ(a.find(e, 17), 17);  absl::string_view g("xx not found bb");  EXPECT_EQ(a.find(g), absl::string_view::npos);  // empty std::string nonsense  EXPECT_EQ(d.find(b), absl::string_view::npos);  EXPECT_EQ(e.find(b), absl::string_view::npos);  EXPECT_EQ(d.find(b, 4), absl::string_view::npos);  EXPECT_EQ(e.find(b, 7), absl::string_view::npos);  size_t empty_search_pos = std::string().find(std::string());  EXPECT_EQ(d.find(d), empty_search_pos);  EXPECT_EQ(d.find(e), empty_search_pos);  EXPECT_EQ(e.find(d), empty_search_pos);  EXPECT_EQ(e.find(e), empty_search_pos);  EXPECT_EQ(d.find(d, 4), std::string().find(std::string(), 4));  EXPECT_EQ(d.find(e, 4), std::string().find(std::string(), 4));  EXPECT_EQ(e.find(d, 4), std::string().find(std::string(), 4));  EXPECT_EQ(e.find(e, 4), std::string().find(std::string(), 4));  EXPECT_EQ(a.find('a'), 0);  EXPECT_EQ(a.find('c'), 2);  EXPECT_EQ(a.find('z'), 25);  EXPECT_EQ(a.find('$'), absl::string_view::npos);  EXPECT_EQ(a.find('\0'), absl::string_view::npos);  EXPECT_EQ(f.find('\0'), 3);  EXPECT_EQ(f.find('3'), 2);  EXPECT_EQ(f.find('5'), 5);  EXPECT_EQ(g.find('o'), 4);  EXPECT_EQ(g.find('o', 4), 4);  EXPECT_EQ(g.find('o', 5), 8);  EXPECT_EQ(a.find('b', 5), absl::string_view::npos);  // empty std::string nonsense  EXPECT_EQ(d.find('\0'), absl::string_view::npos);  EXPECT_EQ(e.find('\0'), absl::string_view::npos);  EXPECT_EQ(d.find('\0', 4), absl::string_view::npos);  EXPECT_EQ(e.find('\0', 7), absl::string_view::npos);  EXPECT_EQ(d.find('x'), absl::string_view::npos);  EXPECT_EQ(e.find('x'), absl::string_view::npos);  EXPECT_EQ(d.find('x', 4), absl::string_view::npos);  EXPECT_EQ(e.find('x', 7), absl::string_view::npos);  EXPECT_EQ(a.rfind(b), 0);  EXPECT_EQ(a.rfind(b, 1), 0);  EXPECT_EQ(a.rfind(c), 23);  EXPECT_EQ(a.rfind(c, 22), absl::string_view::npos);  EXPECT_EQ(a.rfind(c, 1), absl::string_view::npos);  EXPECT_EQ(a.rfind(c, 0), absl::string_view::npos);  EXPECT_EQ(b.rfind(c), absl::string_view::npos);  EXPECT_EQ(b.rfind(c, 0), absl::string_view::npos);  EXPECT_EQ(a.rfind(d), std::string(a).rfind(std::string()));  EXPECT_EQ(a.rfind(e), std::string(a).rfind(std::string()));  EXPECT_EQ(a.rfind(d, 12), 12);  EXPECT_EQ(a.rfind(e, 17), 17);  EXPECT_EQ(a.rfind(g), absl::string_view::npos);  EXPECT_EQ(d.rfind(b), absl::string_view::npos);  EXPECT_EQ(e.rfind(b), absl::string_view::npos);  EXPECT_EQ(d.rfind(b, 4), absl::string_view::npos);  EXPECT_EQ(e.rfind(b, 7), absl::string_view::npos);  // empty std::string nonsense  EXPECT_EQ(d.rfind(d, 4), std::string().rfind(std::string()));  EXPECT_EQ(e.rfind(d, 7), std::string().rfind(std::string()));  EXPECT_EQ(d.rfind(e, 4), std::string().rfind(std::string()));  EXPECT_EQ(e.rfind(e, 7), std::string().rfind(std::string()));  EXPECT_EQ(d.rfind(d), std::string().rfind(std::string()));  EXPECT_EQ(e.rfind(d), std::string().rfind(std::string()));  EXPECT_EQ(d.rfind(e), std::string().rfind(std::string()));  EXPECT_EQ(e.rfind(e), std::string().rfind(std::string()));  EXPECT_EQ(g.rfind('o'), 8);  EXPECT_EQ(g.rfind('q'), absl::string_view::npos);  EXPECT_EQ(g.rfind('o', 8), 8);  EXPECT_EQ(g.rfind('o', 7), 4);  EXPECT_EQ(g.rfind('o', 3), absl::string_view::npos);  EXPECT_EQ(f.rfind('\0'), 3);  EXPECT_EQ(f.rfind('\0', 12), 3);  EXPECT_EQ(f.rfind('3'), 2);  EXPECT_EQ(f.rfind('5'), 5);  // empty std::string nonsense  EXPECT_EQ(d.rfind('o'), absl::string_view::npos);  EXPECT_EQ(e.rfind('o'), absl::string_view::npos);  EXPECT_EQ(d.rfind('o', 4), absl::string_view::npos);  EXPECT_EQ(e.rfind('o', 7), absl::string_view::npos);}// Continued from STL2TEST(StringViewTest, STL2FindFirst) {  const absl::string_view a("abcdefghijklmnopqrstuvwxyz");  const absl::string_view b("abc");  const absl::string_view c("xyz");  absl::string_view d("foobar");  const absl::string_view e;  const absl::string_view f(      "123"      "\0"      "456",      7);  absl::string_view g("xx not found bb");  d = absl::string_view();  EXPECT_EQ(a.find_first_of(b), 0);  EXPECT_EQ(a.find_first_of(b, 0), 0);  EXPECT_EQ(a.find_first_of(b, 1), 1);  EXPECT_EQ(a.find_first_of(b, 2), 2);  EXPECT_EQ(a.find_first_of(b, 3), absl::string_view::npos);  EXPECT_EQ(a.find_first_of(c), 23);  EXPECT_EQ(a.find_first_of(c, 23), 23);  EXPECT_EQ(a.find_first_of(c, 24), 24);  EXPECT_EQ(a.find_first_of(c, 25), 25);  EXPECT_EQ(a.find_first_of(c, 26), absl::string_view::npos);  EXPECT_EQ(g.find_first_of(b), 13);  EXPECT_EQ(g.find_first_of(c), 0);  EXPECT_EQ(a.find_first_of(f), absl::string_view::npos);  EXPECT_EQ(f.find_first_of(a), absl::string_view::npos);  // empty std::string nonsense  EXPECT_EQ(a.find_first_of(d), absl::string_view::npos);  EXPECT_EQ(a.find_first_of(e), absl::string_view::npos);  EXPECT_EQ(d.find_first_of(b), absl::string_view::npos);  EXPECT_EQ(e.find_first_of(b), absl::string_view::npos);  EXPECT_EQ(d.find_first_of(d), absl::string_view::npos);  EXPECT_EQ(e.find_first_of(d), absl::string_view::npos);  EXPECT_EQ(d.find_first_of(e), absl::string_view::npos);  EXPECT_EQ(e.find_first_of(e), absl::string_view::npos);  EXPECT_EQ(a.find_first_not_of(b), 3);  EXPECT_EQ(a.find_first_not_of(c), 0);  EXPECT_EQ(b.find_first_not_of(a), absl::string_view::npos);  EXPECT_EQ(c.find_first_not_of(a), absl::string_view::npos);  EXPECT_EQ(f.find_first_not_of(a), 0);  EXPECT_EQ(a.find_first_not_of(f), 0);  EXPECT_EQ(a.find_first_not_of(d), 0);  EXPECT_EQ(a.find_first_not_of(e), 0);  // empty std::string nonsense  EXPECT_EQ(a.find_first_not_of(d), 0);  EXPECT_EQ(a.find_first_not_of(e), 0);  EXPECT_EQ(a.find_first_not_of(d, 1), 1);  EXPECT_EQ(a.find_first_not_of(e, 1), 1);  EXPECT_EQ(a.find_first_not_of(d, a.size() - 1), a.size() - 1);  EXPECT_EQ(a.find_first_not_of(e, a.size() - 1), a.size() - 1);  EXPECT_EQ(a.find_first_not_of(d, a.size()), absl::string_view::npos);  EXPECT_EQ(a.find_first_not_of(e, a.size()), absl::string_view::npos);  EXPECT_EQ(a.find_first_not_of(d, absl::string_view::npos),            absl::string_view::npos);  EXPECT_EQ(a.find_first_not_of(e, absl::string_view::npos),            absl::string_view::npos);  EXPECT_EQ(d.find_first_not_of(a), absl::string_view::npos);  EXPECT_EQ(e.find_first_not_of(a), absl::string_view::npos);  EXPECT_EQ(d.find_first_not_of(d), absl::string_view::npos);  EXPECT_EQ(e.find_first_not_of(d), absl::string_view::npos);  EXPECT_EQ(d.find_first_not_of(e), absl::string_view::npos);  EXPECT_EQ(e.find_first_not_of(e), absl::string_view::npos);  absl::string_view h("====");  EXPECT_EQ(h.find_first_not_of('='), absl::string_view::npos);  EXPECT_EQ(h.find_first_not_of('=', 3), absl::string_view::npos);  EXPECT_EQ(h.find_first_not_of('\0'), 0);  EXPECT_EQ(g.find_first_not_of('x'), 2);  EXPECT_EQ(f.find_first_not_of('\0'), 0);  EXPECT_EQ(f.find_first_not_of('\0', 3), 4);  EXPECT_EQ(f.find_first_not_of('\0', 2), 2);  // empty std::string nonsense  EXPECT_EQ(d.find_first_not_of('x'), absl::string_view::npos);  EXPECT_EQ(e.find_first_not_of('x'), absl::string_view::npos);  EXPECT_EQ(d.find_first_not_of('\0'), absl::string_view::npos);  EXPECT_EQ(e.find_first_not_of('\0'), absl::string_view::npos);}// Continued from STL2TEST(StringViewTest, STL2FindLast) {  const absl::string_view a("abcdefghijklmnopqrstuvwxyz");  const absl::string_view b("abc");  const absl::string_view c("xyz");  absl::string_view d("foobar");  const absl::string_view e;  const absl::string_view f(      "123"      "\0"      "456",      7);  absl::string_view g("xx not found bb");  absl::string_view h("====");  absl::string_view i("56");  d = absl::string_view();  EXPECT_EQ(h.find_last_of(a), absl::string_view::npos);  EXPECT_EQ(g.find_last_of(a), g.size()-1);  EXPECT_EQ(a.find_last_of(b), 2);  EXPECT_EQ(a.find_last_of(c), a.size()-1);  EXPECT_EQ(f.find_last_of(i), 6);  EXPECT_EQ(a.find_last_of('a'), 0);  EXPECT_EQ(a.find_last_of('b'), 1);  EXPECT_EQ(a.find_last_of('z'), 25);  EXPECT_EQ(a.find_last_of('a', 5), 0);  EXPECT_EQ(a.find_last_of('b', 5), 1);  EXPECT_EQ(a.find_last_of('b', 0), absl::string_view::npos);  EXPECT_EQ(a.find_last_of('z', 25), 25);  EXPECT_EQ(a.find_last_of('z', 24), absl::string_view::npos);  EXPECT_EQ(f.find_last_of(i, 5), 5);  EXPECT_EQ(f.find_last_of(i, 6), 6);  EXPECT_EQ(f.find_last_of(a, 4), absl::string_view::npos);  // empty std::string nonsense  EXPECT_EQ(f.find_last_of(d), absl::string_view::npos);  EXPECT_EQ(f.find_last_of(e), absl::string_view::npos);  EXPECT_EQ(f.find_last_of(d, 4), absl::string_view::npos);  EXPECT_EQ(f.find_last_of(e, 4), absl::string_view::npos);  EXPECT_EQ(d.find_last_of(d), absl::string_view::npos);  EXPECT_EQ(d.find_last_of(e), absl::string_view::npos);  EXPECT_EQ(e.find_last_of(d), absl::string_view::npos);  EXPECT_EQ(e.find_last_of(e), absl::string_view::npos);  EXPECT_EQ(d.find_last_of(f), absl::string_view::npos);  EXPECT_EQ(e.find_last_of(f), absl::string_view::npos);  EXPECT_EQ(d.find_last_of(d, 4), absl::string_view::npos);  EXPECT_EQ(d.find_last_of(e, 4), absl::string_view::npos);  EXPECT_EQ(e.find_last_of(d, 4), absl::string_view::npos);  EXPECT_EQ(e.find_last_of(e, 4), absl::string_view::npos);  EXPECT_EQ(d.find_last_of(f, 4), absl::string_view::npos);  EXPECT_EQ(e.find_last_of(f, 4), absl::string_view::npos);  EXPECT_EQ(a.find_last_not_of(b), a.size()-1);  EXPECT_EQ(a.find_last_not_of(c), 22);  EXPECT_EQ(b.find_last_not_of(a), absl::string_view::npos);  EXPECT_EQ(b.find_last_not_of(b), absl::string_view::npos);  EXPECT_EQ(f.find_last_not_of(i), 4);  EXPECT_EQ(a.find_last_not_of(c, 24), 22);  EXPECT_EQ(a.find_last_not_of(b, 3), 3);  EXPECT_EQ(a.find_last_not_of(b, 2), absl::string_view::npos);  // empty std::string nonsense  EXPECT_EQ(f.find_last_not_of(d), f.size()-1);  EXPECT_EQ(f.find_last_not_of(e), f.size()-1);  EXPECT_EQ(f.find_last_not_of(d, 4), 4);  EXPECT_EQ(f.find_last_not_of(e, 4), 4);  EXPECT_EQ(d.find_last_not_of(d), absl::string_view::npos);  EXPECT_EQ(d.find_last_not_of(e), absl::string_view::npos);  EXPECT_EQ(e.find_last_not_of(d), absl::string_view::npos);  EXPECT_EQ(e.find_last_not_of(e), absl::string_view::npos);  EXPECT_EQ(d.find_last_not_of(f), absl::string_view::npos);  EXPECT_EQ(e.find_last_not_of(f), absl::string_view::npos);  EXPECT_EQ(d.find_last_not_of(d, 4), absl::string_view::npos);  EXPECT_EQ(d.find_last_not_of(e, 4), absl::string_view::npos);  EXPECT_EQ(e.find_last_not_of(d, 4), absl::string_view::npos);  EXPECT_EQ(e.find_last_not_of(e, 4), absl::string_view::npos);  EXPECT_EQ(d.find_last_not_of(f, 4), absl::string_view::npos);  EXPECT_EQ(e.find_last_not_of(f, 4), absl::string_view::npos);  EXPECT_EQ(h.find_last_not_of('x'), h.size() - 1);  EXPECT_EQ(h.find_last_not_of('='), absl::string_view::npos);  EXPECT_EQ(b.find_last_not_of('c'), 1);  EXPECT_EQ(h.find_last_not_of('x', 2), 2);  EXPECT_EQ(h.find_last_not_of('=', 2), absl::string_view::npos);  EXPECT_EQ(b.find_last_not_of('b', 1), 0);  // empty std::string nonsense  EXPECT_EQ(d.find_last_not_of('x'), absl::string_view::npos);  EXPECT_EQ(e.find_last_not_of('x'), absl::string_view::npos);  EXPECT_EQ(d.find_last_not_of('\0'), absl::string_view::npos);  EXPECT_EQ(e.find_last_not_of('\0'), absl::string_view::npos);}// Continued from STL2TEST(StringViewTest, STL2Substr) {  const absl::string_view a("abcdefghijklmnopqrstuvwxyz");  const absl::string_view b("abc");  const absl::string_view c("xyz");  absl::string_view d("foobar");  const absl::string_view e;  d = absl::string_view();  EXPECT_EQ(a.substr(0, 3), b);  EXPECT_EQ(a.substr(23), c);  EXPECT_EQ(a.substr(23, 3), c);  EXPECT_EQ(a.substr(23, 99), c);  EXPECT_EQ(a.substr(0), a);  EXPECT_EQ(a.substr(3, 2), "de");  // empty std::string nonsense  EXPECT_EQ(d.substr(0, 99), e);  // use of npos  EXPECT_EQ(a.substr(0, absl::string_view::npos), a);  EXPECT_EQ(a.substr(23, absl::string_view::npos), c);  // throw exception#ifdef ABSL_HAVE_EXCEPTIONS  EXPECT_THROW(a.substr(99, 2), std::out_of_range);#else  EXPECT_DEATH(a.substr(99, 2), "absl::string_view::substr");#endif}TEST(StringViewTest, TruncSubstr) {  const absl::string_view hi("hi");  EXPECT_EQ("", absl::ClippedSubstr(hi, 0, 0));  EXPECT_EQ("h", absl::ClippedSubstr(hi, 0, 1));  EXPECT_EQ("hi", absl::ClippedSubstr(hi, 0));  EXPECT_EQ("i", absl::ClippedSubstr(hi, 1));  EXPECT_EQ("", absl::ClippedSubstr(hi, 2));  EXPECT_EQ("", absl::ClippedSubstr(hi, 3));  // truncation  EXPECT_EQ("", absl::ClippedSubstr(hi, 3, 2));  // truncation}TEST(StringViewTest, UTF8) {  EXPECT_EQ(strlen("á"), absl::string_view("á á").find_first_of(" "));  EXPECT_EQ(strlen("á"), absl::string_view("á á").find_first_of(" \t"));}TEST(StringViewTest, FindConformance) {  struct {    std::string haystack;    std::string needle;  } specs[] = {    {"", ""},    {"", "a"},    {"a", ""},    {"a", "a"},    {"a", "b"},    {"aa", ""},    {"aa", "a"},    {"aa", "b"},    {"ab", "a"},    {"ab", "b"},    {"abcd", ""},    {"abcd", "a"},    {"abcd", "d"},    {"abcd", "ab"},    {"abcd", "bc"},    {"abcd", "cd"},    {"abcd", "abcd"},  };  for (const auto& s : specs) {    SCOPED_TRACE(s.haystack);    SCOPED_TRACE(s.needle);    std::string st = s.haystack;    absl::string_view sp = s.haystack;    for (size_t i = 0; i <= sp.size(); ++i) {      size_t pos = (i == sp.size()) ? absl::string_view::npos : i;      SCOPED_TRACE(pos);      EXPECT_EQ(sp.find(s.needle, pos),                st.find(s.needle, pos));      EXPECT_EQ(sp.rfind(s.needle, pos),                st.rfind(s.needle, pos));      EXPECT_EQ(sp.find_first_of(s.needle, pos),                st.find_first_of(s.needle, pos));      EXPECT_EQ(sp.find_first_not_of(s.needle, pos),                st.find_first_not_of(s.needle, pos));      EXPECT_EQ(sp.find_last_of(s.needle, pos),                st.find_last_of(s.needle, pos));      EXPECT_EQ(sp.find_last_not_of(s.needle, pos),                st.find_last_not_of(s.needle, pos));    }  }}TEST(StringViewTest, Remove) {  absl::string_view a("foobar");  std::string s1("123");  s1 += '\0';  s1 += "456";  absl::string_view b(s1);  absl::string_view e;  std::string s2;  // remove_prefix  absl::string_view c(a);  c.remove_prefix(3);  EXPECT_EQ(c, "bar");  c = a;  c.remove_prefix(0);  EXPECT_EQ(c, a);  c.remove_prefix(c.size());  EXPECT_EQ(c, e);  // remove_suffix  c = a;  c.remove_suffix(3);  EXPECT_EQ(c, "foo");  c = a;  c.remove_suffix(0);  EXPECT_EQ(c, a);  c.remove_suffix(c.size());  EXPECT_EQ(c, e);}TEST(StringViewTest, Set) {  absl::string_view a("foobar");  absl::string_view empty;  absl::string_view b;  // set  b = absl::string_view("foobar", 6);  EXPECT_EQ(b, a);  b = absl::string_view("foobar", 0);  EXPECT_EQ(b, empty);  b = absl::string_view("foobar", 7);  EXPECT_NE(b, a);  b = absl::string_view("foobar");  EXPECT_EQ(b, a);}TEST(StringViewTest, FrontBack) {  static const char arr[] = "abcd";  const absl::string_view csp(arr, 4);  EXPECT_EQ(&arr[0], &csp.front());  EXPECT_EQ(&arr[3], &csp.back());}TEST(StringViewTest, FrontBackSingleChar) {  static const char c = 'a';  const absl::string_view csp(&c, 1);  EXPECT_EQ(&c, &csp.front());  EXPECT_EQ(&c, &csp.back());}TEST(StringViewTest, NULLInput) {  absl::string_view s;  EXPECT_EQ(s.data(), nullptr);  EXPECT_EQ(s.size(), 0);  s = absl::string_view(nullptr);  EXPECT_EQ(s.data(), nullptr);  EXPECT_EQ(s.size(), 0);  // .ToString() on a absl::string_view with nullptr should produce the empty  // std::string.  EXPECT_EQ("", std::string(s));}TEST(StringViewTest, Comparisons2) {  // The `compare` member has 6 overloads (v: string_view, s: const char*):  //  (1) compare(v)  //  (2) compare(pos1, count1, v)  //  (3) compare(pos1, count1, v, pos2, count2)  //  (4) compare(s)  //  (5) compare(pos1, count1, s)  //  (6) compare(pos1, count1, s, count2)  absl::string_view abc("abcdefghijklmnopqrstuvwxyz");  // check comparison operations on strings longer than 4 bytes.  EXPECT_EQ(abc, absl::string_view("abcdefghijklmnopqrstuvwxyz"));  EXPECT_EQ(abc.compare(absl::string_view("abcdefghijklmnopqrstuvwxyz")), 0);  EXPECT_LT(abc, absl::string_view("abcdefghijklmnopqrstuvwxzz"));  EXPECT_LT(abc.compare(absl::string_view("abcdefghijklmnopqrstuvwxzz")), 0);  EXPECT_GT(abc, absl::string_view("abcdefghijklmnopqrstuvwxyy"));  EXPECT_GT(abc.compare(absl::string_view("abcdefghijklmnopqrstuvwxyy")), 0);  // The "substr" variants of `compare`.  absl::string_view digits("0123456789");  auto npos = absl::string_view::npos;  // Taking string_view  EXPECT_EQ(digits.compare(3, npos, absl::string_view("3456789")), 0);  // 2  EXPECT_EQ(digits.compare(3, 4, absl::string_view("3456")), 0);        // 2  EXPECT_EQ(digits.compare(10, 0, absl::string_view()), 0);             // 2  EXPECT_EQ(digits.compare(3, 4, absl::string_view("0123456789"), 3, 4),            0);  // 3  EXPECT_LT(digits.compare(3, 4, absl::string_view("0123456789"), 3, 5),            0);  // 3  EXPECT_LT(digits.compare(0, npos, absl::string_view("0123456789"), 3, 5),            0);  // 3  // Taking const char*  EXPECT_EQ(digits.compare(3, 4, "3456"), 0);                 // 5  EXPECT_EQ(digits.compare(3, npos, "3456789"), 0);           // 5  EXPECT_EQ(digits.compare(10, 0, ""), 0);                    // 5  EXPECT_EQ(digits.compare(3, 4, "0123456789", 3, 4), 0);     // 6  EXPECT_LT(digits.compare(3, 4, "0123456789", 3, 5), 0);     // 6  EXPECT_LT(digits.compare(0, npos, "0123456789", 3, 5), 0);  // 6}struct MyCharAlloc : std::allocator<char> {};TEST(StringViewTest, ExplicitConversionOperator) {  absl::string_view sp = "hi";  EXPECT_EQ(sp, std::string(sp));}TEST(StringViewTest, NullSafeStringView) {  {    absl::string_view s = absl::NullSafeStringView(nullptr);    EXPECT_EQ(nullptr, s.data());    EXPECT_EQ(0, s.size());    EXPECT_EQ(absl::string_view(), s);  }  {    static const char kHi[] = "hi";    absl::string_view s = absl::NullSafeStringView(kHi);    EXPECT_EQ(kHi, s.data());    EXPECT_EQ(strlen(kHi), s.size());    EXPECT_EQ(absl::string_view("hi"), s);  }}TEST(StringViewTest, ConstexprCompiles) {  constexpr absl::string_view sp;  constexpr absl::string_view cstr(nullptr);  constexpr absl::string_view cstr_len("cstr", 4);#if defined(ABSL_HAVE_STD_STRING_VIEW)  // In libstdc++ (as of 7.2), `std::string_view::string_view(const char*)`  // calls `std::char_traits<char>::length(const char*)` to get the std::string  // length, but it is not marked constexpr yet. See GCC bug:  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78156  // Also, there is a LWG issue that adds constexpr to length() which was just  // resolved 2017-06-02. See  // http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2232  // TODO(zhangxy): Update the condition when libstdc++ adopts the constexpr  // length().#if !defined(__GLIBCXX__)#define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1#endif  // !__GLIBCXX__#else  // ABSL_HAVE_STD_STRING_VIEW// This duplicates the check for __builtin_strlen in the header.#if ABSL_HAVE_BUILTIN(__builtin_strlen) || \    (defined(__GNUC__) && !defined(__clang__))#define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1#elif defined(__GNUC__)  // GCC or clang#error GCC/clang should have constexpr string_view.#endif#endif  // ABSL_HAVE_STD_STRING_VIEW#ifdef ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR  constexpr absl::string_view cstr_strlen("foo");  EXPECT_EQ(cstr_strlen.length(), 3);  constexpr absl::string_view cstr_strlen2 = "bar";  EXPECT_EQ(cstr_strlen2, "bar");#endif#if !defined(__clang__) || 3 < __clang_major__ || \  (3 == __clang_major__ && 4 < __clang_minor__)  // older clang versions (< 3.5) complain that:  //   "cannot perform pointer arithmetic on null pointer"  constexpr absl::string_view::iterator const_begin_empty = sp.begin();  constexpr absl::string_view::iterator const_end_empty = sp.end();  EXPECT_EQ(const_begin_empty, const_end_empty);#endif  constexpr absl::string_view::iterator const_begin = cstr_len.begin();  constexpr absl::string_view::iterator const_end = cstr_len.end();  constexpr absl::string_view::size_type const_size = cstr_len.size();  constexpr absl::string_view::size_type const_length = cstr_len.length();  EXPECT_EQ(const_begin + const_size, const_end);  EXPECT_EQ(const_begin + const_length, const_end);  constexpr bool isempty = sp.empty();  EXPECT_TRUE(isempty);  constexpr const char c = cstr_len[2];  EXPECT_EQ(c, 't');  constexpr const char cfront = cstr_len.front();  constexpr const char cback = cstr_len.back();  EXPECT_EQ(cfront, 'c');  EXPECT_EQ(cback, 'r');  constexpr const char* np = sp.data();  constexpr const char* cstr_ptr = cstr_len.data();  EXPECT_EQ(np, nullptr);  EXPECT_NE(cstr_ptr, nullptr);  constexpr size_t sp_npos = sp.npos;  EXPECT_EQ(sp_npos, -1);}TEST(StringViewTest, Noexcept) {  EXPECT_TRUE((std::is_nothrow_constructible<absl::string_view,                                             const std::string&>::value));  EXPECT_TRUE(      (std::is_nothrow_constructible<absl::string_view, const std::string&>::value));  EXPECT_TRUE(std::is_nothrow_constructible<absl::string_view>::value);  constexpr absl::string_view sp;  EXPECT_TRUE(noexcept(sp.begin()));  EXPECT_TRUE(noexcept(sp.end()));  EXPECT_TRUE(noexcept(sp.cbegin()));  EXPECT_TRUE(noexcept(sp.cend()));  EXPECT_TRUE(noexcept(sp.rbegin()));  EXPECT_TRUE(noexcept(sp.rend()));  EXPECT_TRUE(noexcept(sp.crbegin()));  EXPECT_TRUE(noexcept(sp.crend()));  EXPECT_TRUE(noexcept(sp.size()));  EXPECT_TRUE(noexcept(sp.length()));  EXPECT_TRUE(noexcept(sp.empty()));  EXPECT_TRUE(noexcept(sp.data()));  EXPECT_TRUE(noexcept(sp.compare(sp)));  EXPECT_TRUE(noexcept(sp.find(sp)));  EXPECT_TRUE(noexcept(sp.find('f')));  EXPECT_TRUE(noexcept(sp.rfind(sp)));  EXPECT_TRUE(noexcept(sp.rfind('f')));  EXPECT_TRUE(noexcept(sp.find_first_of(sp)));  EXPECT_TRUE(noexcept(sp.find_first_of('f')));  EXPECT_TRUE(noexcept(sp.find_last_of(sp)));  EXPECT_TRUE(noexcept(sp.find_last_of('f')));  EXPECT_TRUE(noexcept(sp.find_first_not_of(sp)));  EXPECT_TRUE(noexcept(sp.find_first_not_of('f')));  EXPECT_TRUE(noexcept(sp.find_last_not_of(sp)));  EXPECT_TRUE(noexcept(sp.find_last_not_of('f')));}TEST(ComparisonOpsTest, StringCompareNotAmbiguous) {  EXPECT_EQ("hello", std::string("hello"));  EXPECT_LT("hello", std::string("world"));}TEST(ComparisonOpsTest, HeterogenousStringViewEquals) {  EXPECT_EQ(absl::string_view("hello"), std::string("hello"));  EXPECT_EQ("hello", absl::string_view("hello"));}TEST(FindOneCharTest, EdgeCases) {  absl::string_view a("xxyyyxx");  // Set a = "xyyyx".  a.remove_prefix(1);  a.remove_suffix(1);  EXPECT_EQ(0, a.find('x'));  EXPECT_EQ(0, a.find('x', 0));  EXPECT_EQ(4, a.find('x', 1));  EXPECT_EQ(4, a.find('x', 4));  EXPECT_EQ(absl::string_view::npos, a.find('x', 5));  EXPECT_EQ(4, a.rfind('x'));  EXPECT_EQ(4, a.rfind('x', 5));  EXPECT_EQ(4, a.rfind('x', 4));  EXPECT_EQ(0, a.rfind('x', 3));  EXPECT_EQ(0, a.rfind('x', 0));  // Set a = "yyy".  a.remove_prefix(1);  a.remove_suffix(1);  EXPECT_EQ(absl::string_view::npos, a.find('x'));  EXPECT_EQ(absl::string_view::npos, a.rfind('x'));}#ifndef THREAD_SANITIZER  // Allocates too much memory for tsan.TEST(HugeStringView, TwoPointTwoGB) {  if (sizeof(size_t) <= 4 || RunningOnValgrind())    return;  // Try a huge std::string piece.  const size_t size = size_t{2200} * 1000 * 1000;  std::string s(size, 'a');  absl::string_view sp(s);  EXPECT_EQ(size, sp.length());  sp.remove_prefix(1);  EXPECT_EQ(size - 1, sp.length());  sp.remove_suffix(2);  EXPECT_EQ(size - 1 - 2, sp.length());}#endif  // THREAD_SANITIZER#ifndef NDEBUGTEST(NonNegativeLenTest, NonNegativeLen) {  EXPECT_DEATH_IF_SUPPORTED(absl::string_view("xyz", -1), "len <= kMaxSize");}#endif  // NDEBUGclass StringViewStreamTest : public ::testing::Test { public:  // Set negative 'width' for right justification.  template <typename T>  std::string Pad(const T& s, int width, char fill = 0) {    std::ostringstream oss;    if (fill != 0) {      oss << std::setfill(fill);    }    if (width < 0) {      width = -width;      oss << std::right;    }    oss << std::setw(width) << s;    return oss.str();  }};TEST_F(StringViewStreamTest, Padding) {  std::string s("hello");  absl::string_view sp(s);  for (int w = -64; w < 64; ++w) {    SCOPED_TRACE(w);    EXPECT_EQ(Pad(s, w), Pad(sp, w));  }  for (int w = -64; w < 64; ++w) {    SCOPED_TRACE(w);    EXPECT_EQ(Pad(s, w, '#'), Pad(sp, w, '#'));  }}TEST_F(StringViewStreamTest, ResetsWidth) {  // Width should reset after one formatted write.  // If we weren't resetting width after formatting the string_view,  // we'd have width=5 carrying over to the printing of the "]",  // creating "[###hi####]".  std::string s = "hi";  absl::string_view sp = s;  {    std::ostringstream oss;    oss << "[" << std::setfill('#') << std::setw(5) << s << "]";    ASSERT_EQ("[###hi]", oss.str());  }  {    std::ostringstream oss;    oss << "[" << std::setfill('#') << std::setw(5) << sp << "]";    EXPECT_EQ("[###hi]", oss.str());  }}}  // namespace
 |