openMSX
string_view.cc
Go to the documentation of this file.
1 #include "string_view.hh"
2 #include "likely.hh"
3 #include <algorithm>
4 #include <iostream>
5 #include <cstdlib>
6 #include <stdexcept>
7 
8 using std::string;
9 
10 // Outgoing conversion operators
11 
12 string string_view::str() const
13 {
14  return siz ? string(dat, siz)
15  : string();
16 }
17 
18 
19 // string operations with the same semantics as std::string
20 
22 {
23  // Check prefix.
24  if (int r = memcmp(dat, x.dat, std::min(siz, x.siz))) {
25  return r;
26  }
27  // Prefixes match, check length.
28  return int(siz - x.siz); // Note: this overflows for very large strings.
29 }
30 
31 
33 {
34  if (pos >= siz) return string_view();
35  return string_view(dat + pos, std::min(n, siz - pos));
36 }
37 
39 {
40  // Simple string search algorithm O(size() * s.size()). An algorithm
41  // like Boyer–Moore has better time complexity and will run a lot
42  // faster on large strings. Though when the strings are relatively
43  // short (the typically case?) this very simple algorithm may run
44  // faster (because it has no setup-time). The implementation of
45  // std::string::find() in gcc uses a similar simple algorithm.
46  if (s.empty()) return 0;
47  if (s.size() <= siz) {
48  auto m = siz - s.size();
49  for (size_type pos = 0; pos <= m; ++pos) {
50  if ((dat[pos] == s[0]) &&
51  std::equal(s.begin() + 1, s.end(), dat + pos + 1)) {
52  return pos;
53  }
54  }
55  }
56  return npos;
57 }
58 
60 {
61  auto it = std::find(begin(), end(), c);
62  return (it == end()) ? npos : it - begin();
63 }
64 
66 {
67  // see comment in find()
68  if (s.empty()) return siz;
69  if (s.size() <= siz) {
70  auto m = siz - s.size();
71  for (auto pos = m; pos != size_type(-1); --pos) {
72  if ((dat[pos] == s[0]) &&
73  std::equal(s.begin() + 1, s.end(), dat + pos + 1)) {
74  return pos;
75  }
76  }
77  }
78  return npos;
79 }
80 
82 {
83  auto it = std::find(rbegin(), rend(), c);
84  return (it == rend()) ? npos : (it.base() - begin() - 1);
85 }
86 
88 {
89  auto it = std::find_first_of(begin(), end(), s.begin(), s.end());
90  return (it == end()) ? npos : it - begin();
91 }
92 
94 {
95  return find(c);
96 }
97 
98 //string_view::size_type string_view::find_first_not_of(string_view s) const;
99 //string_view::size_type string_view::find_first_not_of(char c) const;
100 
102 {
103  auto it = std::find_first_of(rbegin(), rend(), s.begin(), s.end());
104  return (it == rend()) ? npos : (it.base() - begin() - 1);
105 }
106 
108 {
109  return rfind(c);
110 }
111 
112 //string_view::size_type string_view::find_last_not_of(string_view s) const;
113 //string_view::size_type string_view::find_last_not_of(char c) const;
114 
115 // new string operations (not part of std::string)
117 {
118  return (siz >= x.size()) &&
119  (memcmp(dat, x.data(), x.size()) == 0);
120 }
121 bool string_view::starts_with(char x) const
122 {
123  return !empty() && (front() == x);
124 }
125 
127 {
128  return (siz >= x.size()) &&
129  (memcmp(dat + siz - x.size(), x.data(), x.size()) == 0);
130 }
131 bool string_view::ends_with(char x) const
132 {
133  return !empty() && (back() == x);
134 }
135 
136 
137 // Comparison operators
139 {
140  return x.compare(y) < 0;
141 }
142 
143 
144 // numeric conversions
146 {
147  unsigned result = 0;
148  for (char c : s) {
149  unsigned d = c - '0';
150  if (unlikely(d > 9)) {
151  throw std::invalid_argument("fast_stoi");
152  }
153  result *= 10;
154  result += d;
155  }
156  return result;
157 }
158 
159 
160 std::ostream& operator<<(std::ostream& os, string_view s)
161 {
162  os.write(s.data(), s.size());
163  return os;
164 }
const char * data() const
Definition: string_view.hh:57
auto rend() const
Definition: string_view.hh:41
auto find(InputRange &&range, const T &value)
Definition: ranges.hh:107
auto rbegin() const
Definition: string_view.hh:40
bool starts_with(string_view x) const
Definition: string_view.cc:116
size_type find_first_of(string_view s) const
Definition: string_view.cc:87
#define unlikely(x)
Definition: likely.hh:15
bool operator<(string_view x, string_view y)
Definition: string_view.cc:138
vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:269
size_type find_last_of(string_view s) const
Definition: string_view.cc:101
char back() const
Definition: string_view.hh:56
bool ends_with(string_view x) const
Definition: string_view.cc:126
static const size_type npos
Definition: string_view.hh:24
int compare(string_view x) const
Definition: string_view.cc:21
char front() const
Definition: string_view.hh:55
std::ostream & operator<<(std::ostream &os, string_view s)
Definition: string_view.cc:160
size_type find(string_view s) const
Definition: string_view.cc:38
size_t size_type
Definition: string_view.hh:19
size_type rfind(string_view s) const
Definition: string_view.cc:65
bool empty() const
Definition: string_view.hh:45
This class implements a (close approximation) of the std::string_view class.
Definition: string_view.hh:16
auto begin() const
Definition: string_view.hh:38
std::string str() const
Definition: string_view.cc:12
string_view substr(size_type pos, size_type n=npos) const
Definition: string_view.cc:32
string_view()=default
size_type size() const
Definition: string_view.hh:44
auto end() const
Definition: string_view.hh:39
unsigned fast_stou(string_view s)
Definition: string_view.cc:145