1#![no_std]
2#![feature(trait_alias)]
3#![feature(generic_const_exprs)]
4#![feature(const_trait_impl)]
5#![feature(const_precise_live_drops)]
6#![feature(tuple_trait)]
7#![recursion_limit = "512"]
8
9use core::marker::Tuple;
112
113use blk_count_macro::count;
114use tupleops::{ConcatTuples, TupleConcat};
115
116pub type Left<T, const MIDDLE: usize> = <T as TupleSplitAt<MIDDLE>>::Left;
119pub type Right<T, const MIDDLE: usize> = <T as TupleSplitAt<MIDDLE>>::Right;
122
123#[diagnostic::on_unimplemented(message = "`{Self}` cannot be split at index `{MIDDLE}`")]
138#[const_trait]
139pub trait TupleSplitAt<const MIDDLE: usize>: Tuple
140{
141 type Left: Tuple;
142 type Right: Tuple;
143
144 fn split_tuple_at(self) -> (Self::Left, Self::Right);
145}
146
147#[diagnostic::on_unimplemented(message = "`{Self}` cannot be split up into `{L}` and `{R}`")]
161#[const_trait]
162pub trait TupleSplitInto<L, R>: ~const TupleSplitIntoLeft<L, Right = R> + ~const TupleSplitIntoRight<R, Left = L>
163where
164 L: Tuple,
165 R: Tuple
166{
167 fn split_tuple_into(self) -> (L, R);
168}
169
170impl<T, L, R> const TupleSplitInto<L, R> for T
171where
172 Self: ~const TupleSplitIntoLeft<L, Right = R> + ~const TupleSplitIntoRight<R, Left = L>,
173 L: Tuple,
174 R: Tuple
175{
176 fn split_tuple_into(self) -> (L, R)
177 {
178 self.split_tuple_into_left()
179 }
180}
181
182#[diagnostic::on_unimplemented(message = "`{L}` is not the left part of `{Self}`")]
196#[const_trait]
197pub trait TupleSplitIntoLeft<L>: Tuple
198where
199 L: Tuple
200{
201 type Right: Tuple;
202
203 fn split_tuple_into_left(self) -> (L, Self::Right);
204}
205
206#[diagnostic::on_unimplemented(message = "`{R}` is not the right part of `{Self}`")]
220#[const_trait]
221pub trait TupleSplitIntoRight<R>: Tuple
222where
223 R: Tuple
224{
225 type Left: Tuple;
226
227 fn split_tuple_into_right(self) -> (Self::Left, R);
228}
229
230pub const fn split_tuple_at<const MIDDLE: usize, T>(tuple: T) -> (T::Left, T::Right)
248where
249 T: ~const TupleSplitAt<MIDDLE>
250{
251 tuple.split_tuple_at()
252}
253
254pub const fn split_tuple_into<L, R>(tuple: ConcatTuples<L, R>) -> (L, R)
268where
269 L: Tuple,
270 R: Tuple,
271 (L, R): TupleConcat<L, R>,
272 ConcatTuples<L, R>: ~const TupleSplitInto<L, R>
273{
274 tuple.split_tuple_into()
275}
276
277pub const fn split_tuple_into_left<L, T>(tuple: T) -> (L, T::Right)
291where
292 L: Tuple,
293 T: ~const TupleSplitIntoLeft<L>
294{
295 tuple.split_tuple_into_left()
296}
297
298pub const fn split_tuple_into_right<R, T>(tuple: T) -> (T::Left, R)
312where
313 R: Tuple,
314 T: ~const TupleSplitIntoRight<R>
315{
316 tuple.split_tuple_into_right()
317}
318
319macro_rules! impl_split_single {
320 (( $($types1:ident),* ), ( $($types2:ident),* )) => {
321 impl<$($types1,)* $($types2,)*> const TupleSplitAt<{count!($($types1),*)}> for ($($types1,)* $($types2,)*)
322 {
323 type Left = ($($types1,)*);
324 type Right = ($($types2,)*);
325
326 fn split_tuple_at(self) -> (Self::Left, Self::Right)
327 {
328 let ($($types1,)* $($types2,)*) = self;
329 (($($types1,)*), ($($types2,)*))
330 }
331 }
332
333 impl<$($types1,)* $($types2,)*> const TupleSplitIntoLeft<($($types1,)*)> for ($($types1,)* $($types2,)*)
334 {
335 type Right = ($($types2,)*);
336
337 fn split_tuple_into_left(self) -> (($($types1,)*), ($($types2,)*))
338 {
339 let ($($types1,)* $($types2,)*) = self;
340 (($($types1,)*), ($($types2,)*))
341 }
342 }
343 impl<$($types1,)* $($types2,)*> const TupleSplitIntoRight<($($types2,)*)> for ($($types1,)* $($types2,)*)
344 {
345 type Left = ($($types1,)*);
346
347 fn split_tuple_into_right(self) -> (($($types1,)*), ($($types2,)*))
348 {
349 let ($($types1,)* $($types2,)*) = self;
350 (($($types1,)*), ($($types2,)*))
351 }
352 }
353 };
354}
355macro_rules! impl_split_combinations {
356 ( (), ( $($types2:ident),* ) ) => {
357 impl_split_single!{(), ($($types2),*)}
358 };
359 (($t0:ident $(,$types1:ident)* ), ( $($types2:ident),* )) => {
360 impl_split_single!{($t0 $(,$types1)*), ($($types2),*)}
361
362 impl_split_combinations!{($($types1),*), ($t0 $(,$types2)*)}
363 };
364 (($($types:ident),*)) => {
365 impl_split_combinations!{($($types),*), ()}
366 }
367}
368macro_rules! impl_split_all {
369 (()) => {
370 impl_split_combinations!{()}
371 };
372 (($t0:ident $(,$types:ident)*)) => {
373 impl_split_combinations!{($t0 $(,$types)*)}
374
375 impl_split_all!{($($types),*)}
376 }
377}
378
379#[cfg(not(feature = "8"))]
380impl_split_all! {
381 (
382 _1, _2, _3, _4
383 )
384}
385
386#[cfg(feature = "8")]
387#[cfg(any(feature = "dont_hurt_yourself_by_using_all_features", not(feature = "16")))]
388impl_split_all! {
389 (
390 _1, _2, _3, _4, _5, _6, _7, _8
391 )
392}
393
394#[cfg(feature = "16")]
395#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
396#[cfg(not(feature = "32"))]
397impl_split_all! {
398 (
399 _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16
400 )
401}
402
403#[cfg(feature = "32")]
404#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
405#[cfg(not(feature = "64"))]
406impl_split_all! {
407 (
408 _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
409 _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32
410 )
411}
412
413#[cfg(feature = "64")]
414#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
415#[cfg(not(feature = "96"))]
416impl_split_all! {
417 (
418 _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
419 _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32,
420 _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48,
421 _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64
422 )
423}
424
425#[cfg(feature = "96")]
426#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
427#[cfg(not(feature = "128"))]
428impl_split_all! {
429 (
430 _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
431 _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32,
432 _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48,
433 _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64,
434 _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,
435 _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96
436 )
437}
438
439#[cfg(feature = "128")]
440#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
441#[cfg(not(feature = "160"))]
442impl_split_all! {
443 (
444 _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
445 _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32,
446 _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48,
447 _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64,
448 _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,
449 _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96,
450 _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112,
451 _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128
452 )
453}
454
455#[cfg(feature = "160")]
456#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
457#[cfg(not(feature = "192"))]
458impl_split_all! {
459 (
460 _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
461 _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32,
462 _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48,
463 _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64,
464 _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,
465 _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96,
466 _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112,
467 _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128,
468 _129, _130, _131, _132, _133, _134, _135, _136, _137, _138, _139, _140, _141, _142, _143, _144,
469 _145, _146, _147, _148, _149, _150, _151, _152, _153, _154, _155, _156, _157, _158, _159, _160
470 )
471}
472
473#[cfg(feature = "192")]
474#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
475#[cfg(not(feature = "224"))]
476impl_split_all! {
477 (
478 _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
479 _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32,
480 _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48,
481 _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64,
482 _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,
483 _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96,
484 _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112,
485 _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128,
486 _129, _130, _131, _132, _133, _134, _135, _136, _137, _138, _139, _140, _141, _142, _143, _144,
487 _145, _146, _147, _148, _149, _150, _151, _152, _153, _154, _155, _156, _157, _158, _159, _160,
488 _161, _162, _163, _164, _165, _166, _167, _168, _169, _170, _171, _172, _173, _174, _175, _176,
489 _177, _178, _179, _180, _181, _182, _183, _184, _185, _186, _187, _188, _189, _190, _191, _192
490 )
491}
492
493#[cfg(feature = "224")]
494#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
495#[cfg(not(feature = "256"))]
496impl_split_all! {
497 (
498 _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
499 _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32,
500 _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48,
501 _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64,
502 _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,
503 _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96,
504 _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112,
505 _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128,
506 _129, _130, _131, _132, _133, _134, _135, _136, _137, _138, _139, _140, _141, _142, _143, _144,
507 _145, _146, _147, _148, _149, _150, _151, _152, _153, _154, _155, _156, _157, _158, _159, _160,
508 _161, _162, _163, _164, _165, _166, _167, _168, _169, _170, _171, _172, _173, _174, _175, _176,
509 _177, _178, _179, _180, _181, _182, _183, _184, _185, _186, _187, _188, _189, _190, _191, _192,
510 _193, _194, _195, _196, _197, _198, _199, _200, _201, _202, _203, _204, _205, _206, _207, _208,
511 _209, _210, _211, _212, _213, _214, _215, _216, _217, _218, _219, _220, _221, _222, _223, _224
512 )
513}
514
515#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
516#[cfg(feature = "256")]
517impl_split_all! {
518 (
519 _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
520 _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32,
521 _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48,
522 _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64,
523 _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,
524 _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96,
525 _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112,
526 _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128,
527 _129, _130, _131, _132, _133, _134, _135, _136, _137, _138, _139, _140, _141, _142, _143, _144,
528 _145, _146, _147, _148, _149, _150, _151, _152, _153, _154, _155, _156, _157, _158, _159, _160,
529 _161, _162, _163, _164, _165, _166, _167, _168, _169, _170, _171, _172, _173, _174, _175, _176,
530 _177, _178, _179, _180, _181, _182, _183, _184, _185, _186, _187, _188, _189, _190, _191, _192,
531 _193, _194, _195, _196, _197, _198, _199, _200, _201, _202, _203, _204, _205, _206, _207, _208,
532 _209, _210, _211, _212, _213, _214, _215, _216, _217, _218, _219, _220, _221, _222, _223, _224,
533 _225, _226, _227, _228, _229, _230, _231, _232, _233, _234, _235, _236, _237, _238, _239, _240,
534 _241, _242, _243, _244, _245, _246, _247, _248, _249, _250, _251, _252, _253, _254, _255, _256
535 )
536}
537
538#[cfg(test)]
539mod tests
540{
541 use crate as tuple_split;
542
543 #[test]
544 fn test_split_concat()
545 {
546 let t: (u8, f32, &str) = (1, 1.0, "test");
547
548 let (l, r) = tuple_split::split_tuple_at::<0, _>(t);
549 assert_eq!(t, tupleops::concat_tuples(l, r));
550
551 let (l, r) = tuple_split::split_tuple_at::<1, _>(t);
552 assert_eq!(t, tupleops::concat_tuples(l, r));
553
554 let (l, r) = tuple_split::split_tuple_at::<2, _>(t);
555 assert_eq!(t, tupleops::concat_tuples(l, r));
556
557 let (l, r) = tuple_split::split_tuple_at::<3, _>(t);
558 assert_eq!(t, tupleops::concat_tuples(l, r));
559 }
560
561 #[cfg(feature = "8")]
562 #[test]
563 fn test()
564 {
565 let t = (1u8, 2u16, 3u32, 4u64, 5u128);
566
567 let (l1, r1) = tuple_split::split_tuple_into_left::<(u8, u16), _>(t);
568 let (l2, r2) = tuple_split::split_tuple_into_right::<(u32, u64, u128), _>(t);
569 let (l3, r3) = tuple_split::split_tuple_at::<2, _>(t);
570
571 assert_eq!(l1, l2);
572 assert_eq!(l2, l3);
573
574 assert_eq!(r1, r2);
575 assert_eq!(r2, r3);
576
577 assert_eq!(t, tupleops::concat_tuples(l1, r1));
578 assert_eq!(t, tupleops::concat_tuples(l2, r2));
579 assert_eq!(t, tupleops::concat_tuples(l3, r3));
580 }
581}
582
583