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 {
156 len = N;
157 }
158 let bytes = src.as_bytes();
160 let mut i = 0;
161 while i < len {
162 m.chrs[i] = bytes[i];
163 i += 1;
164 }
165 m.len = len as u16;
166 m
167 } pub const fn const_try_make(s: &str) -> Result<cstr<N>, &str> {
171 if s.len() > N || N < 1 || N > 65535 {
172 Err(s)
173 } else {
174 Ok(cstr::const_make(s))
175 }
176 }
177
178 #[inline(always)]
181 pub fn is_contiguous(&self) -> bool {
182 (self.front as usize + self.len as usize) <= N
183 }
184
185 pub fn reset(&mut self) {
190 if self.front == 0 {
191 return;
192 }
193 let mut mhrs = [0; N];
194 for i in 0..self.len as usize {
195 mhrs[i] = self.chrs[self.index(i)];
196 }
197 self.chrs = mhrs;
198 self.front = 0;
199 } pub fn clear(&mut self) {
203 self.len = 0;
204 }
205
206 pub fn zero(&mut self) {
209 self.chrs = [0; N];
210 self.front = 0;
211 self.len = 0;
212 }
213
214 pub fn make_contiguous(&mut self) {
217 if !self.is_contiguous() {
218 self.reset();
219 }
220 }
221
222 pub fn nth(&self, n: usize) -> Option<char> {
227 if n < self.len as usize {
228 Some(self.chrs[self.index(n)] as char)
229 } else {
230 None
231 }
232 }
233
234 #[inline]
237 pub const fn nth_bytechar(&self, n: usize) -> char {
238 self.chrs[self.index(n)] as char
239 }
240
241 pub fn set(&mut self, n: usize, c: char) -> bool {
244 if c.len_utf8() > 1 || n >= self.len as usize {
245 false
246 } else {
247 self.chrs[self.index(n)] = c as u8;
248 true
249 }
250 } pub fn push_str<'t>(&mut self, src: &'t str) -> &'t str {
254 let srclen = src.len();
255 let slen = self.len as usize;
256 let bytes = &src.as_bytes();
257 let length = core::cmp::min(slen + srclen, N);
258 let remain = if N > (slen + srclen) {
259 0
260 } else {
261 (srclen + slen) - N
262 };
263 let mut i = 0;
264 while i < srclen && i + slen < N {
265 self.chrs[self.index(slen + i)] = bytes[i];
266 i += 1;
267 } self.len += i as u16;
269 &src[srclen - remain..]
270 } pub fn push_front<'t>(&mut self, src: &'t str) -> &'t str {
277 let srclen = src.len();
278 let slen = self.len as usize;
279 let bytes = &src.as_bytes();
280 let length = core::cmp::min(slen + srclen, N);
281 let remain = if N >= (slen + srclen) {
282 0
283 } else {
284 (srclen + slen) - N
285 };
286 let mut i = 0;
287 while i < srclen && i + slen < N {
288 self.front = ((self.front as usize + N - 1) % N) as u16;
290 self.chrs[self.front as usize] = bytes[srclen - 1 - i];
291 i += 1;
292 } self.len += i as u16;
294 &src[..remain]
295 } pub fn push_str_front<'t>(&mut self, src: &'t str) -> &'t str {
299 self.push_front(src)
300 }
301
302 pub fn push_char(&mut self, c: char) -> bool {
306 let clen = c.len_utf8();
307 if clen > 1 || self.len as usize + clen > N {
308 return false;
309 }
310 let mut buf = [0u8; 4]; let bstr = c.encode_utf8(&mut buf);
312 self.push_str(bstr);
313 true
314 } pub fn push_char_front(&mut self, c: char) -> bool {
320 let clen = c.len_utf8();
321 if clen > 1 || self.len as usize + clen > N {
322 return false;
323 }
324 let newfront = (self.front as usize + N - 1) % N;
325 self.chrs[newfront] = c as u8;
326 self.front = newfront as u16;
327 self.len += 1;
328 true
329 } pub fn pop_char(&mut self) -> Option<char> {
333 if self.len() == 0 {
334 return None;
335 }
336 let lasti = ((self.front + self.len - 1) as usize) % N;
337 let firstchar = self.chrs[lasti] as char;
338 self.len -= 1;
339 Some(firstchar)
340 } pub fn pop_char_front(&mut self) -> Option<char> {
351 if self.len() == 0 {
352 return None;
353 }
354 let firstchar = self.chrs[self.front as usize] as char;
355 self.front = self.index16(1);
356 self.len -= 1;
357 Some(firstchar)
358 } pub fn truncate_right(&mut self, n: usize) {
362 if (n < self.len as usize) {
363 self.len = n as u16;
364 }
365 }
366
367 #[inline]
371 pub fn truncate(&mut self, n: usize) {
372 self.truncate_right(n);
373 }
374
375 pub fn truncate_left(&mut self, n: usize) {
380 if (n > 0 && n <= self.len as usize) {
381 self.front = self.index16(n as u16);
391 self.len -= n as u16;
392 }
393 } pub fn truncate_front(&mut self, n: usize) {
397 self.truncate_left(n);
398 }
399
400 pub fn find<P>(&self, predicate: P) -> Option<usize>
402 where
403 P: Fn(char) -> bool,
404 {
405 let (a, b) = self.to_strs();
406 if let Some(pos) = a.find(|x: char| predicate(x)) {
407 Some(pos)
408 } else if let Some(pos) = b.find(|x: char| predicate(x)) {
409 Some(a.len() + pos)
410 } else {
411 None
412 }
413 } pub fn rfind<P>(&self, predicate: P) -> Option<usize>
417 where
418 P: Fn(char) -> bool,
419 {
420 let (a, b) = self.to_strs();
421 if let Some(pos) = b.find(|x: char| predicate(x)) {
422 Some(a.len() + pos)
423 } else if let Some(pos) = a.find(|x: char| predicate(x)) {
424 Some(pos)
425 } else {
426 None
427 }
428 } pub fn find_substr(&self, s: &str) -> Option<usize> {
432 let (a, b) = self.to_strs();
433 if let Some(pos) = a.find(s) {
434 return Some(pos);
435 }
436 if s.len() > 1 {
437 for i in 0..s.len() - 1 {
439 let mid = s.len() - i - 1;
440 if a.ends_with(&s[..mid]) && b.starts_with(&s[mid..]) {
441 return Some(a.len() - mid);
442 }
443 } }
445 if let Some(pos) = b.find(s) {
446 return Some(a.len() + pos);
447 } else {
448 None
449 }
450 } pub fn rfind_substr(&self, s: &str) -> Option<usize> {
454 let (a, b) = self.to_strs();
455 if let Some(pos) = b.find(s) {
456 return Some(a.len() + pos);
457 }
458 if s.len() > 1 {
459 for i in 0..s.len() - 1 {
461 let mid = s.len() - i - 1;
462 if b.starts_with(&s[mid..]) && a.ends_with(&s[..mid]) {
463 return Some(a.len() - mid);
464 }
465 } }
467 if let Some(pos) = a.find(s) {
468 Some(pos)
469 } else {
470 None
471 }
472 } pub fn trim_left(&mut self) {
476 let (a, b) = self.to_strs();
477 let offset;
478 if let Some(i) = a.find(|c: char| !c.is_whitespace()) {
479 offset = i as u16;
480 } else if let Some(k) = b.find(|c: char| !c.is_whitespace()) {
481 offset = (a.len() + k) as u16;
482 } else {
483 offset = (a.len() + b.len()) as u16;
484 }
485 self.front = self.index16(offset); self.len -= offset;
487 } pub fn trim_right(&mut self) {
491 let (a, b) = self.to_strs();
492 let offset;
493 if b.len() == 0 {
494 if let Some(k) = a.rfind(|c: char| !c.is_whitespace()) {
495 offset = a.len() - k - 1;
496 } else {
497 offset = a.len();
498 }
499 }
500 else if let Some(i) = b.rfind(|c: char| !c.is_whitespace()) {
502 offset = b.len() - i - 1;
503 } else if let Some(k) = a.rfind(|c: char| !c.is_whitespace()) {
504 offset = b.len() + (a.len() - k - 1)
505 } else {
506 offset = a.len() + b.len();
507 }
508 self.len -= offset as u16;
509 } pub fn trim_whitespaces(&mut self) {
513 self.trim_left();
514 self.trim_right();
515 }
516
517 #[inline(always)]
519 const fn endi(&self) -> usize {
520 (self.front as usize + self.len as usize) % N
523 } #[inline(always)]
526 const fn index(&self, i: usize) -> usize {
527 (self.front as usize + i) % N
528 } #[inline(always)]
532 pub const fn len(&self) -> usize {
533 self.len as usize
534 }
535
536 #[inline(always)]
538 pub const fn new() -> Self {
539 cstr {
540 chrs: [0; N],
541 front: 0,
542 len: 0,
543 }
544 } pub fn to_strs(&self) -> (&str, &str) {
550 let answer;
551 if self.len() == 0 {
552 answer = ("", "");
553 } else if self.is_contiguous() {
554 let front = self.front as usize;
555 answer = (
556 core::str::from_utf8(&self.chrs[front..front + (self.len as usize)]).unwrap(),
557 "",
558 )
559 } else {
560 answer = (
561 core::str::from_utf8(&self.chrs[self.front as usize..]).unwrap(),
562 core::str::from_utf8(&self.chrs[..self.endi()]).unwrap(),
563 )
564 }
565 answer
566 } pub fn chars<'a>(&'a self) -> CircCharIter<'a> {
570 let contig = self.is_contiguous();
571 CircCharIter {
572 first: if contig {
573 &self.chrs[self.front as usize..(self.front + self.len) as usize]
574 } else {
575 &self.chrs[self.front as usize..]
576 },
577 second: if contig {
578 &[]
579 } else {
580 &self.chrs[..self.endi()]
581 },
582 index: 0,
583 }
584 } pub fn iter<'a>(&'a self) -> CircCharIter<'a> {
588 self.chars()
589 }
590
591 pub fn to_contiguous(&self) -> cstr<N> {
594 let mut c = *self;
595 if !c.is_contiguous() {
596 c.reset();
597 }
598 c
599 }
600
601 pub fn force_str(&self) -> &str {
604 let (a, b) = self.to_strs();
605 if b.len() > 0 {
606 panic!("cstr cannot be transformed into a single str slice without calling reset()");
607 }
608 a
609 }
610
611 #[cfg(not(feature = "no-alloc"))]
613 pub fn to_string(&self) -> alloc::string::String {
614 let (a, b) = self.to_strs();
615 let mut s = alloc::string::String::from(a);
616 if b.len() > 0 {
617 s.push_str(b);
618 }
619 s
620 } pub fn substr(&self, start: usize, end: usize) -> cstr<N> {
625 let mut s = cstr::<N>::default();
626 if (end <= start || start as u16 > self.len - 1 || end > self.len as usize) {
627 return s;
628 }
629 for i in start..end {
630 s.chrs[i - start] = self.chrs[self.index(i)];
631 }
632 s.len = (end - start) as u16;
633 s
634 } pub fn make_ascii_lowercase(&mut self) {
638 for i in 0..self.len as usize {
639 let b = &mut self.chrs[self.index(i)];
640 if *b >= 65 && *b <= 90 {
641 *b |= 32;
642 }
643 }
644 } pub fn make_ascii_uppercase(&mut self) {
648 for i in 0..self.len as usize {
649 let b = &mut self.chrs[self.index(i)];
650 if *b >= 97 && *b <= 122 {
651 *b -= 32;
652 }
653 }
654 } pub fn case_insensitive_eq<TA>(&self, other: TA) -> bool
659 where
660 TA: AsRef<str>,
661 {
662 if self.len() != other.as_ref().len() {
663 return false;
664 }
665 let obytes = other.as_ref().as_bytes();
666 for i in 0..self.len() {
667 let mut c = self.chrs[(self.front as usize + i) % N];
668 if (c > 64 && c < 91) {
669 c = c | 32;
670 } let mut d = obytes[i];
672 if (d > 64 && d < 91) {
673 d = d | 32;
674 } if c != d {
676 return false;
677 }
678 } true
680 } pub fn from_utf16(v: &[u16]) -> Result<Self, Self> {
687 let mut s = Self::new();
688 for c in char::decode_utf16(v.iter().cloned()) {
689 if let Ok(c1) = c {
690 if !s.push_char(c1) {
691 return Err(s);
692 }
693 } else {
694 return Err(s);
695 }
696 }
697 Ok(s)
698 } #[inline(always)]
724 fn index16(&self, i: u16) -> u16 {
725 (self.front + i) % (N as u16)
726 }
730} impl<const M: usize> cstr<M> {
734 pub fn resize<const N: usize>(&self) -> cstr<N> {
738 let slen = self.len();
739 let length = if (slen < N) { slen } else { N };
740 let mut s = cstr::<N>::default();
741 let (a, b) = self.to_strs();
742 s.chrs[..a.len()].copy_from_slice(a.as_bytes());
743 if b.len() > 0 {
744 s.chrs[a.len()..].copy_from_slice(b.as_bytes());
745 }
746 s.len = self.len;
747 s
748 } pub fn reallocate<const N: usize>(&self) -> Option<cstr<N>> {
752 if self.len() < N {
753 Some(self.resize())
754 } else {
755 None
756 }
757 }
758} impl<const N: usize> Default for cstr<N> {
761 fn default() -> Self {
762 cstr {
763 chrs: [0; N],
764 front: 0,
765 len: 0,
766 }
767 }
768} impl<const N: usize> core::fmt::Debug for cstr<N> {
771 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
772 let (a, b) = self.to_strs();
773 f.pad(a)?;
774 f.pad(b)
775 }
776} impl<const N: usize> core::fmt::Display for cstr<N> {
779 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
780 let (a, b) = self.to_strs();
781 f.pad(a)?;
783 f.pad(b)
784 }
785}
786
787impl<const N: usize> PartialEq<&str> for cstr<N> {
789 fn eq(&self, other: &&str) -> bool {
790 &self == other
791 } }
793
794impl<const N: usize> PartialEq<&str> for &cstr<N> {
795 fn eq(&self, other: &&str) -> bool {
796 let (a, b) = self.to_strs();
797 let (alen, blen) = (a.len(), b.len());
798 alen + blen == other.len() && a == &other[..alen] && (blen == 0 || b == &other[alen..])
799 } }
801
802impl<const N: usize> PartialEq<cstr<N>> for &str {
803 fn eq(&self, other: &cstr<N>) -> bool {
804 let (a, b) = other.to_strs();
805 let (alen, blen) = (a.len(), b.len());
806 alen + blen == self.len() && a == &self[..alen] && (blen == 0 || b == &self[alen..])
807 } }
809
810impl<const N: usize> PartialEq<&cstr<N>> for &str {
811 fn eq(&self, other: &&cstr<N>) -> bool {
812 let (a, b) = other.to_strs();
813 let (alen, blen) = (a.len(), b.len());
814 alen + blen == self.len() && a == &self[..alen] && (blen == 0 || b == &self[alen..])
815 } }
817
818pub struct CircCharIter<'a> {
820 first: &'a [u8],
821 second: &'a [u8],
822 index: usize,
823}
824impl<'a> Iterator for CircCharIter<'a> {
825 type Item = char;
826 fn next(&mut self) -> Option<Self::Item> {
827 if self.index < self.first.len() {
828 self.index += 1;
829 Some(self.first[self.index - 1] as char)
830 } else if self.index - self.first.len() < self.second.len() {
831 self.index += 1;
832 Some(self.second[self.index - self.first.len() - 1] as char)
833 } else {
834 None
835 }
836 } } impl<const N: usize, const M: usize> PartialEq<cstr<M>> for cstr<N> {
843 fn eq(&self, other: &cstr<M>) -> bool {
844 if self.len != other.len {
845 return false;
846 }
847 for i in 0..self.len {
848 if self.chrs[(self.front + i) as usize % N]
849 != other.chrs[(other.front + i) as usize % M]
850 {
851 return false;
852 }
853 } true
855 } } impl<const N: usize> Eq for cstr<N> {}
874
875impl<const N: usize> Ord for cstr<N> {
876 fn cmp(&self, other: &Self) -> Ordering {
877 let mut schars = self.chars();
878 let mut ochars = other.chars();
879 let mut answer = Ordering::Equal;
880 loop {
881 match (schars.next(), ochars.next()) {
882 (Some(x), Some(y)) if x.cmp(&y) == Ordering::Equal => {}
883 (Some(x), Some(y)) => {
884 answer = x.cmp(&y);
885 break;
886 }
887 (None, None) => {
888 break;
889 }
890 (None, _) => {
891 answer = Ordering::Less;
892 break;
893 }
894 (_, None) => {
895 answer = Ordering::Greater;
896 break;
897 }
898 } } answer
901 } } impl<const N: usize> PartialOrd for cstr<N> {
905 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
906 Some(self.cmp(other))
907 } } impl<const N: usize> PartialOrd<&str> for cstr<N> {
926 fn partial_cmp(&self, other: &&str) -> Option<Ordering> {
927 let mut schars = self.chars();
928 let mut ochars = other.chars();
929 let mut answer = Ordering::Equal;
930 loop {
931 match (schars.next(), ochars.next()) {
932 (Some(x), Some(y)) if x.cmp(&y) == Ordering::Equal => {}
933 (Some(x), Some(y)) => {
934 answer = x.cmp(&y);
935 break;
936 }
937 (None, None) => {
938 break;
939 }
940 (None, _) => {
941 answer = Ordering::Less;
942 break;
943 }
944 (_, None) => {
945 answer = Ordering::Greater;
946 break;
947 }
948 } } Some(answer)
951 } } impl<const N: usize> PartialOrd<&str> for &cstr<N> {
955 fn partial_cmp(&self, other: &&str) -> Option<Ordering> {
956 let mut schars = self.chars();
957 let mut ochars = other.chars();
958 let mut answer = Ordering::Equal;
959 loop {
960 match (schars.next(), ochars.next()) {
961 (Some(x), Some(y)) if x.cmp(&y) == Ordering::Equal => {}
962 (Some(x), Some(y)) => {
963 answer = x.cmp(&y);
964 break;
965 }
966 (None, None) => {
967 break;
968 }
969 (None, _) => {
970 answer = Ordering::Less;
971 break;
972 }
973 (_, None) => {
974 answer = Ordering::Greater;
975 break;
976 }
977 } } Some(answer)
980 } } impl<const N: usize> core::hash::Hash for cstr<N> {
986 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
987 for i in (0..self.len as usize).rev() {
988 self.nth_bytechar(i).hash(state);
989 }
990 }
992} impl<T: AsRef<str> + ?Sized, const N: usize> core::convert::From<&T> for cstr<N> {
995 fn from(s: &T) -> cstr<N> {
996 cstr::make(s.as_ref())
997 }
998}
999impl<T: AsMut<str> + ?Sized, const N: usize> core::convert::From<&mut T> for cstr<N> {
1000 fn from(s: &mut T) -> cstr<N> {
1001 cstr::make(s.as_mut())
1002 }
1003}
1004
1005impl<const N: usize> core::fmt::Write for cstr<N> {
1006 fn write_str(&mut self, s: &str) -> core::fmt::Result {
1007 if s.len() + self.len() > N {
1008 return Err(core::fmt::Error::default());
1009 }
1010 self.push_str(s);
1011 Ok(())
1012 } } impl<const N: usize, TA: AsRef<str>> Add<TA> for cstr<N> {
1016 type Output = cstr<N>;
1017 fn add(self, other: TA) -> cstr<N> {
1018 let mut a2 = self;
1019 a2.push_str(other.as_ref());
1020 a2
1021 }
1022} impl<const N: usize> Add<&cstr<N>> for &str {
1025 type Output = cstr<N>;
1026 fn add(self, other: &cstr<N>) -> cstr<N> {
1027 let mut a2 = *other;
1028 a2.push_front(self);
1029 a2
1030 }
1031} impl<const N: usize> Add<cstr<N>> for &str {
1034 type Output = cstr<N>;
1035 fn add(self, mut other: cstr<N>) -> cstr<N> {
1036 other.push_front(self);
1037 other
1038 }
1039} impl<const N: usize> Add for &cstr<N> {
1042 type Output = cstr<N>;
1043 fn add(self, other: &cstr<N>) -> cstr<N> {
1044 let mut a2 = *self;
1045 let (l, r) = other.to_strs();
1046 a2.push_str(l);
1047 if r.len() > 0 {
1048 a2.push_str(r);
1049 }
1050 a2
1051 }
1052} impl<const N: usize> Add for cstr<N> {
1055 type Output = cstr<N>;
1056 fn add(self, other: cstr<N>) -> cstr<N> {
1057 let mut a2 = self;
1058 let (l, r) = other.to_strs();
1059 a2.push_str(l);
1060 if r.len() > 0 {
1061 a2.push_str(r);
1062 }
1063 a2
1064 }
1065} impl<const N: usize> core::str::FromStr for cstr<N> {
1068 type Err = &'static str;
1069 fn from_str(s: &str) -> Result<Self, Self::Err> {
1070 if s.len() <= N {
1071 Ok(cstr::from(s))
1072 } else {
1073 Err("capacity exceeded")
1074 }
1075 }
1076}
1077
1078pub type cstr1k = cstr<1024>;
1091pub type cstr8 = cstr<8>;
1092pub type cstr16 = cstr<16>;
1093pub type cstr32 = cstr<32>;
1094pub type cstr64 = cstr<64>;
1095pub type cstr128 = cstr<128>;
1096pub type cstr256 = cstr<256>;
1097pub type cstr512 = cstr<512>;