hicc_std/std_string.rs
1use crate::*;
2use std::cmp::min;
3use std::cmp::{Ordering, PartialEq, PartialOrd};
4use std::convert::From;
5use std::ffi::CStr;
6use std::slice;
7
8hicc::cpp! {
9 #include <string>
10}
11
12hicc::import_class! {
13 #[cpp(class = "template<class CharT, class Traits, class Allocator> std::basic_string<CharT, Traits, Allocator>")]
14 pub class basic_string<CharT> {
15 pub const npos: usize = usize::MAX;
16 /// ```
17 /// use std::ffi::CStr;
18 /// use hicc_std::string;
19 /// let s = string::from(c"abc");
20 /// let cstr = unsafe { CStr::from_ptr(s.c_str()) };
21 /// assert_eq!(cstr, c"abc");
22 /// ```
23 #[cpp(method = "const CharT* c_str() const")]
24 pub fn c_str(&self) -> *const CharT;
25
26 /// ```
27 /// use hicc_std::string;
28 /// let s = string::new();
29 /// assert!(s.is_empty());
30 /// ```
31 #[cpp(method = "bool empty() const")]
32 pub fn is_empty(&self) -> bool;
33
34 /// ```
35 /// use hicc_std::string;
36 /// let s = string::new();
37 /// assert_eq!(s.size(), 0);
38 /// ```
39 #[cpp(method = "size_t size() const")]
40 pub fn size(&self) -> usize;
41
42 /// ```
43 /// use hicc_std::string;
44 /// let s = string::new();
45 /// println!("s.max_size = {}", s.max_size());
46 /// ```
47 #[cpp(method = "size_t max_size() const")]
48 pub fn max_size(&self) -> usize;
49
50 /// ```
51 /// use hicc_std::string;
52 /// let s = string::new();
53 /// println!("s.capacity = {}", s.capacity());
54 /// ```
55 #[cpp(method = "size_t capacity() const")]
56 pub fn capacity(&self) -> usize;
57
58 /// ```
59 /// use hicc_std::string;
60 /// let mut s = string::from(c"a");
61 /// s.resize(3, b'c' as i8);
62 /// assert_eq!(s.as_cstr(), c"acc");
63 /// ```
64 #[cpp(method = "void resize(size_t, CharT) ")]
65 pub fn resize(&mut self, n: usize, c: CharT);
66
67 /// ```
68 /// use hicc_std::string;
69 /// let mut s = string::from(c"abc");
70 /// s.reserve(100);
71 /// println!("s.capacity = {}", s.capacity());
72 /// ```
73 #[cpp(method = "void reserve(size_t)")]
74 pub fn reserve(&mut self, n: usize);
75
76 /// ```
77 /// use hicc_std::string;
78 /// let mut s = string::from(c"abc");
79 /// s.clear();
80 /// assert!(s.is_empty());
81 /// ```
82 #[cpp(method = "void clear()")]
83 pub fn clear(&mut self);
84
85 /// ```
86 /// use hicc_std::string;
87 /// let mut s = string::from(c"abc");
88 /// s.reserve(100);
89 /// println!("before shrink_to_fit: capacity = {}", s.capacity());
90 /// s.assign(10, b'c' as i8);
91 /// s.shrink_to_fit();
92 /// println!("after shrink_to_fit: capacity = {}", s.capacity());
93 /// ```
94 #[cpp(method = "void shrink_to_fit()")]
95 pub fn shrink_to_fit(&mut self);
96
97 /// 如果pos超出范围,会返回空字符串.
98 /// ```
99 /// use hicc_std::string;
100 /// let mut s = string::from(c"abc");
101 /// let substr = s.substr(1, 2);
102 /// assert_eq!(substr.as_cstr(), c"bc");
103 /// ```
104 pub fn substr(&self, mut pos: usize, len: usize) -> Self {
105 if pos > self.size() {
106 pos = self.size();
107 }
108 self._substr(pos, len)
109 }
110 #[cpp(method = "Self substr(size_t, size_t) const")]
111 fn _substr(&self, pos: usize, len: usize) -> Self;
112
113 /// ```
114 /// use hicc_std::string;
115 /// let s1 = string::from(c"abc");
116 /// let s2 = string::from(c"abd");
117 /// assert!(s1 < s2);
118 /// assert!(s1 != s2);
119 /// ```
120 #[cpp(method = "int compare(const Self&) const")]
121 pub fn compare(&self, other: &Self) -> i32;
122
123 /// ```
124 /// use hicc_std::string;
125 /// let s1 = string::from(c"abcdef");
126 /// let s2 = string::from(c"bcd");
127 /// assert_eq!(s1.find_str(&s2, 0), 1);
128 /// ```
129 #[cpp(method = "size_t find(const Self&, size_t) const")]
130 pub fn find_str(&self, target: &Self, pos: usize) -> usize;
131
132 /// ```
133 /// use hicc_std::string;
134 /// let s = string::from(c"abcdef");
135 /// assert_eq!(s.find(b'c' as i8, 1), 2);
136 /// ```
137 #[cpp(method = "size_t find(CharT, size_t) const")]
138 pub fn find(&self, c: CharT, pos: usize) -> usize;
139
140 /// ```
141 /// use hicc_std::string;
142 /// let s1 = string::from(c"abcdef");
143 /// let s2 = string::from(c"bcd");
144 /// assert_eq!(s1.rfind_str(&s2, string::npos), 1);
145 /// ```
146 #[cpp(method = "size_t rfind(const Self&, size_t) const")]
147 pub fn rfind_str(&self, target: &Self, pos: usize) -> usize;
148
149 /// ```
150 /// use hicc_std::string;
151 /// let s = string::from(c"abcdef");
152 /// assert_eq!(s.rfind(b'c' as i8, string::npos), 2);
153 /// ```
154 #[cpp(method = "size_t rfind(CharT, size_t) const")]
155 pub fn rfind(&self, c: CharT, pos: usize) -> usize;
156
157 /// ```
158 /// use hicc_std::string;
159 /// let s1 = string::from(c"abcdef");
160 /// let s2 = string::from(c"dfb");
161 /// assert_eq!(s1.find_first_of(&s2, 0), 1);
162 /// ```
163 #[cpp(method = "size_t find_first_of(const Self&, size_t) const")]
164 pub fn find_first_of(&self, target: &Self, pos: usize) -> usize;
165
166 /// ```
167 /// use hicc_std::string;
168 /// let s = string::from(c"abcabc");
169 /// assert_eq!(s.find_first(b'c' as i8, 0), 2);
170 /// ```
171 #[cpp(method = "size_t find_first_of(CharT, size_t) const")]
172 pub fn find_first(&self, c: CharT, pos: usize) -> usize;
173
174 /// ```
175 /// use hicc_std::string;
176 /// let s1 = string::from(c"abcdef");
177 /// let s2 = string::from(c"dfb");
178 /// assert_eq!(s1.find_last_of(&s2, string::npos), 5);
179 /// ```
180 #[cpp(method = "size_t find_last_of(const Self&, size_t) const")]
181 pub fn find_last_of(&self, target: &Self, pos: usize) -> usize;
182
183 /// ```
184 /// use hicc_std::string;
185 /// let s = string::from(c"abcabc");
186 /// assert_eq!(s.find_last(b'c' as i8, string::npos), 5);
187 /// ```
188 #[cpp(method = "size_t find_last_of(CharT, size_t) const")]
189 pub fn find_last(&self, c: CharT, pos: usize) -> usize;
190
191 /// ```
192 /// use hicc_std::string;
193 /// let s1 = string::from(c"abcdef");
194 /// let s2 = string::from(c"abc");
195 /// assert_eq!(s1.find_first_not_of(&s2, 0), 3);
196 /// ```
197 #[cpp(method = "size_t find_first_not_of(const Self&, size_t) const")]
198 pub fn find_first_not_of(&self, target: &Self, pos: usize) -> usize;
199
200 /// ```
201 /// use hicc_std::string;
202 /// let s = string::from(c"abcabc");
203 /// assert_eq!(s.find_first_not(b'a' as i8, 0), 1);
204 /// ```
205 #[cpp(method = "size_t find_first_not_of(CharT, size_t) const")]
206 pub fn find_first_not(&self, c: CharT, pos: usize) -> usize;
207
208 /// ```
209 /// use hicc_std::string;
210 /// let s1 = string::from(c"abcdef");
211 /// let s2 = string::from(c"def");
212 /// assert_eq!(s1.find_last_not_of(&s2, string::npos), 2);
213 /// ```
214 #[cpp(method = "size_t find_last_not_of(const Self&, size_t) const")]
215 pub fn find_last_not_of(&self, target: &Self, pos: usize) -> usize;
216
217 /// ```
218 /// use hicc_std::string;
219 /// let s = string::from(c"abcabc");
220 /// assert_eq!(s.find_last_not(b'c' as i8, string::npos), 4);
221 /// ```
222 #[cpp(method = "size_t find_last_not_of(CharT, size_t) const")]
223 pub fn find_last_not(&self, c: CharT, pos: usize) -> usize;
224
225 /// 如果subpos超出范围则不做任何改变.
226 /// ```
227 /// use hicc_std::string;
228 /// let mut s1 = string::from(c"abc");
229 /// let s2 = string::from(c"def");
230 /// s1.append_str(&s2, 0, 2);
231 /// assert_eq!(s1.as_cstr(), c"abcde");
232 /// ```
233 pub fn append_str(&mut self, s: &Self, subpos: usize, sublen: usize) {
234 if subpos < s.size() {
235 self._append_str(s, subpos, sublen);
236 }
237 }
238 #[cpp(method = "Self& append(const Self&, size_t, size_t)")]
239 fn _append_str(&mut self, s: &Self, subpos: usize, sublen: usize);
240
241 /// ```
242 /// use hicc_std::string;
243 /// let mut s = string::from(c"abc");
244 /// s.append(1, b'd' as i8);
245 /// assert_eq!(s.as_cstr(), c"abcd");
246 /// ```
247 #[cpp(method = "Self& append(size_t, CharT)")]
248 pub fn append(&mut self, n: usize, c: CharT);
249
250 /// 如果subpos超出范围不做任何改变, 如果pos超出范围则追加到最后.
251 /// ```
252 /// use hicc_std::string;
253 /// let mut s1 = string::from(c"abc");
254 /// let mut s2 = string::from(c"def");
255 /// s1.insert_str(0, &s2, 0, string::npos);
256 /// assert_eq!(s1.as_cstr(), c"defabc");
257 /// s1.insert_str(100, &s2, 0, string::npos);
258 /// assert_eq!(s1.as_cstr(), c"defabcdef");
259 /// ```
260 pub fn insert_str(&mut self, pos: usize, s: &Self, subpos: usize, sublen: usize) {
261 if subpos < s.size() {
262 self._insert_str(min(pos, self.size()), s, subpos, sublen);
263 }
264 }
265 #[cpp(method = "Self& insert(size_t, const Self&, size_t, size_t)")]
266 fn _insert_str(&mut self, pos: usize, s: &Self, subpos: usize, sublen: usize);
267
268 /// 如果pos超出范围则追加到最后.
269 /// ```
270 /// use hicc_std::string;
271 /// let mut s = string::from(c"abc");
272 /// s.insert(0, 3, b'd' as i8);
273 /// assert_eq!(s.as_cstr(), c"dddabc");
274 /// s.insert(110, 3, b'd' as i8);
275 /// assert_eq!(s.as_cstr(), c"dddabcddd");
276 /// ```
277 pub fn insert(&mut self, pos: usize, n: usize, c: CharT::InputType) {
278 self._insert(min(pos, self.size()), n, c);
279 }
280 #[cpp(method = "Self& insert(size_t, size_t, CharT)")]
281 fn _insert(&mut self, pos: usize, n: usize, c: CharT);
282
283 /// 如果pos或者subpos超出范围则不做任何改变.
284 /// ```
285 /// use hicc_std::string;
286 /// let mut s1 = string::from(c"abc");
287 /// let mut s2 = string::from(c"de");
288 /// s1.replace_str(0, string::npos, &s2, 0, string::npos);
289 /// assert_eq!(s1.as_cstr(), c"de");
290 /// ```
291 pub fn replace_str(&mut self, pos: usize, len: usize, s: &Self, subpos: usize, sublen: usize) {
292 if pos < self.size() && subpos < s.size() {
293 self._replace_str(pos, len, s, subpos, sublen);
294 }
295 }
296 #[cpp(method = "Self& replace(size_t, size_t, const Self&, size_t, size_t)")]
297 fn _replace_str(&mut self, pos: usize, len: usize, s: &Self, subpos: usize, sublen: usize);
298
299 /// 如果pos超出范围则不做任何改变.
300 /// ```
301 /// use hicc_std::string;
302 /// let mut s = string::from(c"abc");
303 /// s.replace(0, string::npos, 1, b'd' as i8);
304 /// assert_eq!(s.as_cstr(), c"d");
305 /// ```
306 pub fn replace(&mut self, pos: usize, len: usize, n: usize, c: CharT::InputType) {
307 if pos < self.size() {
308 self._replace(pos, len, n, c);
309 }
310 }
311 #[cpp(method = "Self& replace(size_t, size_t, size_t, CharT)")]
312 fn _replace(&mut self, pos: usize, len: usize, n: usize, c: CharT);
313
314 /// 如果subpos超出范围则不做任何改变.
315 /// ```
316 /// use hicc_std::string;
317 /// let mut s1 = string::from(c"abc");
318 /// let mut s2 = string::from(c"de");
319 /// s1.assign_str(&s2, 0, string::npos);
320 /// assert_eq!(s1.as_cstr(), c"de");
321 /// ```
322 pub fn assign_str(&mut self, s: &Self, subpos: usize, sublen: usize) {
323 if subpos < s.size() {
324 self._assign_str(s, subpos, sublen);
325 }
326 }
327 #[cpp(method = "Self& assign(const Self&, size_t, size_t)")]
328 fn _assign_str(&mut self, s: &Self, subpos: usize, sublen: usize);
329
330 /// ```
331 /// use hicc_std::string;
332 /// let mut s = string::from(c"abc");
333 /// s.assign(1, b'd' as i8);
334 /// assert_eq!(s.as_cstr(), c"d");
335 /// ```
336 #[cpp(method = "Self& assign(size_t, CharT)")]
337 pub fn assign(&mut self, n: usize, c: CharT);
338
339 /// 如果pos超出范围则不做任何改变.
340 /// ```
341 /// use hicc_std::string;
342 /// let mut s = string::from(c"abc");
343 /// s.erase(1, 1);
344 /// assert_eq!(s.as_cstr(), c"ac");
345 /// ```
346 pub fn erase(&mut self, pos: usize, len: usize) {
347 if pos < self.size() {
348 self._erase(pos, len);
349 }
350 }
351 #[cpp(method = "Self& erase(size_t, size_t)")]
352 fn _erase(&mut self, pos: usize, len: usize);
353
354
355 /// ```
356 /// use hicc_std::string;
357 /// let mut s = string::from(c"abc");
358 /// s.push_back(b'd' as i8);
359 /// assert_eq!(s.as_cstr(), c"abcd");
360 /// ```
361 #[cpp(method = "void push_back(CharT)")]
362 pub fn push_back(&mut self, c: CharT);
363
364 /// 如果为空则不做任何改变.
365 /// ```
366 /// use hicc_std::string;
367 /// let mut s = string::from(c"abc");
368 /// s.pop_back();
369 /// assert_eq!(s.as_cstr(), c"ab");
370 /// ```
371 pub fn pop_back(&mut self) {
372 if !self.is_empty() {
373 self._pop_back();
374 }
375 }
376 #[cpp(method = "void pop_back()")]
377 fn _pop_back(&mut self);
378
379 /// ```
380 /// use hicc_std::string;
381 /// let mut s1 = string::from(c"abc");
382 /// let mut s2 = string::from(c"de");
383 /// s1.swap(&mut s2);
384 /// assert_eq!(s1.as_cstr(), c"de");
385 /// assert_eq!(s2.as_cstr(), c"abc");
386 /// ```
387 #[cpp(method = "void swap(Self&)")]
388 pub fn swap(&mut self, other: &mut Self);
389
390 /// ```
391 /// use hicc_std::string;
392 /// let s = string::from(c"abc");
393 /// assert_eq!(s.get(0), Some(&(b'a' as i8)));
394 /// assert_eq!(s.get(3), None);
395 /// ```
396 pub fn get(&self, pos: usize) -> Option<CharT::OutputRef<'_>> {
397 if pos < self.size() {
398 return Some(self._get(pos));
399 }
400 None
401 }
402 #[cpp(method = "const CharT& at(size_t) const")]
403 fn _get(&self, pos: usize) -> &CharT;
404
405
406 /// ```
407 /// use hicc_std::string;
408 /// let mut s = string::from(c"abc");
409 /// assert!(s.get_mut(0).is_some());
410 /// assert_eq!(*s.get_mut(0).unwrap(), b'a' as i8);
411 /// assert_eq!(s.get(3), None);
412 /// ```
413 pub fn get_mut(&mut self, pos: usize) -> Option<CharT::OutputRefMut<'_>> {
414 if pos < self.size() {
415 return Some(self._get_mut(pos));
416 }
417 None
418 }
419 #[cpp(method = "CharT& at(size_t)")]
420 fn _get_mut(&mut self, pos: usize) -> &mut CharT;
421 }
422
423 /// 对应`std::string`
424 #[allow(non_camel_case_types)]
425 pub type string = basic_string<hicc::Pod<i8>>;
426 /// 对应`std::u16string`
427 #[allow(non_camel_case_types)]
428 pub type u16string = basic_string<hicc::Pod<i16>>;
429 /// 对应`std::u32string`
430 #[allow(non_camel_case_types)]
431 pub type u32string = basic_string<hicc::Pod<i32>>;
432}
433
434unsafe impl<CharT: hicc::AbiType + Sync> Send for basic_string<CharT> {}
435unsafe impl<CharT: hicc::AbiType + Sync> Sync for basic_string<CharT> {}
436
437impl<T: Sized + 'static> basic_string<hicc::Pod<T>> {
438 /// ```
439 /// use hicc_std::string;
440 /// let mut s = string::with_cstr(c"bcd");
441 /// assert_eq!(s.as_slice(), &[b'b' as i8, b'c' as i8, b'd' as i8]);
442 /// ```
443 pub fn as_slice(&self) -> &[T] {
444 let cstr = self.c_str();
445 let size = self.size();
446 unsafe { slice::from_raw_parts(cstr, size) }
447 }
448
449 /// ```
450 /// use hicc_std::string;
451 /// let mut s = string::with_cstr(c"abc");
452 /// s.as_slice_mut().iter_mut().for_each(|mut c| { *c += 1; });
453 /// assert_eq!(s.as_slice(), &[b'b' as i8, b'c' as i8, b'd' as i8]);
454 /// ```
455 pub fn as_slice_mut(&mut self) -> &mut [T] {
456 let cstr = self.c_str();
457 let size = self.size();
458 unsafe { slice::from_raw_parts_mut(cstr.cast_mut(), size) }
459 }
460}
461
462impl<T: hicc::AbiType> PartialEq for basic_string<T> {
463 fn eq(&self, other: &Self) -> bool {
464 self.compare(other) == 0
465 }
466}
467
468impl<T: hicc::AbiType> PartialOrd for basic_string<T> {
469 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
470 match self.compare(other) {
471 0 => Some(Ordering::Equal),
472 1.. => Some(Ordering::Greater),
473 _ => Some(Ordering::Less),
474 }
475 }
476}
477
478impl string {
479 pub fn new() -> Self {
480 string_new()
481 }
482
483 pub fn with_cstr(s: &CStr) -> Self {
484 unsafe { string_with_cstr(s.as_ptr()) }
485 }
486
487 pub fn with_buf(b: &[u8]) -> Self {
488 unsafe { string_with_buf(b.as_ptr(), b.len()) }
489 }
490
491 pub fn as_cstr(&self) -> &CStr {
492 unsafe { CStr::from_ptr(self.c_str()) }
493 }
494}
495
496impl From<&CStr> for string {
497 fn from(s: &CStr) -> Self {
498 unsafe { string_with_cstr(s.as_ptr()) }
499 }
500}
501
502impl Default for string {
503 fn default() -> Self {
504 Self::new()
505 }
506}
507
508impl u16string {
509 pub fn new() -> Self {
510 u16string_new()
511 }
512
513 pub fn with_buf(b: &[u16]) -> Self {
514 unsafe { u16string_with_buf(b.as_ptr(), b.len()) }
515 }
516}
517
518impl Default for u16string {
519 fn default() -> Self {
520 Self::new()
521 }
522}
523
524impl u32string {
525 pub fn new() -> Self {
526 u32string_new()
527 }
528
529 pub fn with_buf(b: &[u32]) -> Self {
530 unsafe { u32string_with_buf(b.as_ptr(), b.len()) }
531 }
532}
533
534impl Default for u32string {
535 fn default() -> Self {
536 Self::new()
537 }
538}