blob: de3777a674e9199fcd6ec386b90f4fc4e40df906 [file] [log] [blame]
Ethan Nicholas2c9a6ec2021-06-07 16:09:59 -04001/*
2 * Copyright 2021 Google LLC.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkStringView_DEFINED
9#define SkStringView_DEFINED
10
Brian Osmanf80ef382021-09-01 14:57:44 -040011#include <algorithm>
Ethan Nicholas2c9a6ec2021-06-07 16:09:59 -040012#include <cstring>
13#include <string>
14
15namespace skstd {
16
17class string_view {
18public:
19 using value_type = char;
20 using traits_type = std::char_traits<value_type>;
21 using const_pointer = const value_type*;
22 using const_reference = const value_type&;
23 using iterator = const_pointer;
24 using const_iterator = iterator;
25 using size_type = size_t;
Brian Osmanf80ef382021-09-01 14:57:44 -040026 static constexpr size_type npos = size_type(-1);
Ethan Nicholas2c9a6ec2021-06-07 16:09:59 -040027
28 constexpr string_view()
29 : fData(nullptr)
30 , fLength(0) {}
31
32 constexpr string_view(const string_view&) = default;
33
34 constexpr string_view(const_pointer data, size_type length)
35 : fData(data)
36 , fLength(length) {}
37
38 string_view(const_pointer data)
39 : string_view(data, strlen(data)) {}
40
Ethan Nicholas9173b3f2021-06-09 11:26:09 -040041 string_view(const std::string& str)
Ethan Nicholas2c9a6ec2021-06-07 16:09:59 -040042 : string_view(str.data(), str.length()) {}
43
44 constexpr string_view& operator=(const string_view&) = default;
45
46 constexpr iterator begin() const {
47 return fData;
48 }
49
50 constexpr iterator end() const {
51 return fData + fLength;
52 }
53
54 constexpr const_reference operator[](size_type idx) const {
55 return fData[idx];
56 }
57
58 constexpr const_reference front() const {
59 return fData[0];
60 }
61
62 constexpr const_reference back() const {
63 return fData[fLength - 1];
64 }
65
66 constexpr const_pointer data() const {
67 return fData;
68 }
69
70 constexpr size_type size() const {
71 return fLength;
72 }
73
74 constexpr size_type length() const {
75 return fLength;
76 }
77
78 constexpr bool empty() const {
79 return fLength == 0;
80 }
81
82 constexpr bool starts_with(string_view s) const {
83 if (s.length() > fLength) {
84 return false;
85 }
86 return s.length() == 0 || !memcmp(fData, s.fData, s.length());
87 }
88
89 constexpr bool starts_with(value_type c) const {
90 return !this->empty() && this->front() == c;
91 }
92
93 constexpr bool ends_with(string_view s) const {
94 if (s.length() > fLength) {
95 return false;
96 }
97 return s.length() == 0 || !memcmp(this->end() - s.length(), s.fData, s.length());
98 }
99
100 constexpr bool ends_with(value_type c) const {
101 return !this->empty() && this->back() == c;
102 }
103
Brian Osmanf80ef382021-09-01 14:57:44 -0400104 constexpr string_view substr(size_type pos = 0, size_type count = npos) const {
105 if (pos > fLength) {
106 return {};
107 }
108 return string_view{fData + pos, std::min(count, fLength - pos)};
109 }
110
Ethan Nicholas2c9a6ec2021-06-07 16:09:59 -0400111 constexpr void swap(string_view& other) {
112 const_pointer tempData = fData;
113 fData = other.fData;
114 other.fData = tempData;
115
116 size_type tempLength = fLength;
117 fLength = other.fLength;
118 other.fLength = tempLength;
119 }
120
Ethan Nicholasd2e09602021-06-10 11:21:59 -0400121 constexpr void remove_prefix(size_type n) {
122 fData += n;
123 fLength -= n;
124 }
125
126 constexpr void remove_suffix(size_type n) {
127 fLength -= n;
128 }
129
Ethan Nicholas2c9a6ec2021-06-07 16:09:59 -0400130private:
131 const_pointer fData;
132 size_type fLength;
133};
134
135bool operator==(string_view left, string_view right);
136
137bool operator!=(string_view left, string_view right);
138
139bool operator<(string_view left, string_view right);
140
141bool operator<=(string_view left, string_view right);
142
143bool operator>(string_view left, string_view right);
144
145bool operator>=(string_view left, string_view right);
146
147} // namespace skstd
148
Ethan Nicholasd2e09602021-06-10 11:21:59 -0400149namespace std {
150 template<> struct hash<skstd::string_view> {
151 size_t operator()(const skstd::string_view& s) const {
152 size_t result = 0;
153 for (auto iter = s.begin(); iter != s.end(); ++iter) {
154 result = result * 101 + (size_t) *iter;
155 }
156 return result;
157 }
158 };
159} // namespace std
160
Ethan Nicholas2c9a6ec2021-06-07 16:09:59 -0400161#endif