openMSX
zstring_view.hh
Go to the documentation of this file.
1#ifndef ZSTRING_VIEW_HH
2#define ZSTRING_VIEW_HH
3
4#include <cassert>
5#include <cstring>
6#include <iostream>
7#include <string>
8#include <string_view>
9#include <type_traits>
10
22{
23public:
24 using size_type = size_t;
25 using const_iterator = const char*;
26
27 static constexpr auto npos = std::string_view::npos;
28
29 constexpr zstring_view()
30 : dat(nullptr), siz(0) {}
31 constexpr zstring_view(const char* s)
32 : dat(s), siz(std::char_traits<char>::length(s)) {}
33 constexpr zstring_view(const char* s, size_t n)
34 : dat(s), siz(n) { assert(s[n] == '\0'); }
35 /*constexpr*/ zstring_view(const std::string& s)
36 : dat(s.c_str()), siz(s.size()) {}
37
38 [[nodiscard]] constexpr auto begin() const { return dat; }
39 [[nodiscard]] constexpr auto end() const { return dat + siz; }
40
41 [[nodiscard]] constexpr auto size() const { return siz; }
42 [[nodiscard]] constexpr auto empty() const { return siz == 0; }
43
44 [[nodiscard]] constexpr char operator[](size_type i) const {
45 assert(i < siz);
46 return dat[i];
47 }
48 [[nodiscard]] constexpr char front() const { return *dat; }
49 [[nodiscard]] constexpr char back() const { return *(dat + siz - 1); }
50 [[nodiscard]] constexpr const char* data() const { return dat; }
51 [[nodiscard]] constexpr const char* c_str() const { return dat; }
52
53 [[nodiscard]] constexpr auto find(char c, size_type pos = 0) const {
54 return view().find(c, pos);
55 }
56 [[nodiscard]] constexpr auto find(const char* s, size_type pos = 0) const {
57 return view().find(s, pos);
58 }
59
60 [[nodiscard]] constexpr zstring_view substr(size_type pos) const {
61 assert(pos <= siz);
62 return {dat + pos, siz - pos};
63 }
64 [[nodiscard]] constexpr std::string_view substr(size_type pos, size_type count) const {
65 assert(pos <= siz);
66 return view().substr(pos, count);
67 }
68
69 [[nodiscard]] constexpr bool starts_with(std::string_view sv) const {
70 return view().starts_with(sv);
71 }
72 [[nodiscard]] constexpr bool starts_with(char c) const {
73 return view().starts_with(c);
74 }
75 [[nodiscard]] constexpr bool starts_with(const char* s) const {
76 return view().starts_with(s);
77 }
78 [[nodiscard]] constexpr bool ends_with(std::string_view sv) const {
79 return view().ends_with(sv);
80 }
81 [[nodiscard]] constexpr bool ends_with(char c) const {
82 return view().ends_with(c);
83 }
84 [[nodiscard]] constexpr bool ends_with(const char* s) const {
85 return view().ends_with(s);
86 }
87 [[nodiscard]] constexpr bool contains(std::string_view sv) const {
88 return view().contains(sv);
89 }
90 [[nodiscard]] constexpr bool contains(char c) const {
91 return view().contains(c);
92 }
93 [[nodiscard]] constexpr bool contains(const char* s) const {
94 return view().contains(s);
95 }
96
97 [[nodiscard]] explicit operator std::string() const {
98 return {dat, siz};
99 }
100 [[nodiscard]] constexpr std::string_view view() const {
101 return {dat, siz};
102 }
103 [[nodiscard]] explicit(false) constexpr operator std::string_view() const {
104 return view();
105 }
106
107 [[nodiscard]] constexpr friend bool operator==(const zstring_view& x, const zstring_view& y) {
108 return std::string_view(x) == std::string_view(y);
109 }
110 [[nodiscard]] inline friend bool operator==(const zstring_view& x, const std::string& y) {
111 return std::string_view(x) == std::string_view(y);
112 }
113 [[nodiscard]] constexpr friend bool operator==(const zstring_view& x, const std::string_view& y) {
114 return std::string_view(x) == y;
115 }
116 [[nodiscard]] constexpr friend bool operator==(const zstring_view& x, const char* y) {
117 return std::string_view(x) == std::string_view(y);
118 }
119
120 friend std::ostream& operator<<(std::ostream& os, const zstring_view& str)
121 {
122 os << std::string_view(str);
123 return os;
124 }
125
126private:
127 const char* dat;
128 size_type siz;
129};
130
131static_assert(std::is_trivially_destructible_v<zstring_view>);
132static_assert(std::is_trivially_copyable_v<zstring_view>);
133static_assert(std::is_trivially_copy_constructible_v<zstring_view>);
134static_assert(std::is_trivially_move_constructible_v<zstring_view>);
135static_assert(std::is_trivially_assignable_v<zstring_view, zstring_view>);
136static_assert(std::is_trivially_copy_assignable_v<zstring_view>);
137static_assert(std::is_trivially_move_assignable_v<zstring_view>);
138
139[[nodiscard]] constexpr auto begin(const zstring_view& x) { return x.begin(); }
140[[nodiscard]] constexpr auto end (const zstring_view& x) { return x.end(); }
141
142// !!! Workaround clang-15, libc++ bug !!! (fixed in clang-16)
143// These should be 4x operator<=> instead of 4x operator<, <=, >=, >
144[[nodiscard]] constexpr auto operator<(const zstring_view& x, const zstring_view& y) {
145 return std::string_view(x) < std::string_view(y);
146}
147[[nodiscard]] inline auto operator<(const zstring_view& x, const std::string& y) {
148 return std::string_view(x) < std::string_view(y);
149}
150[[nodiscard]] constexpr auto operator<(const zstring_view& x, const std::string_view& y) {
151 return std::string_view(x) < y;
152}
153[[nodiscard]] constexpr auto operator<(const zstring_view& x, const char* y) {
154 return std::string_view(x) < std::string_view(y);
155}
156[[nodiscard]] constexpr auto operator<=(const zstring_view& x, const zstring_view& y) {
157 return std::string_view(x) <= std::string_view(y);
158}
159[[nodiscard]] inline auto operator<=(const zstring_view& x, const std::string& y) {
160 return std::string_view(x) <= std::string_view(y);
161}
162[[nodiscard]] constexpr auto operator<=(const zstring_view& x, const std::string_view& y) {
163 return std::string_view(x) <= y;
164}
165[[nodiscard]] constexpr auto operator<=(const zstring_view& x, const char* y) {
166 return std::string_view(x) <= std::string_view(y);
167}
168[[nodiscard]] constexpr auto operator>(const zstring_view& x, const zstring_view& y) {
169 return std::string_view(x) > std::string_view(y);
170}
171[[nodiscard]] inline auto operator>(const zstring_view& x, const std::string& y) {
172 return std::string_view(x) > std::string_view(y);
173}
174[[nodiscard]] constexpr auto operator>(const zstring_view& x, const std::string_view& y) {
175 return std::string_view(x) > y;
176}
177[[nodiscard]] constexpr auto operator>(const zstring_view& x, const char* y) {
178 return std::string_view(x) > std::string_view(y);
179}
180[[nodiscard]] constexpr auto operator>=(const zstring_view& x, const zstring_view& y) {
181 return std::string_view(x) >= std::string_view(y);
182}
183[[nodiscard]] inline auto operator>=(const zstring_view& x, const std::string& y) {
184 return std::string_view(x) >= std::string_view(y);
185}
186[[nodiscard]] constexpr auto operator>=(const zstring_view& x, const std::string_view& y) {
187 return std::string_view(x) >= y;
188}
189[[nodiscard]] constexpr auto operator>=(const zstring_view& x, const char* y) {
190 return std::string_view(x) >= std::string_view(y);
191}
192
193#endif
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
constexpr bool ends_with(char c) const
constexpr bool contains(char c) const
constexpr zstring_view(const char *s)
constexpr bool starts_with(char c) const
constexpr auto begin() const
constexpr bool starts_with(const char *s) const
constexpr auto size() const
constexpr auto find(const char *s, size_type pos=0) const
constexpr char back() const
zstring_view(const std::string &s)
friend std::ostream & operator<<(std::ostream &os, const zstring_view &str)
constexpr std::string_view substr(size_type pos, size_type count) const
constexpr zstring_view(const char *s, size_t n)
constexpr const char * data() const
constexpr char operator[](size_type i) const
constexpr friend bool operator==(const zstring_view &x, const char *y)
const char * const_iterator
constexpr bool ends_with(std::string_view sv) const
constexpr zstring_view()
constexpr auto end() const
constexpr bool ends_with(const char *s) const
static constexpr auto npos
constexpr bool contains(std::string_view sv) const
constexpr const char * c_str() const
constexpr char front() const
constexpr auto find(char c, size_type pos=0) const
constexpr bool contains(const char *s) const
constexpr zstring_view substr(size_type pos) const
constexpr bool starts_with(std::string_view sv) const
constexpr auto empty() const
friend bool operator==(const zstring_view &x, const std::string &y)
constexpr std::string_view view() const
constexpr friend bool operator==(const zstring_view &x, const std::string_view &y)
STL namespace.
constexpr auto operator<(const zstring_view &x, const zstring_view &y)
constexpr auto operator>(const zstring_view &x, const zstring_view &y)
constexpr auto operator<=(const zstring_view &x, const zstring_view &y)
constexpr auto operator>=(const zstring_view &x, const zstring_view &y)
constexpr auto begin(const zstring_view &x)
constexpr auto end(const zstring_view &x)