const_str/__ctfe/
concat.rs1#![allow(unsafe_code)]
2
3use super::StrBuf;
4
5pub struct Concat<'a>(pub &'a [&'a str]);
6
7impl Concat<'_> {
8 pub const fn output_len(&self) -> usize {
9 let mut ans = 0;
10 let mut iter = self.0;
11 while let [x, xs @ ..] = iter {
12 ans += x.len();
13 iter = xs;
14 }
15 ans
16 }
17
18 pub const fn const_eval<const N: usize>(&self) -> StrBuf<N> {
19 let mut buf = [0; N];
20 let mut pos = 0;
21
22 let mut iter = self.0;
23 while let [x, xs @ ..] = iter {
24 let x = x.as_bytes();
25 let mut i = 0;
26 while i < x.len() {
27 buf[pos] = x[i];
28 pos += 1;
29 i += 1;
30 }
31 iter = xs;
32 }
33 assert!(pos == N);
34
35 unsafe { StrBuf::new_unchecked(buf) }
36 }
37}
38
39#[macro_export]
62macro_rules! concat {
63 ($($x: expr),+ $(,)?) => {{
64 const STRS: &[&str] = &[$( $crate::to_str!($x) ),+];
65 const OUTPUT_LEN: usize = $crate::__ctfe::Concat(STRS).output_len();
66 const OUTPUT_BUF: $crate::__ctfe::StrBuf<OUTPUT_LEN> = $crate::__ctfe::Concat(STRS).const_eval();
67 OUTPUT_BUF.as_str()
68 }}
69}
70
71pub struct Join<'a>(pub &'a [&'a str], pub &'a str);
72
73impl Join<'_> {
74 pub const fn output_len(&self) -> usize {
75 let mut ans = 0;
76 let mut i = 0;
77 while i < self.0.len() {
78 ans += self.0[i].len();
79 if i < self.0.len() - 1 {
80 ans += self.1.len();
81 }
82 i += 1;
83 }
84 ans
85 }
86
87 pub const fn const_eval<const N: usize>(&self) -> StrBuf<N> {
88 let mut buf = [0; N];
89 let mut pos = 0;
90
91 let mut i = 0;
92 while i < self.0.len() {
93 let x = self.0[i].as_bytes();
94 let mut j = 0;
95 while j < x.len() {
96 buf[pos] = x[j];
97 pos += 1;
98 j += 1;
99 }
100 if i < self.0.len() - 1 {
101 let sep = self.1.as_bytes();
102 let mut j = 0;
103 while j < sep.len() {
104 buf[pos] = sep[j];
105 pos += 1;
106 j += 1;
107 }
108 }
109 i += 1;
110 }
111
112 unsafe { StrBuf::new_unchecked(buf) }
113 }
114}
115
116#[macro_export]
136macro_rules! join {
137 ($strs: expr, $sep: expr) => {{
138 const STRS: &[&str] = $strs;
139 const SEP: &str = $sep;
140 const OUTPUT_LEN: usize = $crate::__ctfe::Join(STRS, SEP).output_len();
141 const OUTPUT_BUF: $crate::__ctfe::StrBuf<OUTPUT_LEN> =
142 $crate::__ctfe::Join(STRS, SEP).const_eval();
143 OUTPUT_BUF.as_str()
144 }};
145}