struct Calc[S] {
mut:
	typ S
}

struct TypeA {}

struct TypeB {}

fn (mut c Calc[S]) next[T](input T) f64 {
	$if S is TypeA || S is TypeB {
		return c.typ.next(input)
	} $else {
		return 99.0
	}
}

fn (mut t TypeA) next[T](input T) f64 {
	return 10
}

fn (mut t TypeB) next[T](input T) f64 {
	return 11
}

fn new[S]() Calc[S] {
	$if S is TypeA {
		return Calc[TypeA]{
			typ: TypeA{}
		}
	} $else $if S is TypeB {
		return Calc[TypeB]{
			typ: TypeB{}
		}
	} $else {
		panic('unknown type ${S.name}')
	}
}

fn main() {
	{
		mut c := Calc[TypeA]{
			typ: TypeA{}
		}
		assert c.next(100) == 10.0
	}
	{
		mut c := Calc[TypeB]{
			typ: TypeB{}
		}
		assert c.next(100) == 11.0
	}
	println('OK!!')
}
