Skip to content

Instantly share code, notes, and snippets.

@SeokminHong
Last active October 1, 2021 08:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SeokminHong/285606144d905655d243341f9ba9e212 to your computer and use it in GitHub Desktop.
Save SeokminHong/285606144d905655d243341f9ba9e212 to your computer and use it in GitHub Desktop.
use std::marker::PhantomData;
struct True {}
struct False {}
trait Boolean {
type Out;
}
struct BoolOp<T1, T2> {
t: PhantomData<(T1, T2)>,
}
trait AndTrait {
type Out;
}
impl AndTrait for BoolOp<True, True> {
type Out = True;
}
impl AndTrait for BoolOp<True, False> {
type Out = False;
}
impl AndTrait for BoolOp<False, True> {
type Out = False;
}
impl AndTrait for BoolOp<False, False> {
type Out = False;
}
struct Ty1 {}
struct Ty2 {}
impl Boolean for Ty1 {
type Out = True;
}
impl Boolean for Ty2 {
type Out = False;
}
trait TestHelperTrait {
type ReturnType;
fn test_impl() -> Self::ReturnType;
}
struct TestHelper<AndValue> {
x: PhantomData<AndValue>,
}
impl TestHelperTrait for TestHelper<True> {
type ReturnType = i32;
fn test_impl() -> Self::ReturnType {
3
}
}
impl TestHelperTrait for TestHelper<False> {
type ReturnType = &'static str;
fn test_impl() -> Self::ReturnType {
"5!"
}
}
struct Test<A: Boolean, B: Boolean> {
x: PhantomData<(A, B)>,
}
type And<A, B> = <BoolOp<<A as Boolean>::Out, <B as Boolean>::Out> as AndTrait>::Out;
type ReturnType<A, B> = <TestHelper<And<A, B>> as TestHelperTrait>::ReturnType;
impl<A: Boolean, B: Boolean> Test<A, B> {
fn test() -> ReturnType<A, B>
where
BoolOp<A::Out, B::Out>: AndTrait,
TestHelper<And<A, B>>: TestHelperTrait,
{
<TestHelper<And<A, B>> as TestHelperTrait>::test_impl()
}
}
fn main() {
let v1 = Test::<Ty1, Ty1>::test();
let v2 = Test::<Ty1, Ty2>::test();
let v3 = Test::<Ty2, Ty1>::test();
let v4 = Test::<Ty2, Ty2>::test();
println!("{} {} {} {}", v1, v2, v3, v4);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment