v/vlib/v/tests/generics_test.v

280 lines
4.3 KiB
V

fn test_todo() {
}
fn simple<T>(p T) T {
return p
}
fn plus<T>(xxx T, b T) T {
// x := a
// y := b
// ww := ww
// q := xx + 1
return xxx + b
}
fn test_generic_fn() {
assert simple<int>(1) == 1
assert simple<int>(1 + 0) == 1
assert simple<string>('g') == 'g'
assert simple<string>('g') + 'h' == 'gh'
a := plus<int>(2, 3)
println(a)
assert a == 5
assert plus<int>(10, 1) == 11
assert plus<string>('a', 'b') == 'ab'
}
fn sum<T>(l []T) T {
mut r := T(0)
for e in l {
r += e
}
return r
}
fn test_foo() {
b := [1, 2, 3]
assert sum<int>(b) == 6
}
fn create<T>() {
a := T{}
println(a.name)
mut xx := T{}
xx.name = 'foo'
println(xx.name)
assert xx.name == 'foo'
xx.init()
}
struct User {
mut:
name string
}
struct City {
mut:
name string
}
fn (u User) init() {
}
fn (c City) init() {
}
fn mut_arg<T>(mut x T) {
println(x.name) // = 'foo'
}
fn mut_arg2<T>(mut x T) T {
println(x.name) // = 'foo'
return *x
}
fn test_create() {
create<User>()
create<City>()
mut u := User{}
mut_arg<User>(mut u)
mut_arg2<User>(mut u)
}
fn return_array<T>(arr []T) []T {
return arr
}
fn test_return_array() {
a1 := return_array<int>([1, 2, 3])
assert a1 == [1, 2, 3]
a2 := return_array<f64>([1.1, 2.2, 3.3])
assert a2 == [1.1, 2.2, 3.3]
a3 := return_array<string>(['a', 'b', 'c'])
assert a3 == ['a', 'b', 'c']
a4 := return_array<bool>([true, false, true])
assert a4 == [true, false, true]
}
/*
fn map_f<T,U>(l []T, f fn(T)U) []U {
mut r := []U{}
for e in l {
r << f(e)
}
return r
}
fn foldl<T>(l []T, nil T, f fn(T,T)T) T {
mut r := nil
for e in l {
r = f(r, e)
}
return r
}
fn square(x int) int {
return x*x
}
fn mul_int(x int, y int) int {
return x*y
}
fn assert_eq<T>(a, b T) {
r := a == b
println('$a == $b: ${r.str()}')
assert r
}
fn print_nice<T>(x T, indent int) {
mut space := ''
for _ in 0..indent {
space = space + ' '
}
println('$space$x')
}
fn test_generic_fn() {
assert_eq(simple(0+1), 1)
assert_eq(simple('g') + 'h', 'gh')
assert_eq(sum([5.1,6.2,7.0]), 18.3)
assert_eq(plus(i64(4), i64(6)), i64(10))
a := [1,2,3,4]
b := map_f(a, square)
assert_eq(sum(b), 30) // 1+4+9+16 = 30
assert_eq(foldl(b, 1, mul_int), 576) // 1*4*9*16 = 576
print_nice('str', 8)
}
struct Point {
mut:
x f64
y f64
}
fn (mut p Point) translate<T>(x, y T) {
p.x += x
p.y += y
}
fn test_generic_method() {
mut p := Point{}
p.translate(2, 1.0)
assert p.x == 2.0 && p.y == 1.0
}
fn get_values<T>(i T) []T {
return [i]
}
fn test_generic_fn_in_for_in_expression() {
for value in get_values(1) {
assert value == 1
}
for i, val in get_values(0) {
assert i == val
}
for value in get_values('a') {
assert value == 'a'
}
}
*/
// test generic struct
struct DB {
driver string
}
struct Group {
pub mut:
name string
group_name string
}
struct Permission {
pub mut:
name string
}
struct Repo<T, U> {
db DB
pub mut:
model T
permission U
}
// TODO: multiple type generic struct needs fixing in return for fn
// fn new_repo<T>(db DB) Repo<T,U> {
// return Repo<T,Permission>{db: db}
// }
fn test_generic_struct() {
mut a := Repo<User, Permission>{
model: User{
name: 'joe'
}
}
// a.model.name = 'joe'
assert a.model.name == 'joe'
println('a.model.name: $a.model.name')
mut b := Repo<Group, Permission>{
permission: Permission{
name: 'superuser'
}
}
b.model.name = 'admins'
assert b.model.name == 'admins'
assert b.permission.name == 'superuser'
println('b.model.name: $b.model.name')
println('b.permission.name: $b.permission.name')
assert typeof(a.model) == 'User'
assert typeof(b.model) == 'Group'
println('typeof(a.model): ' + typeof(a.model))
println('typeof(b.model): ' + typeof(b.model))
// mut x := new_repo<User>(DB{})
// x.model.name = 'joe2'
// println(x.model.name)
}
struct Foo<T> {
pub:
data T
}
fn (f Foo<int>) value() string {
return f.data.str()
}
fn test_generic_struct_method() {
foo_int := Foo<int>{2}
assert foo_int.value() == '2'
}
/*
struct Abc{ x int y int z int }
fn p<T>(args ...T) {
size:=sizeof(T)
print('p called with size: ${size:3d} | ')
for _,x in args {
print(x)
print(' ')
}
println('')
assert true
}
fn test_generic_fn_with_variadics(){
s:='abc'
i:=1
abc:=Abc{1,2,3}
// these calls should all compile, and print the arguments,
// even though the arguments are all a different type and arity:
p(s)
p(i)
p(abc)
p('Good', 'morning', 'world')
}
*/