1use crate::Const;
4
5struct TwoValues<A, B>(A, B);
6impl<'a, T: ?Sized + 'a, A: Const<Type = &'a T>, B: Const<Type = &'a T>> Const for TwoValues<A, B> {
7 type Type = &'a [&'a T];
8 const VALUE: Self::Type = &[A::VALUE, B::VALUE];
9}
10pub const fn concat_strs2<'a, Lhs: Const<Type = &'a str>, Rhs: Const<Type = &'a str>>(
12) -> &'static str {
13 concat_strs::<TwoValues<Lhs, Rhs>>()
14}
15
16pub const fn concat_bytes2<'a, Lhs: Const<Type = &'a [u8]>, Rhs: Const<Type = &'a [u8]>>(
18) -> &'static [u8] {
19 concat_bytes::<TwoValues<Lhs, Rhs>>()
20}
21
22pub const fn concat_strs<'a, Strs: Const<Type = &'a [&'a str]>>() -> &'static str {
42 struct ToBytes<C>(C);
43 impl<'a, C: Const<Type = &'a [&'a str]>> Const for ToBytes<C> {
44 type Type = &'a [&'a [u8]];
45 const VALUE: Self::Type = unsafe {
47 let strs = crate::value_of::<C>();
48 core::slice::from_raw_parts(strs.as_ptr().cast(), strs.len())
49 };
50 }
51 match core::str::from_utf8(concat_bytes::<ToBytes<Strs>>()) {
52 Ok(s) => s,
53 Err(_) => unreachable!(),
54 }
55}
56
57macro_rules! generate_slice_concat {
58 ($T:ty, $input:ty, $default:expr) => {{
59 use generic_upper_bound as gub;
60 struct Concat<C>(C);
61 gub::impl_accept_upper_bound! {
62 impl{'a, C: Const<Type = &'a [&'a [$T]]>} Concat<C>;
63 const DESIRED_GENERIC: usize = {
64 let mut slices = crate::value_of::<C>();
65 let mut out = 0;
66 while let [first, rest @ ..] = slices {
67 out += first.len();
68 slices = rest;
69 }
70 out
71 };
72 const EVAL<const N: usize>: &'static [$T] = &{
73 let mut out = [const { $default }; N];
74 let mut out_slice: &mut [_] = &mut out;
75 let mut slices = crate::value_of::<C>();
76 while let [first, rest @ ..] = slices {
77 let lhs;
78 (lhs, out_slice) = out_slice.split_at_mut(first.len());
79 crate::utils::copy_from_slice(first, lhs);
80 slices = rest;
81 }
82 out
83 };
84 }
85 gub::eval_with_upper_bound::<Concat<$input>>()
86 .split_at(gub::desired_generic::<Concat<$input>>())
87 .0
88 }};
89}
90
91pub const fn concat_bytes<'a, Bytes: Const<Type = &'a [&'a [u8]]>>() -> &'static [u8] {
96 generate_slice_concat!(u8, Bytes, 0)
97}