1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2021 Google LLC. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#ifndef SkStringView_DEFINED 9cb93a386Sopenharmony_ci#define SkStringView_DEFINED 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ci#include <algorithm> 14cb93a386Sopenharmony_ci#include <cstring> 15cb93a386Sopenharmony_ci#include <string> 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_cinamespace skstd { 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ciclass string_view { 20cb93a386Sopenharmony_cipublic: 21cb93a386Sopenharmony_ci using value_type = char; 22cb93a386Sopenharmony_ci using traits_type = std::char_traits<value_type>; 23cb93a386Sopenharmony_ci using const_pointer = const value_type*; 24cb93a386Sopenharmony_ci using const_reference = const value_type&; 25cb93a386Sopenharmony_ci using iterator = const_pointer; 26cb93a386Sopenharmony_ci using const_iterator = iterator; 27cb93a386Sopenharmony_ci using size_type = size_t; 28cb93a386Sopenharmony_ci static constexpr size_type npos = size_type(-1); 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci constexpr string_view() 31cb93a386Sopenharmony_ci : fData(nullptr) 32cb93a386Sopenharmony_ci , fLength(0) {} 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci constexpr string_view(const string_view&) = default; 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ci constexpr string_view(const_pointer data, size_type length) 37cb93a386Sopenharmony_ci : fData(data) 38cb93a386Sopenharmony_ci , fLength(length) {} 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ci string_view(const_pointer data) 41cb93a386Sopenharmony_ci : string_view(data, strlen(data)) {} 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_ci string_view(const std::string& str) 44cb93a386Sopenharmony_ci : string_view(str.data(), str.length()) {} 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ci constexpr string_view& operator=(const string_view&) = default; 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ci constexpr iterator begin() const { 49cb93a386Sopenharmony_ci return fData; 50cb93a386Sopenharmony_ci } 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci constexpr iterator end() const { 53cb93a386Sopenharmony_ci return fData + fLength; 54cb93a386Sopenharmony_ci } 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci constexpr const_reference operator[](size_type idx) const { 57cb93a386Sopenharmony_ci return fData[idx]; 58cb93a386Sopenharmony_ci } 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci constexpr const_reference front() const { 61cb93a386Sopenharmony_ci return fData[0]; 62cb93a386Sopenharmony_ci } 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci constexpr const_reference back() const { 65cb93a386Sopenharmony_ci return fData[fLength - 1]; 66cb93a386Sopenharmony_ci } 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci constexpr const_pointer data() const { 69cb93a386Sopenharmony_ci return fData; 70cb93a386Sopenharmony_ci } 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ci constexpr size_type size() const { 73cb93a386Sopenharmony_ci return fLength; 74cb93a386Sopenharmony_ci } 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_ci constexpr size_type length() const { 77cb93a386Sopenharmony_ci return fLength; 78cb93a386Sopenharmony_ci } 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci constexpr bool empty() const { 81cb93a386Sopenharmony_ci return fLength == 0; 82cb93a386Sopenharmony_ci } 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_ci constexpr bool starts_with(string_view s) const { 85cb93a386Sopenharmony_ci if (s.length() > fLength) { 86cb93a386Sopenharmony_ci return false; 87cb93a386Sopenharmony_ci } 88cb93a386Sopenharmony_ci return s.length() == 0 || !memcmp(fData, s.fData, s.length()); 89cb93a386Sopenharmony_ci } 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_ci constexpr bool starts_with(value_type c) const { 92cb93a386Sopenharmony_ci return !this->empty() && this->front() == c; 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci constexpr bool ends_with(string_view s) const { 96cb93a386Sopenharmony_ci if (s.length() > fLength) { 97cb93a386Sopenharmony_ci return false; 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci return s.length() == 0 || !memcmp(this->end() - s.length(), s.fData, s.length()); 100cb93a386Sopenharmony_ci } 101cb93a386Sopenharmony_ci 102cb93a386Sopenharmony_ci constexpr bool ends_with(value_type c) const { 103cb93a386Sopenharmony_ci return !this->empty() && this->back() == c; 104cb93a386Sopenharmony_ci } 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_ci size_type find(string_view needle, size_type pos = 0) const { 107cb93a386Sopenharmony_ci if (needle.length() == 0) { 108cb93a386Sopenharmony_ci return 0; 109cb93a386Sopenharmony_ci } 110cb93a386Sopenharmony_ci if (this->length() < needle.length()) { 111cb93a386Sopenharmony_ci return npos; 112cb93a386Sopenharmony_ci } 113cb93a386Sopenharmony_ci const char* match = nullptr; 114cb93a386Sopenharmony_ci const char* start = this->data() + pos; 115cb93a386Sopenharmony_ci const char* end = start + this->length() - needle.length() + 1; 116cb93a386Sopenharmony_ci while ((match = (const char*)(memchr(start, needle[0], (size_t)(end - start))))) { 117cb93a386Sopenharmony_ci if (!memcmp(match, needle.data(), needle.length())) { 118cb93a386Sopenharmony_ci return (size_type)(match - this->data()); 119cb93a386Sopenharmony_ci } else { 120cb93a386Sopenharmony_ci start = match + 1; 121cb93a386Sopenharmony_ci } 122cb93a386Sopenharmony_ci } 123cb93a386Sopenharmony_ci return npos; 124cb93a386Sopenharmony_ci } 125cb93a386Sopenharmony_ci 126cb93a386Sopenharmony_ci bool contains(string_view needle) const { 127cb93a386Sopenharmony_ci return this->find(needle) != npos; 128cb93a386Sopenharmony_ci } 129cb93a386Sopenharmony_ci 130cb93a386Sopenharmony_ci constexpr string_view substr(size_type pos = 0, size_type count = npos) const { 131cb93a386Sopenharmony_ci if (pos > fLength) { 132cb93a386Sopenharmony_ci return {}; 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci return string_view{fData + pos, std::min(count, fLength - pos)}; 135cb93a386Sopenharmony_ci } 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci constexpr void swap(string_view& other) { 138cb93a386Sopenharmony_ci const_pointer tempData = fData; 139cb93a386Sopenharmony_ci fData = other.fData; 140cb93a386Sopenharmony_ci other.fData = tempData; 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ci size_type tempLength = fLength; 143cb93a386Sopenharmony_ci fLength = other.fLength; 144cb93a386Sopenharmony_ci other.fLength = tempLength; 145cb93a386Sopenharmony_ci } 146cb93a386Sopenharmony_ci 147cb93a386Sopenharmony_ci constexpr void remove_prefix(size_type n) { 148cb93a386Sopenharmony_ci fData += n; 149cb93a386Sopenharmony_ci fLength -= n; 150cb93a386Sopenharmony_ci } 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_ci constexpr void remove_suffix(size_type n) { 153cb93a386Sopenharmony_ci fLength -= n; 154cb93a386Sopenharmony_ci } 155cb93a386Sopenharmony_ci 156cb93a386Sopenharmony_ciprivate: 157cb93a386Sopenharmony_ci const_pointer fData; 158cb93a386Sopenharmony_ci size_type fLength; 159cb93a386Sopenharmony_ci}; 160cb93a386Sopenharmony_ci 161cb93a386Sopenharmony_ciSK_API bool operator==(string_view left, string_view right); 162cb93a386Sopenharmony_ci 163cb93a386Sopenharmony_ciSK_API bool operator!=(string_view left, string_view right); 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_ciSK_API bool operator<(string_view left, string_view right); 166cb93a386Sopenharmony_ci 167cb93a386Sopenharmony_ciSK_API bool operator<=(string_view left, string_view right); 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_ciSK_API bool operator>(string_view left, string_view right); 170cb93a386Sopenharmony_ci 171cb93a386Sopenharmony_ciSK_API bool operator>=(string_view left, string_view right); 172cb93a386Sopenharmony_ci 173cb93a386Sopenharmony_ci} // namespace skstd 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_cinamespace std { 176cb93a386Sopenharmony_ci template<> struct hash<skstd::string_view> { 177cb93a386Sopenharmony_ci size_t operator()(const skstd::string_view& s) const { 178cb93a386Sopenharmony_ci size_t result = 0; 179cb93a386Sopenharmony_ci for (auto iter = s.begin(); iter != s.end(); ++iter) { 180cb93a386Sopenharmony_ci result = result * 101 + (size_t) *iter; 181cb93a386Sopenharmony_ci } 182cb93a386Sopenharmony_ci return result; 183cb93a386Sopenharmony_ci } 184cb93a386Sopenharmony_ci }; 185cb93a386Sopenharmony_ci} // namespace std 186cb93a386Sopenharmony_ci 187cb93a386Sopenharmony_ci#endif 188