openMSX
string_ref.hh
Go to the documentation of this file.
1 #ifndef STRING_REF_HH
2 #define STRING_REF_HH
3 
4 #include <string>
5 #include <iterator>
6 #include <iosfwd>
7 #include <cassert>
8 #include <cstring>
9 
19 {
20 public:
21  using size_type = size_t;
22  using difference_type = std::ptrdiff_t;
23  using const_iterator = const char*;
24  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
25 
26  static const size_type npos = size_type(-1);
27 
28  // construct/copy/assign
30  : dat(nullptr), siz(0) {}
32  : dat(s.dat), siz(s.siz) {}
33  /*implicit*/ string_ref(const char* s)
34  : dat(s), siz(s ? size_type(strlen(s)) : 0) {}
35  string_ref(const char* s, size_type len)
36  : dat(s), siz(len) { if (!dat) assert(siz == 0); }
37  string_ref(const char* first, const char* last)
38  : dat(first), siz(last - first) { if (!dat) assert(siz == 0); }
39  /*implicit*/ string_ref(const std::string& s)
40  : dat(s.data()), siz(s.size()) {}
41 
43  dat = rhs.data();
44  siz = rhs.size();
45  return *this;
46  }
47 
48  // iterators
49  const_iterator begin() const { return dat; }
50  const_iterator end() const { return dat + siz; }
53 
54  // capacity
55  size_type size() const { return siz; }
56  bool empty() const { return siz == 0; }
57  //size_type max_size() const;
58  //size_type length() const;
59 
60  // element access
61  char operator[](size_type i) const {
62  assert(i < siz);
63  return dat[i];
64  }
65  //const char& at(size_type i) const;
66  char front() const { return *dat; }
67  char back() const { return *(dat + siz - 1); }
68  const char* data() const { return dat; }
69 
70  // Outgoing conversion operators
71  //explicit operator std::string() const; // c++11
72  std::string str() const;
73 
74  // mutators
75  void clear() { siz = 0; } // no need to change 'dat'
77  if (n <= siz) {
78  dat += n;
79  siz -= n;
80  } else {
81  clear();
82  }
83  }
85  if (n <= siz) {
86  siz -= n;
87  } else {
88  clear();
89  }
90  }
91  void pop_back() { remove_suffix(1); }
92  void pop_front() { remove_prefix(1); }
93 
94  // string operations with the same semantics as std::string
95  int compare(string_ref x) const;
96  string_ref substr(size_type pos, size_type n = npos) const;
97  //size_type copy(char* buf) const;
98  size_type find(string_ref s) const;
99  size_type find(char c) const;
100  size_type rfind(string_ref s) const;
101  size_type rfind(char c) const;
103  size_type find_first_of(char c) const;
104  //size_type find_first_not_of(string_ref s) const;
105  //size_type find_first_not_of(char c) const;
107  size_type find_last_of(char c) const;
108  //size_type find_last_not_of(string_ref s) const;
109  //size_type find_last_not_of(char c) const;
110 
111  // new string operations (not part of std::string)
112  bool starts_with(string_ref x) const;
113  bool starts_with(char x) const;
114  bool ends_with(string_ref x) const;
115  bool ends_with(char x) const;
116 
117 private:
118  const char* dat;
119  size_type siz;
120 };
121 
122 
123 // Comparison operators
124 inline bool operator==(string_ref x, string_ref y) {
125  return (x.size() == y.size()) &&
126  (memcmp(x.data(), y.data(), x.size()) == 0);
127 }
128 
129 bool operator< (string_ref x, string_ref y);
130 inline bool operator!=(string_ref x, string_ref y) { return !(x == y); }
131 inline bool operator> (string_ref x, string_ref y) { return (y < x); }
132 inline bool operator<=(string_ref x, string_ref y) { return !(y < x); }
133 inline bool operator>=(string_ref x, string_ref y) { return !(x < y); }
134 
135 // numeric conversions
136 //int stoi (string_ref s, string_ref::size_type* idx = nullptr, int base = 0);
137 //long stol (string_ref s, string_ref::size_type* idx = nullptr, int base = 0);
138 //unsigned long stoul (string_ref s, string_ref::size_type* idx = nullptr, int base = 0);
139 //long long stoll (string_ref s, string_ref::size_type* idx = nullptr, int base = 0);
140 //unsigned long long stoull(string_ref s, string_ref::size_type* idx = nullptr, int base = 0);
141 //float stof (string_ref s, string_ref::size_type* idx = nullptr);
142 //double stod (string_ref s, string_ref::size_type* idx = nullptr);
143 //long double stold (string_ref s, string_ref::size_type* idx = nullptr);
144 
145 
146 // Faster than the above, but less general (not part of the std proposal):
147 // - Only handles decimal.
148 // - No leading + or - sign (and thus only positive values).
149 // - No leading whitespace.
150 // - No trailing non-digit characters.
151 // - No out-of-range check (so undetected overflow on e.g. 9999999999).
152 // - Empty string parses as zero.
153 // Throws std::invalid_argument if any character is different from [0-9],
154 // similar to the error reporting in the std::stoi() (and related) functions.
155 unsigned fast_stou(string_ref s);
156 
157 
158 // concatenation (this is not part of the std::string_ref proposal)
159 std::string operator+(string_ref x, string_ref y);
160 std::string operator+(char x, string_ref y);
161 std::string operator+(string_ref x, char y);
162 
163 std::ostream& operator<<(std::ostream& os, string_ref s);
164 
165 // begin, end
166 inline string_ref::const_iterator begin(const string_ref& x) { return x.begin(); }
167 inline string_ref::const_iterator end (const string_ref& x) { return x.end(); }
168 
169 #endif
unsigned fast_stou(string_ref s)
Definition: string_ref.cc:145
bool operator<(string_ref x, string_ref y)
Definition: string_ref.cc:138
string_ref(const char *first, const char *last)
Definition: string_ref.hh:37
void pop_front()
Definition: string_ref.hh:92
size_type find_last_of(string_ref s) const
Definition: string_ref.cc:101
bool ends_with(string_ref x) const
Definition: string_ref.cc:126
const_reverse_iterator rend() const
Definition: string_ref.hh:52
bool operator==(string_ref x, string_ref y)
Definition: string_ref.hh:124
void pop_back()
Definition: string_ref.hh:91
void remove_suffix(size_type n)
Definition: string_ref.hh:84
This class implements a subset of the proposal for std::string_ref (proposed for the next c++ standar...
Definition: string_ref.hh:18
const_iterator end() const
Definition: string_ref.hh:50
int compare(string_ref x) const
Definition: string_ref.cc:21
bool empty() const
Definition: string_ref.hh:56
std::string operator+(string_ref x, string_ref y)
Definition: string_ref.cc:162
const_iterator begin() const
Definition: string_ref.hh:49
const char * data() const
Definition: string_ref.hh:68
void remove_prefix(size_type n)
Definition: string_ref.hh:76
bool starts_with(string_ref x) const
Definition: string_ref.cc:116
const_reverse_iterator rbegin() const
Definition: string_ref.hh:51
std::ptrdiff_t difference_type
Definition: string_ref.hh:22
size_t size_type
Definition: string_ref.hh:21
std::string str() const
Definition: string_ref.cc:12
static const size_type npos
Definition: string_ref.hh:26
void clear()
Definition: string_ref.hh:75
string_ref substr(size_type pos, size_type n=npos) const
Definition: string_ref.cc:32
string_ref(const string_ref &s)
Definition: string_ref.hh:31
string_ref & operator=(const string_ref &rhs)
Definition: string_ref.hh:42
size_type rfind(string_ref s) const
Definition: string_ref.cc:65
bool operator!=(string_ref x, string_ref y)
Definition: string_ref.hh:130
char back() const
Definition: string_ref.hh:67
string_ref(const char *s, size_type len)
Definition: string_ref.hh:35
string_ref(const char *s)
Definition: string_ref.hh:33
size_type size() const
Definition: string_ref.hh:55
bool operator<=(string_ref x, string_ref y)
Definition: string_ref.hh:132
const char * const_iterator
Definition: string_ref.hh:23
bool operator>=(string_ref x, string_ref y)
Definition: string_ref.hh:133
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: string_ref.hh:24
bool operator>(string_ref x, string_ref y)
Definition: string_ref.hh:131
size_type find_first_of(string_ref s) const
Definition: string_ref.cc:87
char front() const
Definition: string_ref.hh:66
string_ref(const std::string &s)
Definition: string_ref.hh:39
char operator[](size_type i) const
Definition: string_ref.hh:61
std::ostream & operator<<(std::ostream &os, string_ref s)
Definition: string_ref.cc:188
size_type find(string_ref s) const
Definition: string_ref.cc:38