1#![allow(unused_variables)]
2#![allow(non_snake_case)]
3#![allow(non_camel_case_types)]
4#![allow(unused_parens)]
5#![allow(unused_assignments)]
6#![allow(unused_mut)]
7#![allow(unused_imports)]
8#![allow(dead_code)]
9use core::cmp::{min, Ordering, PartialOrd};
12#[cfg(not(feature = "no-alloc"))]
13extern crate alloc;
14use core::ops::Add;
15
16#[derive(Copy, Clone)]
59pub struct cstr<const N: usize = 32> {
60 chrs: [u8; N],
61 front: u16,
62 len: u16,
63} impl<const N: usize> cstr<N> {
66 pub fn make(src: &str) -> cstr<N> {
69 if N < 1 || N > 65535 {
70 panic!("cstr strings are limited to a capacity between 1 and 65535");
71 }
72 let mut m = cstr::<N>::new();
73 let length = core::cmp::min(N, src.len());
74 m.chrs[..length].copy_from_slice(&src.as_bytes()[..length]);
75 m.len = length as u16;
76 m
77 } pub fn from_ascii(src: &str) -> cstr<N> {
81 if N < 1 || N > 65535 {
82 panic!("cstr strings are limited to a maximum capacity of 65535");
83 }
84 if !src.is_ascii() {
85 panic!("cstr string is not ascii");
86 }
87 let mut m = cstr::<N>::new();
88 let length = core::cmp::min(N, src.len());
89 m.chrs[..length].copy_from_slice(&src.as_bytes()[..length]);
90 m.len = length as u16;
91 m
92 } pub fn try_make(src: &str) -> Result<cstr<N>, &str> {
97 let length = src.len();
98 if length > N || N > 65535 || N < 1 {
99 return Err(src);
100 }
101 let mut m = cstr::new();
102 m.chrs[..].copy_from_slice(&src.as_bytes()[..length]);
103 m.len = length as u16;
104 Ok(m)
105 } pub fn try_make_ascii(src: &str) -> Option<cstr<N>> {
109 let length = src.len();
110 if length > N || N > 65535 || N < 1 || !src.is_ascii() {
111 return None;
112 }
113 let mut m = cstr::new();
114 m.chrs[..].copy_from_slice(&src.as_bytes()[..length]);
115 m.len = length as u16;
116 Some(m)
117 } pub fn make_remainder(src: &str) -> (cstr<N>, &str) {
123 if N > 65535 || N < 1 {
124 panic!("cstr strings are limited to a capacity between 1 and 65535");
125 }
126 let mut m = cstr::new();
127 let length = core::cmp::min(N, src.len());
128 m.chrs[..].copy_from_slice(&src.as_bytes()[..length]);
129 m.len = length as u16;
130 (m, &src[length..])
131 } pub fn from_pair(left: &str, right: &str) -> Option<cstr<N>> {
137 let (llen, rlen) = (left.len(), right.len());
138 if llen + rlen > N || N > 65535 || N < 1 {
139 return None;
140 }
141 let mut m = cstr::new();
142 m.len = (llen + rlen) as u16;
143 m.chrs[..llen].copy_from_slice(&left.as_bytes()[..llen]);
144 m.chrs[llen..].copy_from_slice(&right.as_bytes()[llen..]);
145 Some(m)
146 } pub const fn const_make(src: &str) -> cstr<N> {
153 let mut m = cstr::<N>::new();
154 let mut len = src.len();
155 if len>N {len=N;}
156 let bytes = src.as_bytes();
158 let mut i = 0;
159 while i<len {
160 m.chrs[i] = bytes[i];
161 i += 1;
162 }
163 m.len = len as u16;
164 m
165 }pub const fn const_try_make(s:&str) -> Result<cstr<N>, &str> {
169 if s.len()>N || N<1 || N>65535 {Err(s)}
170 else { Ok(cstr::const_make(s)) }
171 }
172
173 #[inline(always)]
176 pub fn is_contiguous(&self) -> bool {
177 (self.front as usize + self.len as usize) <= N
178 }
179
180 pub fn reset(&mut self) {
185 if self.front == 0 {
186 return;
187 }
188 let mut mhrs = [0; N];
189 for i in 0..self.len as usize {
190 mhrs[i] = self.chrs[self.index(i)];
191 }
192 self.chrs = mhrs;
193 self.front = 0;
194 } pub fn clear(&mut self) {
198 self.len = 0;
199 }
200
201 pub fn zero(&mut self) {
204 self.chrs = [0; N];
205 self.front = 0;
206 self.len = 0;
207 }
208
209 pub fn make_contiguous(&mut self) {
212 if !self.is_contiguous() {
213 self.reset();
214 }
215 }
216
217 pub fn nth(&self, n: usize) -> Option<char> {
222 if n < self.len as usize {
223 Some(self.chrs[self.index(n)] as char)
224 } else {
225 None
226 }
227 }
228
229 #[inline]
232 pub const fn nth_bytechar(&self, n: usize) -> char {
233 self.chrs[self.index(n)] as char
234 }
235
236 pub fn set(&mut self, n: usize, c: char) -> bool {
239 if c.len_utf8() > 1 || n >= self.len as usize {
240 false
241 } else {
242 self.chrs[self.index(n)] = c as u8;
243 true
244 }
245 } pub fn push_str<'t>(&mut self, src: &'t str) -> &'t str {
249 let srclen = src.len();
250 let slen = self.len as usize;
251 let bytes = &src.as_bytes();
252 let length = core::cmp::min(slen + srclen, N);
253 let remain = if N > (slen + srclen) {
254 0
255 } else {
256 (srclen + slen) - N
257 };
258 let mut i = 0;
259 while i < srclen && i + slen < N {
260 self.chrs[self.index(slen + i)] = bytes[i];
261 i += 1;
262 } self.len += i as u16;
264 &src[srclen - remain..]
265 } pub fn push_front<'t>(&mut self, src: &'t str) -> &'t str {
272 let srclen = src.len();
273 let slen = self.len as usize;
274 let bytes = &src.as_bytes();
275 let length = core::cmp::min(slen + srclen, N);
276 let remain = if N >= (slen + srclen) {
277 0
278 } else {
279 (srclen + slen) - N
280 };
281 let mut i = 0;
282 while i < srclen && i + slen < N {
283 self.front = ((self.front as usize + N - 1) % N) as u16;
285 self.chrs[self.front as usize] = bytes[srclen - 1 - i];
286 i += 1;
287 } self.len += i as u16;
289 &src[..remain]
290 } pub fn push_str_front<'t>(&mut self, src: &'t str) -> &'t str {
294 self.push_front(src)
295 }
296
297 pub fn push_char(&mut self, c: char) -> bool {
301 let clen = c.len_utf8();
302 if clen > 1 || self.len as usize + clen > N {
303 return false;
304 }
305 let mut buf = [0u8; 4]; let bstr = c.encode_utf8(&mut buf);
307 self.push_str(bstr);
308 true
309 } pub fn push_char_front(&mut self, c: char) -> bool {
315 let clen = c.len_utf8();
316 if clen > 1 || self.len as usize + clen > N {
317 return false;
318 }
319 let newfront = (self.front as usize + N - 1) % N;
320 self.chrs[newfront] = c as u8;
321 self.front = newfront as u16;
322 self.len += 1;
323 true
324 } pub fn pop_char(&mut self) -> Option<char> {
328 if self.len() == 0 {
329 return None;
330 }
331 let lasti = ((self.front + self.len - 1) as usize) % N;
332 let firstchar = self.chrs[lasti] as char;
333 self.len -= 1;
334 Some(firstchar)
335 } pub fn pop_char_front(&mut self) -> Option<char> {
346 if self.len() == 0 {
347 return None;
348 }
349 let firstchar = self.chrs[self.front as usize] as char;
350 self.front = self.index16(1);
351 self.len -= 1;
352 Some(firstchar)
353 } pub fn truncate_right(&mut self, n: usize) {
357 if (n < self.len as usize) {
358 self.len = n as u16;
359 }
360 }
361
362 #[inline]
366 pub fn truncate(&mut self, n: usize) {
367 self.truncate_right(n);
368 }
369
370 pub fn truncate_left(&mut self, n: usize) {
375 if (n > 0 && n <= self.len as usize) {
376 self.front = self.index16(n as u16);
386 self.len -= n as u16;
387 }
388 } pub fn truncate_front(&mut self, n: usize) {
392 self.truncate_left(n);
393 }
394
395 pub fn find<P>(&self, predicate: P) -> Option<usize>
397 where
398 P: Fn(char) -> bool,
399 {
400 let (a, b) = self.to_strs();
401 if let Some(pos) = a.find(|x: char| predicate(x)) {
402 Some(pos)
403 } else if let Some(pos) = b.find(|x: char| predicate(x)) {
404 Some(a.len() + pos)
405 } else {
406 None
407 }
408 } pub fn rfind<P>(&self, predicate: P) -> Option<usize>
412 where
413 P: Fn(char) -> bool,
414 {
415 let (a, b) = self.to_strs();
416 if let Some(pos) = b.find(|x: char| predicate(x)) {
417 Some(a.len() + pos)
418 } else if let Some(pos) = a.find(|x: char| predicate(x)) {
419 Some(pos)
420 } else {
421 None
422 }
423 } pub fn find_substr(&self, s: &str) -> Option<usize> {
427 let (a, b) = self.to_strs();
428 if let Some(pos) = a.find(s) {
429 return Some(pos);
430 }
431 if s.len() > 1 {
432 for i in 0..s.len() - 1 {
434 let mid = s.len() - i - 1;
435 if a.ends_with(&s[..mid]) && b.starts_with(&s[mid..]) {
436 return Some(a.len() - mid);
437 }
438 } }
440 if let Some(pos) = b.find(s) {
441 return Some(a.len() + pos);
442 } else {
443 None
444 }
445 } pub fn rfind_substr(&self, s: &str) -> Option<usize> {
449 let (a, b) = self.to_strs();
450 if let Some(pos) = b.find(s) {
451 return Some(a.len() + pos);
452 }
453 if s.len() > 1 {
454 for i in 0..s.len() - 1 {
456 let mid = s.len() - i - 1;
457 if b.starts_with(&s[mid..]) && a.ends_with(&s[..mid]) {
458 return Some(a.len() - mid);
459 }
460 } }
462 if let Some(pos) = a.find(s) {
463 Some(pos)
464 } else {
465 None
466 }
467 } pub fn trim_left(&mut self) {
471 let (a, b) = self.to_strs();
472 let offset;
473 if let Some(i) = a.find(|c: char| !c.is_whitespace()) {
474 offset = i as u16;
475 } else if let Some(k) = b.find(|c: char| !c.is_whitespace()) {
476 offset = (a.len() + k) as u16;
477 } else {
478 offset = (a.len() + b.len()) as u16;
479 }
480 self.front = self.index16(offset); self.len -= offset;
482 } pub fn trim_right(&mut self) {
486 let (a, b) = self.to_strs();
487 let offset;
488 if b.len() == 0 {
489 if let Some(k) = a.rfind(|c: char| !c.is_whitespace()) {
490 offset = a.len() - k - 1;
491 } else {
492 offset = a.len();
493 }
494 }
495 else if let Some(i) = b.rfind(|c: char| !c.is_whitespace()) {
497 offset = b.len() - i - 1;
498 } else if let Some(k) = a.rfind(|c: char| !c.is_whitespace()) {
499 offset = b.len() + (a.len() - k - 1)
500 } else {
501 offset = a.len() + b.len();
502 }
503 self.len -= offset as u16;
504 } pub fn trim_whitespaces(&mut self) {
508 self.trim_left();
509 self.trim_right();
510 }
511
512 #[inline(always)]
514 const fn endi(&self) -> usize {
515 (self.front as usize + self.len as usize) % N
518 } #[inline(always)]
521 const fn index(&self, i: usize) -> usize {
522 (self.front as usize + i) % N
523 } #[inline(always)]
527 pub const fn len(&self) -> usize {
528 self.len as usize
529 }
530
531 #[inline(always)]
533 pub const fn new() -> Self {
534 cstr {
535 chrs: [0; N],
536 front: 0,
537 len: 0,
538 }
539 } pub fn to_strs(&self) -> (&str, &str) {
545 let answer;
546 if self.len() == 0 {
547 answer = ("", "");
548 } else if self.is_contiguous() {
549 let front = self.front as usize;
550 answer = (
551 core::str::from_utf8(&self.chrs[front..front + (self.len as usize)]).unwrap(),
552 "",
553 )
554 } else {
555 answer = (
556 core::str::from_utf8(&self.chrs[self.front as usize..]).unwrap(),
557 core::str::from_utf8(&self.chrs[..self.endi()]).unwrap(),
558 )
559 }
560 answer
561 } pub fn chars<'a>(&'a self) -> CircCharIter<'a> {
565 let contig = self.is_contiguous();
566 CircCharIter {
567 first: if contig {
568 &self.chrs[self.front as usize..(self.front + self.len) as usize]
569 } else {
570 &self.chrs[self.front as usize..]
571 },
572 second: if contig {
573 &[]
574 } else {
575 &self.chrs[..self.endi()]
576 },
577 index: 0,
578 }
579 } pub fn iter<'a>(&'a self) -> CircCharIter<'a> {
583 self.chars()
584 }
585
586 pub fn to_contiguous(&self) -> cstr<N> {
589 let mut c = *self;
590 if !c.is_contiguous() {
591 c.reset();
592 }
593 c
594 }
595
596 pub fn force_str(&self) -> &str {
599 let (a, b) = self.to_strs();
600 if b.len() > 0 {
601 panic!("cstr cannot be transformed into a single str slice without calling reset()");
602 }
603 a
604 }
605
606 #[cfg(not(feature = "no-alloc"))]
608 pub fn to_string(&self) -> alloc::string::String {
609 let (a, b) = self.to_strs();
610 let mut s = alloc::string::String::from(a);
611 if b.len() > 0 {
612 s.push_str(b);
613 }
614 s
615 } pub fn substr(&self, start: usize, end: usize) -> cstr<N> {
620 let mut s = cstr::<N>::default();
621 if (end <= start || start as u16 > self.len - 1 || end > self.len as usize) {
622 return s;
623 }
624 for i in start..end {
625 s.chrs[i - start] = self.chrs[self.index(i)];
626 }
627 s.len = (end - start) as u16;
628 s
629 } pub fn make_ascii_lowercase(&mut self) {
633 for i in 0..self.len as usize {
634 let b = &mut self.chrs[self.index(i)];
635 if *b >= 65 && *b <= 90 {
636 *b |= 32;
637 }
638 }
639 } pub fn make_ascii_uppercase(&mut self) {
643 for i in 0..self.len as usize {
644 let b = &mut self.chrs[self.index(i)];
645 if *b >= 97 && *b <= 122 {
646 *b -= 32;
647 }
648 }
649 } pub fn case_insensitive_eq<TA>(&self, other: TA) -> bool
654 where
655 TA: AsRef<str>,
656 {
657 if self.len() != other.as_ref().len() {
658 return false;
659 }
660 let obytes = other.as_ref().as_bytes();
661 for i in 0..self.len() {
662 let mut c = self.chrs[(self.front as usize + i) % N];
663 if (c > 64 && c < 91) {
664 c = c | 32;
665 } let mut d = obytes[i];
667 if (d > 64 && d < 91) {
668 d = d | 32;
669 } if c != d {
671 return false;
672 }
673 } true
675 } pub fn from_utf16(v: &[u16]) -> Result<Self, Self> {
682 let mut s = Self::new();
683 for c in char::decode_utf16(v.iter().cloned()) {
684 if let Ok(c1) = c {
685 if !s.push_char(c1) {
686 return Err(s);
687 }
688 } else {
689 return Err(s);
690 }
691 }
692 Ok(s)
693 } #[inline(always)]
719 fn index16(&self, i: u16) -> u16 {
720 (self.front + i) % (N as u16)
721 }
725} impl<const M: usize> cstr<M> {
729 pub fn resize<const N: usize>(&self) -> cstr<N> {
733 let slen = self.len();
734 let length = if (slen < N) { slen } else { N };
735 let mut s = cstr::<N>::default();
736 let (a, b) = self.to_strs();
737 s.chrs[..a.len()].copy_from_slice(a.as_bytes());
738 if b.len() > 0 {
739 s.chrs[a.len()..].copy_from_slice(b.as_bytes());
740 }
741 s.len = self.len;
742 s
743 } pub fn reallocate<const N: usize>(&self) -> Option<cstr<N>> {
747 if self.len() < N {
748 Some(self.resize())
749 } else {
750 None
751 }
752 }
753} impl<const N: usize> Default for cstr<N> {
756 fn default() -> Self {
757 cstr {
758 chrs: [0; N],
759 front: 0,
760 len: 0,
761 }
762 }
763} impl<const N: usize> core::fmt::Debug for cstr<N> {
766 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
767 let (a, b) = self.to_strs();
768 f.pad(a)?;
769 f.pad(b)
770 }
771} impl<const N: usize> core::fmt::Display for cstr<N> {
774 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
775 let (a, b) = self.to_strs();
776 f.pad(a)?;
778 f.pad(b)
779 }
780}
781
782impl<const N: usize> PartialEq<&str> for cstr<N> {
784 fn eq(&self, other: &&str) -> bool {
785 &self == other
786 } }
788
789impl<const N: usize> PartialEq<&str> for &cstr<N> {
790 fn eq(&self, other: &&str) -> bool {
791 let (a, b) = self.to_strs();
792 let (alen, blen) = (a.len(), b.len());
793 alen + blen == other.len() && a == &other[..alen] && (blen == 0 || b == &other[alen..])
794 } }
796
797impl<const N: usize> PartialEq<cstr<N>> for &str {
798 fn eq(&self, other: &cstr<N>) -> bool {
799 let (a, b) = other.to_strs();
800 let (alen, blen) = (a.len(), b.len());
801 alen + blen == self.len() && a == &self[..alen] && (blen == 0 || b == &self[alen..])
802 } }
804
805impl<const N: usize> PartialEq<&cstr<N>> for &str {
806 fn eq(&self, other: &&cstr<N>) -> bool {
807 let (a, b) = other.to_strs();
808 let (alen, blen) = (a.len(), b.len());
809 alen + blen == self.len() && a == &self[..alen] && (blen == 0 || b == &self[alen..])
810 } }
812
813pub struct CircCharIter<'a> {
815 first: &'a [u8],
816 second: &'a [u8],
817 index: usize,
818}
819impl<'a> Iterator for CircCharIter<'a> {
820 type Item = char;
821 fn next(&mut self) -> Option<Self::Item> {
822 if self.index < self.first.len() {
823 self.index += 1;
824 Some(self.first[self.index - 1] as char)
825 } else if self.index - self.first.len() < self.second.len() {
826 self.index += 1;
827 Some(self.second[self.index - self.first.len() - 1] as char)
828 } else {
829 None
830 }
831 } } impl<const N: usize, const M: usize> PartialEq<cstr<M>> for cstr<N> {
838 fn eq(&self, other: &cstr<M>) -> bool {
839 if self.len != other.len {
840 return false;
841 }
842 for i in 0..self.len {
843 if self.chrs[(self.front + i) as usize % N]
844 != other.chrs[(other.front + i) as usize % M]
845 {
846 return false;
847 }
848 } true
850 } } impl<const N: usize> Eq for cstr<N> {}
869
870impl<const N: usize> Ord for cstr<N> {
871 fn cmp(&self, other: &Self) -> Ordering {
872 let mut schars = self.chars();
873 let mut ochars = other.chars();
874 let mut answer = Ordering::Equal;
875 loop {
876 match (schars.next(), ochars.next()) {
877 (Some(x), Some(y)) if x.cmp(&y) == Ordering::Equal => {}
878 (Some(x), Some(y)) => {
879 answer = x.cmp(&y);
880 break;
881 }
882 (None, None) => {
883 break;
884 }
885 (None, _) => {
886 answer = Ordering::Less;
887 break;
888 }
889 (_, None) => {
890 answer = Ordering::Greater;
891 break;
892 }
893 } } answer
896 } } impl<const N: usize> PartialOrd for cstr<N> {
900 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
901 Some(self.cmp(other))
902 } } impl<const N: usize> PartialOrd<&str> for cstr<N> {
921 fn partial_cmp(&self, other: &&str) -> Option<Ordering> {
922 let mut schars = self.chars();
923 let mut ochars = other.chars();
924 let mut answer = Ordering::Equal;
925 loop {
926 match (schars.next(), ochars.next()) {
927 (Some(x), Some(y)) if x.cmp(&y) == Ordering::Equal => {}
928 (Some(x), Some(y)) => {
929 answer = x.cmp(&y);
930 break;
931 }
932 (None, None) => {
933 break;
934 }
935 (None, _) => {
936 answer = Ordering::Less;
937 break;
938 }
939 (_, None) => {
940 answer = Ordering::Greater;
941 break;
942 }
943 } } Some(answer)
946 } } impl<const N: usize> PartialOrd<&str> for &cstr<N> {
950 fn partial_cmp(&self, other: &&str) -> Option<Ordering> {
951 let mut schars = self.chars();
952 let mut ochars = other.chars();
953 let mut answer = Ordering::Equal;
954 loop {
955 match (schars.next(), ochars.next()) {
956 (Some(x), Some(y)) if x.cmp(&y) == Ordering::Equal => {}
957 (Some(x), Some(y)) => {
958 answer = x.cmp(&y);
959 break;
960 }
961 (None, None) => {
962 break;
963 }
964 (None, _) => {
965 answer = Ordering::Less;
966 break;
967 }
968 (_, None) => {
969 answer = Ordering::Greater;
970 break;
971 }
972 } } Some(answer)
975 } } impl<const N: usize> core::hash::Hash for cstr<N> {
981 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
982 for i in (0..self.len as usize).rev() {
983 self.nth_bytechar(i).hash(state);
984 }
985 }
987} impl<T: AsRef<str> + ?Sized, const N: usize> core::convert::From<&T> for cstr<N> {
990 fn from(s: &T) -> cstr<N> {
991 cstr::make(s.as_ref())
992 }
993}
994impl<T: AsMut<str> + ?Sized, const N: usize> core::convert::From<&mut T> for cstr<N> {
995 fn from(s: &mut T) -> cstr<N> {
996 cstr::make(s.as_mut())
997 }
998}
999
1000impl<const N: usize> core::fmt::Write for cstr<N> {
1001 fn write_str(&mut self, s: &str) -> core::fmt::Result {
1002 if s.len() + self.len() > N {
1003 return Err(core::fmt::Error::default());
1004 }
1005 self.push_str(s);
1006 Ok(())
1007 } } impl<const N: usize, TA: AsRef<str>> Add<TA> for cstr<N> {
1011 type Output = cstr<N>;
1012 fn add(self, other: TA) -> cstr<N> {
1013 let mut a2 = self;
1014 a2.push_str(other.as_ref());
1015 a2
1016 }
1017} impl<const N: usize> Add<&cstr<N>> for &str {
1020 type Output = cstr<N>;
1021 fn add(self, other: &cstr<N>) -> cstr<N> {
1022 let mut a2 = *other;
1023 a2.push_front(self);
1024 a2
1025 }
1026} impl<const N: usize> Add<cstr<N>> for &str {
1029 type Output = cstr<N>;
1030 fn add(self, mut other: cstr<N>) -> cstr<N> {
1031 other.push_front(self);
1032 other
1033 }
1034} impl<const N: usize> Add for &cstr<N> {
1037 type Output = cstr<N>;
1038 fn add(self, other: &cstr<N>) -> cstr<N> {
1039 let mut a2 = *self;
1040 let (l, r) = other.to_strs();
1041 a2.push_str(l);
1042 if r.len() > 0 {
1043 a2.push_str(r);
1044 }
1045 a2
1046 }
1047} impl<const N: usize> Add for cstr<N> {
1050 type Output = cstr<N>;
1051 fn add(self, other: cstr<N>) -> cstr<N> {
1052 let mut a2 = self;
1053 let (l, r) = other.to_strs();
1054 a2.push_str(l);
1055 if r.len() > 0 {
1056 a2.push_str(r);
1057 }
1058 a2
1059 }
1060} impl<const N: usize> core::str::FromStr for cstr<N> {
1063 type Err = &'static str;
1064 fn from_str(s: &str) -> Result<Self, Self::Err> {
1065 if s.len() <= N {
1066 Ok(cstr::from(s))
1067 } else {
1068 Err("capacity exceeded")
1069 }
1070 }
1071}
1072
1073pub type cstr1k = cstr<1024>;
1086pub type cstr8 = cstr<8>;
1087pub type cstr16 = cstr<16>;
1088pub type cstr32 = cstr<32>;
1089pub type cstr64 = cstr<64>;
1090pub type cstr128 = cstr<128>;
1091pub type cstr256 = cstr<256>;
1092pub type cstr512 = cstr<512>;