Zen C++ Libraries
Zero-dependency re-usable components for C++
Loading...
Searching...
No Matches
bytestring.hpp
1#ifndef ZEN_BYTESTRING_HPP
2#define ZEN_BYTESTRING_HPP
3
4#include <cstdlib>
5#include <string.h>
6#include <stdlib.h>
7
8#include <cstdint>
9#include <utility>
10
11#include "zen/config.hpp"
12#include "zen/algorithm.hpp"
13#include "zen/zip_iterator.hpp"
15
16ZEN_NAMESPACE_START
17
18inline bool string_equal_helper(const char* a, const char* b, std::size_t a_sz) {
19 for (std::size_t i = 0;; ++i) {
20 if (i == a_sz) {
21 return *b == '\0';
22 }
23 auto ch_a = *a;
24 auto ch_b = *b;
25 if (ch_b == '\0' || ch_a != ch_b) {
26 return false;
27 }
28 ++a;
29 ++b;
30 }
31 return true;
32}
33
34template<std::size_t N = 1024>
36
37class bytestring_view {
38public:
39
40 using reference = const char&;
41 using value_type = const char;
42 using iterator = const char*;
43 using const_iterator = const char*;
44
45 const char* ptr;
46 const std::size_t sz;
47
48 template<typename BS>
49 bytestring_view(const BS& data) ZEN_NOEXCEPT:
50 ptr(data.ptr), sz(data.sz) {}
51
52 bool operator==(const char* other) const ZEN_NOEXCEPT {
53 return string_equal_helper(ptr, other, sz);
54 }
55
56 template<std::size_t N>
57 bool operator==(const basic_bytestring<N>& other) const ZEN_NOEXCEPT {
58 if (sz != other.sz) {
59 return false;
60 }
61 for (auto [c1, c2]: zip(*this, other)) {
62 if (c1 != c2) {
63 return false;
64 }
65 }
66 return true;
67 }
68
69 // FIXME Implement this properly
70 template<typename T>
71 bool operator!=(const T& other) const ZEN_NOEXCEPT {
72 return !(*this == other);
73 }
74
75 const char& operator[](std::size_t index) const ZEN_NOEXCEPT {
76 return ptr[index];
77 }
78
79 iterator begin() ZEN_NOEXCEPT {
80 return ptr;
81 }
82
83 iterator end() ZEN_NOEXCEPT {
84 return ptr + sz;
85 }
86
87 const_iterator begin() const ZEN_NOEXCEPT {
88 return ptr;
89 }
90
91 const_iterator end() const ZEN_NOEXCEPT {
92 return ptr + sz;
93 }
94
95 const_iterator cbegin() const ZEN_NOEXCEPT {
96 return ptr;
97 }
98
99 const_iterator cend() const ZEN_NOEXCEPT {
100 return ptr + sz;
101 }
102
103};
104
105inline std::ostream& operator<<(std::ostream& out, const bytestring_view& bs) {
106 for (auto ch: bs) {
107 out << ch;
108 }
109 return out;
110}
111
112template<std::size_t N>
113class basic_bytestring {
114
115 friend class bytestring_view;
116
117 char* ptr;
118 std::size_t max_sz;
119 std::size_t sz;
120
121public:
122
123 using pointer = char*;
124 using reference = char&;
125 using value_type = char;
126 using iterator = char*;
127 using const_iterator = const char*;
128 using view = bytestring_view;
129
130 basic_bytestring(std::size_t max_sz) ZEN_NOEXCEPT:
131 sz(0) {
132 ptr = static_cast<char*>(malloc(max_sz));
133 if (ptr == nullptr) {
134 ZEN_PANIC("insufficient memory");
135 }
136 max_sz = max_sz;
137 }
138
139 basic_bytestring() ZEN_NOEXCEPT:
140 basic_bytestring(N) {}
141
142 basic_bytestring(const char* const other, std::size_t other_sz) ZEN_NOEXCEPT:
143 basic_bytestring(other_sz) {
144 sz = other_sz;
145 memcpy(ptr, other, sz);
146 }
147
148 basic_bytestring(const char* const other) ZEN_NOEXCEPT:
149 basic_bytestring(other, strlen(other)) {}
150
151 basic_bytestring(const std::string& str) ZEN_NOEXCEPT:
152 basic_bytestring(str.c_str(), str.size()) {}
153
154 basic_bytestring(const basic_bytestring& other) ZEN_NOEXCEPT:
155 basic_bytestring(other.ptr, other.sz) {}
156
157 basic_bytestring(basic_bytestring&& other) ZEN_NOEXCEPT:
158 ptr(std::move(other.ptr)),
159 max_sz(std::move(other.max_sz)),
160 sz(std::move(other.sz)) {
161 other.ptr = nullptr;
162 }
163
164 iterator begin() ZEN_NOEXCEPT {
165 return ptr;
166 }
167
168 iterator end() ZEN_NOEXCEPT {
169 return ptr + sz;
170 }
171
172 const_iterator begin() const ZEN_NOEXCEPT {
173 return ptr;
174 }
175
176 const_iterator end() const ZEN_NOEXCEPT {
177 return ptr + sz;
178 }
179
180 const_iterator cbegin() const ZEN_NOEXCEPT {
181 return ptr;
182 }
183
184 const_iterator cend() const ZEN_NOEXCEPT {
185 return ptr + sz;
186 }
187
188 bool operator==(const char* other) const ZEN_NOEXCEPT {
189 return string_equal_helper(ptr, other, sz);
190 }
191
192 template<std::size_t N2>
193 bool operator==(const basic_bytestring<N2>& other) const ZEN_NOEXCEPT {
194 if (sz != other.sz) {
195 return false;
196 }
197 for (std::size_t i = 0; i < sz; ++i) {
198 if (ptr[i] != other.ptr[i]) {
199 return false;
200 }
201 }
202 return true;
203 }
204
205 char& operator[](std::size_t index) ZEN_NOEXCEPT {
206 return ptr[index];
207 }
208
209 const char& operator[](std::size_t index) const ZEN_NOEXCEPT {
210 return ptr[index];
211 }
212
213 bytestring_view as_view() const ZEN_NOEXCEPT {
214 return bytestring_view(*this);
215 }
216
217 std::size_t capacity() const ZEN_NOEXCEPT {
218 return max_sz;
219 }
220
221 std::size_t size() const ZEN_NOEXCEPT {
222 return sz;
223 }
224
225 const char* c_str() const ZEN_NOEXCEPT {
226 return ptr;
227 }
228
229 char* data() const ZEN_NOEXCEPT {
230 return ptr;
231 }
232
233 std::string to_std_string() const ZEN_NOEXCEPT {
234 return std::string(ptr, sz);
235 }
236
237 void resize(std::size_t new_sz) ZEN_NOEXCEPT{
238 ZEN_ASSERT(new_sz <= sz);
239 sz = new_sz;
240 ptr[new_sz] = '\0';
241 }
242
243 ~basic_bytestring() ZEN_NOEXCEPT {
244 if (ptr != nullptr) {
245 free(ptr);
246 }
247 }
248
249};
250
251template<std::size_t N>
252std::ostream& operator<<(std::ostream& out, const basic_bytestring<N>& bs) ZEN_NOEXCEPT {
253 out << bs.c_str();
254 return out;
255}
256
257using bytestring = basic_bytestring<>;
258
259ZEN_NAMESPACE_END
260
261namespace std {
262
263 template<std::size_t N>
264 struct hash<zen::basic_bytestring<N>> {
265
266 std::size_t operator()(const zen::basic_bytestring<N> str) const noexcept {
267 std::size_t h = 17;
268 for (auto ch: str) {
269 h = h * 19 + ch;
270 }
271 return h;
272 }
273
274 };
275
276}
277
278
279#endif // #infdef ZEN_BYTESTRING_HPP
Definition bytestring.hpp:113
Definition bytestring.hpp:37
Definition concepts.hpp:45
Support for creating ranges over iterators.
auto zip(Ts &&...args)
Definition iterator_range.hpp:136
Definitions for an iterator that merges several other iteerators.