forked from Banderi/Ozymandias
-
-
Notifications
You must be signed in to change notification settings - Fork 12
/
bstring.h
227 lines (199 loc) · 8.87 KB
/
bstring.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
#pragma once
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using pcstr = const char *;
using pstr = char *;
template <size_t _size>
class bstring {
using ref = bstring<_size>&;
using const_ref = const bstring<_size>&;
protected:
char _data[_size];
public:
enum {
capacity = _size,
};
public:
explicit inline bstring(int n) {
::snprintf(_data, _size, "%d", n);
}
inline pcstr c_str() const {
return _data;
}
inline char* data() {
return _data;
}
inline bstring() {
_data[0] = 0;
}
inline bstring(const_ref other) {
::strncpy(_data, other._data, _size);
}
inline bstring(pcstr s1) { concat(s1); }
inline bstring(pcstr s1, pcstr s2) { concat(s1, s2); }
inline bstring(pcstr s1, pcstr s2, pcstr s3) { concat(s1, s2, s3); }
inline bstring(pcstr s1, pcstr s2, pcstr s3, pcstr s4) { concat(s1, s2, s3, s4); }
inline bstring(pcstr s1, pcstr s2, pcstr s3, pcstr s4, pcstr s5) { concat(s1, s2, s3, s4, s5); }
inline bstring(pcstr s1, pcstr s2, pcstr s3, pcstr s4, pcstr s5, pcstr s6) { concat(s1, s2, s3, s4, s5, s6); }
inline bstring(pcstr s1, pcstr s2, pcstr s3, pcstr s4, pcstr s5, pcstr s6, pcstr s7) { concat(s1, s2, s3, s4, s5, s6, s7); }
inline ref concat(pcstr s1) { snprintf(_data, _size, "%s", s1); return *this; }
inline ref concat(pcstr s1, pcstr s2) { snprintf(_data, _size, "%s%s", s1, s2); return *this; }
inline ref concat(pcstr s1, pcstr s2, pcstr s3) { snprintf(_data, _size, "%s%s%s", s1, s2, s3); return *this; }
inline ref concat(pcstr s1, pcstr s2, pcstr s3, pcstr s4) { snprintf(_data, _size, "%s%s%s%s", s1, s2, s3, s4); return *this; }
inline ref concat(pcstr s1, pcstr s2, pcstr s3, pcstr s4, pcstr s5) { snprintf(_data, _size, "%s%s%s%s%s", s1, s2, s3, s4, s5); return *this; }
inline ref concat(pcstr s1, pcstr s2, pcstr s3, pcstr s4, pcstr s5, pcstr s6) { snprintf(_data, _size, "%s%s%s%s%s%s", s1, s2, s3, s4, s5, s6); return *this; }
inline ref concat(pcstr s1, pcstr s2, pcstr s3, pcstr s4, pcstr s5, pcstr s6, pcstr s7) { snprintf(_data, _size, "%s%s%s%s%s%s%s", s1, s2, s3, s4, s5, s6, s7); return *this; }
inline ref cat(pcstr s) { snprintf(_data, _size, "%s%s", _data, s); return *this; }
inline ref cat(pcstr s1, pcstr s2) { snprintf(_data, _size, "%s%s%s", _data, s1, s2); return *this; }
inline ref cat(pcstr s1,pcstr s2, pcstr s3) { snprintf(_data, _size, "%s%s%s%s", _data, s1, s2, s3); return *this; }
inline ref cat(pcstr s1,pcstr s2, pcstr s3, pcstr s4) { snprintf(_data, _size, "%s%s%s%s%s", _data, s1, s2, s3, s4); return *this; }
inline ref cat(pcstr*s1,pcstr s2, pcstr s3, pcstr s4, pcstr s5) { snprintf(_data, _size, "%s%s%s%s%s%s", _data, s1, s2, s3, s4, s5); return *this; }
inline ref ncat(pcstr s, size_t cnt) { ::strncat(_data, s, cnt); return *this; }
inline bool operator!() const { return empty(); }
template <typename... Args>
inline ref append(pcstr fmt, Args&&... args) {
size_t size = this->len();
char* dest = _data + size;
size_t remain = _size - size;
if (remain > 0) {
snprintf(dest, remain, fmt, std::forward<Args>(args)...);
}
return *this;
}
inline ref append(pcstr str) {
size_t size = this->len();
char* dest = _data + size;
size_t remain = _size - size;
if (remain > 0) {
snprintf(dest, remain, "%s", str);
}
return *this;
}
inline ref append(char s) {
size_t size = this->len();
char* dest = _data + size;
size_t remain = _size - size;
if (remain > 0) {
*dest = s;
*(dest + 1) = '\0';
}
return *this;
}
inline ref itoa(int n) { ::snprintf(_data, _size, "%d", n); return *this; }
inline int atoi() { return ::atoi(_data); }
inline float atof() { return ::atof(_data); }
inline int64_t atoi64() { return ::strtoll(_data); }
template <typename... Args>
inline ref printf(pcstr fmt, Args&&... args) {
snprintf(_data, _size - 1, fmt, std::forward<Args>(args)...);
_data[_size - 1] = 0;
return *this;
}
inline ref tolower() {
char* str = _data;
while (*str) {
*str = std::tolower(*str);
++str;
}
return *this;
}
inline ref toupper() {
char* str = _data;
while (*str) {
*str = std::toupper(*str);
++str;
}
return *this;
}
inline ref trim() {
char* end = std::remove_if(_data, _data + len(), ::isspace);
*end = '\0';
return *this;
}
inline bool starts_with(pcstr s) const {
return !empty() && (strncmp(_data, s, strlen(s)) == 0);
}
inline bool ends_with(pcstr s) const {
int slen = (s && *s) ? strlen(s) : 0;
if (!slen) {
return false;
}
int mylen = len();
if (empty() || (mylen <= slen)) {
return false;
}
pcstr ptr = strstr(_data, s);
return (ptr && (ptr == _data[mylen - slen]));
}
inline char back() const { return empty() ? 0 : (_data[len() - 1]); }
inline ref replace(const char x, const char y) {
std::replace_if(_data, _data + len(), [x](char c) { return c == x; }, y);
return *this;
}
inline ref replace_str(pcstr subst, pcstr repl) {
size_t _len = len();
const size_t subst_len = ::strlen(subst);
const size_t repl_len = ::strlen(repl);
char* found_pos = std::search(_data, _data + len(), subst, subst + subst_len);
while (found_pos != _data + _len) {
int sizeDiff = repl_len - subst_len;
::memmove(found_pos + repl_len, found_pos + subst_len, _data + _len - (found_pos + subst_len) + 1);
::memcpy(found_pos, repl, repl_len);
_len = len();
found_pos = std::search(found_pos + repl_len, _data + _len, subst, subst + subst_len);
}
return *this;
}
inline size_t len() const { return ::strlen(_data); }
inline void resize(size_t s) { assert(s < _size); _data[s] = '\0'; }
inline bool empty() const { return !_data[0]; }
inline void clear() { _data[0] = 0; }
inline bool equals(const_ref other) const { return ::strncmp(_data, other._data, _size) == 0; }
inline bool equals(pcstr s) const { assert(s); return ::strncmp(_data, s, _size) == 0; }
inline void operator=(const_ref other) { ::strncpy(_data, other._data, _size); }
inline void operator=(pcstr s) { ::snprintf(_data, _size, "%s", s ? s : "null"); }
inline void operator=(const uint8_t* s) { ::snprintf(_data, _size, "%s", s ? (pcstr)s : "null"); }
inline bool operator==(const_ref other) const { return ::strncmp(_data, other._data, _size) == 0; }
inline operator const uint8_t *() const { return (const uint8_t *)_data; }
inline operator uint8_t *() { return (uint8_t *)_data; }
inline bool operator==(pcstr s) const { assert(s); return ::strncmp(_data, s, _size) == 0; }
inline bool operator!=(const_ref other) const { return !equals(other); }
inline bool operator!=(pcstr s) const { assert(s); return ::strncmp(_data, s, _size) != 0; }
inline char operator[](int i) const { return _data[i]; }
inline char &operator[](int i) { return _data[i]; }
inline operator char*() { return _data; }
inline operator const char*() const { return _data; }
inline pcstr strstr(const_ref sub_str) const { return ::strstr(_data, sub_str._data); }
inline pcstr strstr(const_ref sub_str) { return ::strstr(_data, sub_str._data); }
inline int cmp(const_ref other) const { return strcmp(_data, other._data); }
inline int icmp(const_ref other) const { return stricmp(_data, other._data); }
inline int ncmp(const_ref other, unsigned int count) const { return ::strncmp(_data, other._data, count); }
inline pcstr strstr(pcstr sub_str) const { return ::strstr(_data, sub_str); }
inline pcstr strstr(pcstr sub_str) { return ::strstr(_data, sub_str); }
inline pcstr strchr(char v) { return ::strchr(_data, v); }
inline int cmp(pcstr str) const { return strcmp(_data, str); }
inline int icmp(pcstr str) const { return stricmp(_data, str); }
inline int ncmp(pcstr str, unsigned int count) const { return ::strncmp(_data, str, count); }
inline size_t hash() {
const size_t p = 31;
const size_t m = 1e9 + 9;
size_t hash_value = 0;
size_t p_pow = 1;
for (char c : _data) {
hash_value = (hash_value + (c - 'a' + 1) * p_pow) % m;
p_pow = (p_pow * p) % m;
}
return hash_value;
}
};
using bstring32 = bstring<32>;
using bstring64 = bstring<64>;
using bstring128 = bstring<128>;
using bstring256 = bstring<256>;
using bstring512 = bstring<512>;
using bstring1024 = bstring<1024>;