struct St {
mut:
	a int
}

struct Qr {
mut:
	a int
}

fn (mut r Qr) s_mut(mut s St) {
	r.a = 5
	s.a = 7
}

fn (r Qr) s_val(s St) int {
	return r.a * s.a
}

fn m_mut(mut a map[string]f64) {
	a['yxcv'] = -2.25
}

fn m_val(a map[string]f64) f64 {
	x := a['yxcv']
	return x
}

fn a_mut(mut a []int) {
	a[2] = 42
}

fn a_val(a []int) int {
	return a[1]
}

fn test_shared_as_value() {
	shared s := St{ a: 5 }
	shared a := [3, 4, 6, 13, -23]
	shared m := {'qw': 12.75, 'yxcv': -3.125, 'poiu': 88.0625}
	shared r := Qr{ a: 7 }
	lock s {
		u := r.s_val(s)
		println(u)
	}
	lock r {
		v := r.s_val(s)
		println(v)
	}
	w := m_val(m)
	x := a_val(a)
	println('$w $x')
}

fn test_shared_as_mut() {
	shared s := St{ a: 5 }
	shared a := [3, 4, 6, 13, -23]
	shared m := {'qw': 12.75, 'yxcv': -3.125, 'poiu': 88.0625}
	shared r := Qr{ a: 7 }
	lock s {
		r.s_mut(mut s)
	}
	lock r {
		r.s_mut(mut s)
	}
	m_mut(mut m)
	a_mut(mut a)
}

struct Ab {
	s shared St
}

fn main() {
	shared y := St{ a: 5 }
	println(y)
	println('$y')
	a := Ab{ s: St{ a: 3 } }
	println(a.s)
	println('$a.s')
}
