package glm

data class MutableVec2(var x: Float, var y: Float) {
    // Initializes each element by evaluating init from 0 until 1
    constructor(init: (Int) -> Float) : this(init(0), init(1))
    
    operator fun get(idx: Int): Float = when (idx) {
        0 -> x
        1 -> y
        else -> throw IndexOutOfBoundsException("index $idx is out of bounds")
    }
    
    operator fun set(idx: Int, value: Float) = when (idx) {
        0 -> x = value
        1 -> y = value
        else -> throw IndexOutOfBoundsException("index $idx is out of bounds")
    }
    
    // Operators
    operator fun inc(): MutableVec2 = MutableVec2(x.inc(), y.inc())
    operator fun dec(): MutableVec2 = MutableVec2(x.dec(), y.dec())
    operator fun unaryPlus(): MutableVec2 = MutableVec2(+x, +y)
    operator fun unaryMinus(): MutableVec2 = MutableVec2(-x, -y)
    operator fun plus(rhs: MutableVec2): MutableVec2 = MutableVec2(x + rhs.x, y + rhs.y)
    operator fun minus(rhs: MutableVec2): MutableVec2 = MutableVec2(x - rhs.x, y - rhs.y)
    operator fun times(rhs: MutableVec2): MutableVec2 = MutableVec2(x * rhs.x, y * rhs.y)
    operator fun div(rhs: MutableVec2): MutableVec2 = MutableVec2(x / rhs.x, y / rhs.y)
    operator fun rem(rhs: MutableVec2): MutableVec2 = MutableVec2(x % rhs.x, y % rhs.y)
    operator fun plus(rhs: Float): MutableVec2 = MutableVec2(x + rhs, y + rhs)
    operator fun minus(rhs: Float): MutableVec2 = MutableVec2(x - rhs, y - rhs)
    operator fun times(rhs: Float): MutableVec2 = MutableVec2(x * rhs, y * rhs)
    operator fun div(rhs: Float): MutableVec2 = MutableVec2(x / rhs, y / rhs)
    operator fun rem(rhs: Float): MutableVec2 = MutableVec2(x % rhs, y % rhs)
    
    inline fun map(func: (Float) -> Float): MutableVec2 = MutableVec2(func(x), func(y))
    
    fun toList(): List<Float> = listOf(x, y)
    
    // Predefined vector constants
    companion object Constants {
        val zero: MutableVec2 get() = MutableVec2(0f, 0f)
        val ones: MutableVec2 get() = MutableVec2(1f, 1f)
        val unitX: MutableVec2 get() = MutableVec2(1f, 0f)
        val unitY: MutableVec2 get() = MutableVec2(0f, 1f)
    }
    
    // Conversions to Float
    fun toVec(): Vec2 = Vec2(x, y)
    inline fun toVec(conv: (Float) -> Float): Vec2 = Vec2(conv(x), conv(y))
    fun toVec2(): Vec2 = Vec2(x, y)
    inline fun toVec2(conv: (Float) -> Float): Vec2 = Vec2(conv(x), conv(y))
    fun toVec3(z: Float = 0f): Vec3 = Vec3(x, y, z)
    inline fun toVec3(z: Float = 0f, conv: (Float) -> Float): Vec3 = Vec3(conv(x), conv(y), z)
    fun toVec4(z: Float = 0f, w: Float = 0f): Vec4 = Vec4(x, y, z, w)
    inline fun toVec4(z: Float = 0f, w: Float = 0f, conv: (Float) -> Float): Vec4 = Vec4(conv(x), conv(y), z, w)
    
    // Conversions to Float
    fun toMutableVec(): MutableVec2 = MutableVec2(x, y)
    inline fun toMutableVec(conv: (Float) -> Float): MutableVec2 = MutableVec2(conv(x), conv(y))
    fun toMutableVec2(): MutableVec2 = MutableVec2(x, y)
    inline fun toMutableVec2(conv: (Float) -> Float): MutableVec2 = MutableVec2(conv(x), conv(y))
    fun toMutableVec3(z: Float = 0f): MutableVec3 = MutableVec3(x, y, z)
    inline fun toMutableVec3(z: Float = 0f, conv: (Float) -> Float): MutableVec3 = MutableVec3(conv(x), conv(y), z)
    fun toMutableVec4(z: Float = 0f, w: Float = 0f): MutableVec4 = MutableVec4(x, y, z, w)
    inline fun toMutableVec4(z: Float = 0f, w: Float = 0f, conv: (Float) -> Float): MutableVec4 = MutableVec4(conv(x), conv(y), z, w)
    
    // Conversions to Double
    fun toDoubleVec(): DoubleVec2 = DoubleVec2(x.toDouble(), y.toDouble())
    inline fun toDoubleVec(conv: (Float) -> Double): DoubleVec2 = DoubleVec2(conv(x), conv(y))
    fun toDoubleVec2(): DoubleVec2 = DoubleVec2(x.toDouble(), y.toDouble())
    inline fun toDoubleVec2(conv: (Float) -> Double): DoubleVec2 = DoubleVec2(conv(x), conv(y))
    fun toDoubleVec3(z: Double = 0.0): DoubleVec3 = DoubleVec3(x.toDouble(), y.toDouble(), z)
    inline fun toDoubleVec3(z: Double = 0.0, conv: (Float) -> Double): DoubleVec3 = DoubleVec3(conv(x), conv(y), z)
    fun toDoubleVec4(z: Double = 0.0, w: Double = 0.0): DoubleVec4 = DoubleVec4(x.toDouble(), y.toDouble(), z, w)
    inline fun toDoubleVec4(z: Double = 0.0, w: Double = 0.0, conv: (Float) -> Double): DoubleVec4 = DoubleVec4(conv(x), conv(y), z, w)
    
    // Conversions to Double
    fun toMutableDoubleVec(): MutableDoubleVec2 = MutableDoubleVec2(x.toDouble(), y.toDouble())
    inline fun toMutableDoubleVec(conv: (Float) -> Double): MutableDoubleVec2 = MutableDoubleVec2(conv(x), conv(y))
    fun toMutableDoubleVec2(): MutableDoubleVec2 = MutableDoubleVec2(x.toDouble(), y.toDouble())
    inline fun toMutableDoubleVec2(conv: (Float) -> Double): MutableDoubleVec2 = MutableDoubleVec2(conv(x), conv(y))
    fun toMutableDoubleVec3(z: Double = 0.0): MutableDoubleVec3 = MutableDoubleVec3(x.toDouble(), y.toDouble(), z)
    inline fun toMutableDoubleVec3(z: Double = 0.0, conv: (Float) -> Double): MutableDoubleVec3 = MutableDoubleVec3(conv(x), conv(y), z)
    fun toMutableDoubleVec4(z: Double = 0.0, w: Double = 0.0): MutableDoubleVec4 = MutableDoubleVec4(x.toDouble(), y.toDouble(), z, w)
    inline fun toMutableDoubleVec4(z: Double = 0.0, w: Double = 0.0, conv: (Float) -> Double): MutableDoubleVec4 = MutableDoubleVec4(conv(x), conv(y), z, w)
    
    // Conversions to Int
    fun toIntVec(): IntVec2 = IntVec2(x.toInt(), y.toInt())
    inline fun toIntVec(conv: (Float) -> Int): IntVec2 = IntVec2(conv(x), conv(y))
    fun toIntVec2(): IntVec2 = IntVec2(x.toInt(), y.toInt())
    inline fun toIntVec2(conv: (Float) -> Int): IntVec2 = IntVec2(conv(x), conv(y))
    fun toIntVec3(z: Int = 0): IntVec3 = IntVec3(x.toInt(), y.toInt(), z)
    inline fun toIntVec3(z: Int = 0, conv: (Float) -> Int): IntVec3 = IntVec3(conv(x), conv(y), z)
    fun toIntVec4(z: Int = 0, w: Int = 0): IntVec4 = IntVec4(x.toInt(), y.toInt(), z, w)
    inline fun toIntVec4(z: Int = 0, w: Int = 0, conv: (Float) -> Int): IntVec4 = IntVec4(conv(x), conv(y), z, w)
    
    // Conversions to Int
    fun toMutableIntVec(): MutableIntVec2 = MutableIntVec2(x.toInt(), y.toInt())
    inline fun toMutableIntVec(conv: (Float) -> Int): MutableIntVec2 = MutableIntVec2(conv(x), conv(y))
    fun toMutableIntVec2(): MutableIntVec2 = MutableIntVec2(x.toInt(), y.toInt())
    inline fun toMutableIntVec2(conv: (Float) -> Int): MutableIntVec2 = MutableIntVec2(conv(x), conv(y))
    fun toMutableIntVec3(z: Int = 0): MutableIntVec3 = MutableIntVec3(x.toInt(), y.toInt(), z)
    inline fun toMutableIntVec3(z: Int = 0, conv: (Float) -> Int): MutableIntVec3 = MutableIntVec3(conv(x), conv(y), z)
    fun toMutableIntVec4(z: Int = 0, w: Int = 0): MutableIntVec4 = MutableIntVec4(x.toInt(), y.toInt(), z, w)
    inline fun toMutableIntVec4(z: Int = 0, w: Int = 0, conv: (Float) -> Int): MutableIntVec4 = MutableIntVec4(conv(x), conv(y), z, w)
    
    // Conversions to Long
    fun toLongVec(): LongVec2 = LongVec2(x.toLong(), y.toLong())
    inline fun toLongVec(conv: (Float) -> Long): LongVec2 = LongVec2(conv(x), conv(y))
    fun toLongVec2(): LongVec2 = LongVec2(x.toLong(), y.toLong())
    inline fun toLongVec2(conv: (Float) -> Long): LongVec2 = LongVec2(conv(x), conv(y))
    fun toLongVec3(z: Long = 0L): LongVec3 = LongVec3(x.toLong(), y.toLong(), z)
    inline fun toLongVec3(z: Long = 0L, conv: (Float) -> Long): LongVec3 = LongVec3(conv(x), conv(y), z)
    fun toLongVec4(z: Long = 0L, w: Long = 0L): LongVec4 = LongVec4(x.toLong(), y.toLong(), z, w)
    inline fun toLongVec4(z: Long = 0L, w: Long = 0L, conv: (Float) -> Long): LongVec4 = LongVec4(conv(x), conv(y), z, w)
    
    // Conversions to Long
    fun toMutableLongVec(): MutableLongVec2 = MutableLongVec2(x.toLong(), y.toLong())
    inline fun toMutableLongVec(conv: (Float) -> Long): MutableLongVec2 = MutableLongVec2(conv(x), conv(y))
    fun toMutableLongVec2(): MutableLongVec2 = MutableLongVec2(x.toLong(), y.toLong())
    inline fun toMutableLongVec2(conv: (Float) -> Long): MutableLongVec2 = MutableLongVec2(conv(x), conv(y))
    fun toMutableLongVec3(z: Long = 0L): MutableLongVec3 = MutableLongVec3(x.toLong(), y.toLong(), z)
    inline fun toMutableLongVec3(z: Long = 0L, conv: (Float) -> Long): MutableLongVec3 = MutableLongVec3(conv(x), conv(y), z)
    fun toMutableLongVec4(z: Long = 0L, w: Long = 0L): MutableLongVec4 = MutableLongVec4(x.toLong(), y.toLong(), z, w)
    inline fun toMutableLongVec4(z: Long = 0L, w: Long = 0L, conv: (Float) -> Long): MutableLongVec4 = MutableLongVec4(conv(x), conv(y), z, w)
    
    // Conversions to Short
    fun toShortVec(): ShortVec2 = ShortVec2(x.toShort(), y.toShort())
    inline fun toShortVec(conv: (Float) -> Short): ShortVec2 = ShortVec2(conv(x), conv(y))
    fun toShortVec2(): ShortVec2 = ShortVec2(x.toShort(), y.toShort())
    inline fun toShortVec2(conv: (Float) -> Short): ShortVec2 = ShortVec2(conv(x), conv(y))
    fun toShortVec3(z: Short = 0.toShort()): ShortVec3 = ShortVec3(x.toShort(), y.toShort(), z)
    inline fun toShortVec3(z: Short = 0.toShort(), conv: (Float) -> Short): ShortVec3 = ShortVec3(conv(x), conv(y), z)
    fun toShortVec4(z: Short = 0.toShort(), w: Short = 0.toShort()): ShortVec4 = ShortVec4(x.toShort(), y.toShort(), z, w)
    inline fun toShortVec4(z: Short = 0.toShort(), w: Short = 0.toShort(), conv: (Float) -> Short): ShortVec4 = ShortVec4(conv(x), conv(y), z, w)
    
    // Conversions to Short
    fun toMutableShortVec(): MutableShortVec2 = MutableShortVec2(x.toShort(), y.toShort())
    inline fun toMutableShortVec(conv: (Float) -> Short): MutableShortVec2 = MutableShortVec2(conv(x), conv(y))
    fun toMutableShortVec2(): MutableShortVec2 = MutableShortVec2(x.toShort(), y.toShort())
    inline fun toMutableShortVec2(conv: (Float) -> Short): MutableShortVec2 = MutableShortVec2(conv(x), conv(y))
    fun toMutableShortVec3(z: Short = 0.toShort()): MutableShortVec3 = MutableShortVec3(x.toShort(), y.toShort(), z)
    inline fun toMutableShortVec3(z: Short = 0.toShort(), conv: (Float) -> Short): MutableShortVec3 = MutableShortVec3(conv(x), conv(y), z)
    fun toMutableShortVec4(z: Short = 0.toShort(), w: Short = 0.toShort()): MutableShortVec4 = MutableShortVec4(x.toShort(), y.toShort(), z, w)
    inline fun toMutableShortVec4(z: Short = 0.toShort(), w: Short = 0.toShort(), conv: (Float) -> Short): MutableShortVec4 = MutableShortVec4(conv(x), conv(y), z, w)
    
    // Conversions to Byte
    fun toByteVec(): ByteVec2 = ByteVec2(x.toByte(), y.toByte())
    inline fun toByteVec(conv: (Float) -> Byte): ByteVec2 = ByteVec2(conv(x), conv(y))
    fun toByteVec2(): ByteVec2 = ByteVec2(x.toByte(), y.toByte())
    inline fun toByteVec2(conv: (Float) -> Byte): ByteVec2 = ByteVec2(conv(x), conv(y))
    fun toByteVec3(z: Byte = 0.toByte()): ByteVec3 = ByteVec3(x.toByte(), y.toByte(), z)
    inline fun toByteVec3(z: Byte = 0.toByte(), conv: (Float) -> Byte): ByteVec3 = ByteVec3(conv(x), conv(y), z)
    fun toByteVec4(z: Byte = 0.toByte(), w: Byte = 0.toByte()): ByteVec4 = ByteVec4(x.toByte(), y.toByte(), z, w)
    inline fun toByteVec4(z: Byte = 0.toByte(), w: Byte = 0.toByte(), conv: (Float) -> Byte): ByteVec4 = ByteVec4(conv(x), conv(y), z, w)
    
    // Conversions to Byte
    fun toMutableByteVec(): MutableByteVec2 = MutableByteVec2(x.toByte(), y.toByte())
    inline fun toMutableByteVec(conv: (Float) -> Byte): MutableByteVec2 = MutableByteVec2(conv(x), conv(y))
    fun toMutableByteVec2(): MutableByteVec2 = MutableByteVec2(x.toByte(), y.toByte())
    inline fun toMutableByteVec2(conv: (Float) -> Byte): MutableByteVec2 = MutableByteVec2(conv(x), conv(y))
    fun toMutableByteVec3(z: Byte = 0.toByte()): MutableByteVec3 = MutableByteVec3(x.toByte(), y.toByte(), z)
    inline fun toMutableByteVec3(z: Byte = 0.toByte(), conv: (Float) -> Byte): MutableByteVec3 = MutableByteVec3(conv(x), conv(y), z)
    fun toMutableByteVec4(z: Byte = 0.toByte(), w: Byte = 0.toByte()): MutableByteVec4 = MutableByteVec4(x.toByte(), y.toByte(), z, w)
    inline fun toMutableByteVec4(z: Byte = 0.toByte(), w: Byte = 0.toByte(), conv: (Float) -> Byte): MutableByteVec4 = MutableByteVec4(conv(x), conv(y), z, w)
    
    // Conversions to Char
    fun toCharVec(): CharVec2 = CharVec2(x.toChar(), y.toChar())
    inline fun toCharVec(conv: (Float) -> Char): CharVec2 = CharVec2(conv(x), conv(y))
    fun toCharVec2(): CharVec2 = CharVec2(x.toChar(), y.toChar())
    inline fun toCharVec2(conv: (Float) -> Char): CharVec2 = CharVec2(conv(x), conv(y))
    fun toCharVec3(z: Char): CharVec3 = CharVec3(x.toChar(), y.toChar(), z)
    inline fun toCharVec3(z: Char, conv: (Float) -> Char): CharVec3 = CharVec3(conv(x), conv(y), z)
    fun toCharVec4(z: Char, w: Char): CharVec4 = CharVec4(x.toChar(), y.toChar(), z, w)
    inline fun toCharVec4(z: Char, w: Char, conv: (Float) -> Char): CharVec4 = CharVec4(conv(x), conv(y), z, w)
    
    // Conversions to Char
    fun toMutableCharVec(): MutableCharVec2 = MutableCharVec2(x.toChar(), y.toChar())
    inline fun toMutableCharVec(conv: (Float) -> Char): MutableCharVec2 = MutableCharVec2(conv(x), conv(y))
    fun toMutableCharVec2(): MutableCharVec2 = MutableCharVec2(x.toChar(), y.toChar())
    inline fun toMutableCharVec2(conv: (Float) -> Char): MutableCharVec2 = MutableCharVec2(conv(x), conv(y))
    fun toMutableCharVec3(z: Char): MutableCharVec3 = MutableCharVec3(x.toChar(), y.toChar(), z)
    inline fun toMutableCharVec3(z: Char, conv: (Float) -> Char): MutableCharVec3 = MutableCharVec3(conv(x), conv(y), z)
    fun toMutableCharVec4(z: Char, w: Char): MutableCharVec4 = MutableCharVec4(x.toChar(), y.toChar(), z, w)
    inline fun toMutableCharVec4(z: Char, w: Char, conv: (Float) -> Char): MutableCharVec4 = MutableCharVec4(conv(x), conv(y), z, w)
    
    // Conversions to Boolean
    fun toBoolVec(): BoolVec2 = BoolVec2(x != 0f, y != 0f)
    inline fun toBoolVec(conv: (Float) -> Boolean): BoolVec2 = BoolVec2(conv(x), conv(y))
    fun toBoolVec2(): BoolVec2 = BoolVec2(x != 0f, y != 0f)
    inline fun toBoolVec2(conv: (Float) -> Boolean): BoolVec2 = BoolVec2(conv(x), conv(y))
    fun toBoolVec3(z: Boolean = false): BoolVec3 = BoolVec3(x != 0f, y != 0f, z)
    inline fun toBoolVec3(z: Boolean = false, conv: (Float) -> Boolean): BoolVec3 = BoolVec3(conv(x), conv(y), z)
    fun toBoolVec4(z: Boolean = false, w: Boolean = false): BoolVec4 = BoolVec4(x != 0f, y != 0f, z, w)
    inline fun toBoolVec4(z: Boolean = false, w: Boolean = false, conv: (Float) -> Boolean): BoolVec4 = BoolVec4(conv(x), conv(y), z, w)
    
    // Conversions to Boolean
    fun toMutableBoolVec(): MutableBoolVec2 = MutableBoolVec2(x != 0f, y != 0f)
    inline fun toMutableBoolVec(conv: (Float) -> Boolean): MutableBoolVec2 = MutableBoolVec2(conv(x), conv(y))
    fun toMutableBoolVec2(): MutableBoolVec2 = MutableBoolVec2(x != 0f, y != 0f)
    inline fun toMutableBoolVec2(conv: (Float) -> Boolean): MutableBoolVec2 = MutableBoolVec2(conv(x), conv(y))
    fun toMutableBoolVec3(z: Boolean = false): MutableBoolVec3 = MutableBoolVec3(x != 0f, y != 0f, z)
    inline fun toMutableBoolVec3(z: Boolean = false, conv: (Float) -> Boolean): MutableBoolVec3 = MutableBoolVec3(conv(x), conv(y), z)
    fun toMutableBoolVec4(z: Boolean = false, w: Boolean = false): MutableBoolVec4 = MutableBoolVec4(x != 0f, y != 0f, z, w)
    inline fun toMutableBoolVec4(z: Boolean = false, w: Boolean = false, conv: (Float) -> Boolean): MutableBoolVec4 = MutableBoolVec4(conv(x), conv(y), z, w)
    
    // Conversions to String
    fun toStringVec(): StringVec2 = StringVec2(x.toString(), y.toString())
    inline fun toStringVec(conv: (Float) -> String): StringVec2 = StringVec2(conv(x), conv(y))
    fun toStringVec2(): StringVec2 = StringVec2(x.toString(), y.toString())
    inline fun toStringVec2(conv: (Float) -> String): StringVec2 = StringVec2(conv(x), conv(y))
    fun toStringVec3(z: String = ""): StringVec3 = StringVec3(x.toString(), y.toString(), z)
    inline fun toStringVec3(z: String = "", conv: (Float) -> String): StringVec3 = StringVec3(conv(x), conv(y), z)
    fun toStringVec4(z: String = "", w: String = ""): StringVec4 = StringVec4(x.toString(), y.toString(), z, w)
    inline fun toStringVec4(z: String = "", w: String = "", conv: (Float) -> String): StringVec4 = StringVec4(conv(x), conv(y), z, w)
    
    // Conversions to String
    fun toMutableStringVec(): MutableStringVec2 = MutableStringVec2(x.toString(), y.toString())
    inline fun toMutableStringVec(conv: (Float) -> String): MutableStringVec2 = MutableStringVec2(conv(x), conv(y))
    fun toMutableStringVec2(): MutableStringVec2 = MutableStringVec2(x.toString(), y.toString())
    inline fun toMutableStringVec2(conv: (Float) -> String): MutableStringVec2 = MutableStringVec2(conv(x), conv(y))
    fun toMutableStringVec3(z: String = ""): MutableStringVec3 = MutableStringVec3(x.toString(), y.toString(), z)
    inline fun toMutableStringVec3(z: String = "", conv: (Float) -> String): MutableStringVec3 = MutableStringVec3(conv(x), conv(y), z)
    fun toMutableStringVec4(z: String = "", w: String = ""): MutableStringVec4 = MutableStringVec4(x.toString(), y.toString(), z, w)
    inline fun toMutableStringVec4(z: String = "", w: String = "", conv: (Float) -> String): MutableStringVec4 = MutableStringVec4(conv(x), conv(y), z, w)
    
    // Conversions to T2
    inline fun <T2> toTVec(conv: (Float) -> T2): TVec2<T2> = TVec2<T2>(conv(x), conv(y))
    inline fun <T2> toTVec2(conv: (Float) -> T2): TVec2<T2> = TVec2<T2>(conv(x), conv(y))
    inline fun <T2> toTVec3(z: T2, conv: (Float) -> T2): TVec3<T2> = TVec3<T2>(conv(x), conv(y), z)
    inline fun <T2> toTVec4(z: T2, w: T2, conv: (Float) -> T2): TVec4<T2> = TVec4<T2>(conv(x), conv(y), z, w)
    
    // Conversions to T2
    inline fun <T2> toMutableTVec(conv: (Float) -> T2): MutableTVec2<T2> = MutableTVec2<T2>(conv(x), conv(y))
    inline fun <T2> toMutableTVec2(conv: (Float) -> T2): MutableTVec2<T2> = MutableTVec2<T2>(conv(x), conv(y))
    inline fun <T2> toMutableTVec3(z: T2, conv: (Float) -> T2): MutableTVec3<T2> = MutableTVec3<T2>(conv(x), conv(y), z)
    inline fun <T2> toMutableTVec4(z: T2, w: T2, conv: (Float) -> T2): MutableTVec4<T2> = MutableTVec4<T2>(conv(x), conv(y), z, w)
    
    // Allows for swizzling, e.g. v.swizzle.xzx
    inner class Swizzle {
        val xx: MutableVec2 get() = MutableVec2(x, x)
        var xy: MutableVec2
            get() = MutableVec2(x, y)
            set(value) {
                x = value.x
                y = value.y
            }
        var yx: MutableVec2
            get() = MutableVec2(y, x)
            set(value) {
                y = value.x
                x = value.y
            }
        val yy: MutableVec2 get() = MutableVec2(y, y)
        val xxx: MutableVec3 get() = MutableVec3(x, x, x)
        val xxy: MutableVec3 get() = MutableVec3(x, x, y)
        val xyx: MutableVec3 get() = MutableVec3(x, y, x)
        val xyy: MutableVec3 get() = MutableVec3(x, y, y)
        val yxx: MutableVec3 get() = MutableVec3(y, x, x)
        val yxy: MutableVec3 get() = MutableVec3(y, x, y)
        val yyx: MutableVec3 get() = MutableVec3(y, y, x)
        val yyy: MutableVec3 get() = MutableVec3(y, y, y)
        val xxxx: MutableVec4 get() = MutableVec4(x, x, x, x)
        val xxxy: MutableVec4 get() = MutableVec4(x, x, x, y)
        val xxyx: MutableVec4 get() = MutableVec4(x, x, y, x)
        val xxyy: MutableVec4 get() = MutableVec4(x, x, y, y)
        val xyxx: MutableVec4 get() = MutableVec4(x, y, x, x)
        val xyxy: MutableVec4 get() = MutableVec4(x, y, x, y)
        val xyyx: MutableVec4 get() = MutableVec4(x, y, y, x)
        val xyyy: MutableVec4 get() = MutableVec4(x, y, y, y)
        val yxxx: MutableVec4 get() = MutableVec4(y, x, x, x)
        val yxxy: MutableVec4 get() = MutableVec4(y, x, x, y)
        val yxyx: MutableVec4 get() = MutableVec4(y, x, y, x)
        val yxyy: MutableVec4 get() = MutableVec4(y, x, y, y)
        val yyxx: MutableVec4 get() = MutableVec4(y, y, x, x)
        val yyxy: MutableVec4 get() = MutableVec4(y, y, x, y)
        val yyyx: MutableVec4 get() = MutableVec4(y, y, y, x)
        val yyyy: MutableVec4 get() = MutableVec4(y, y, y, y)
    }
    
    val swizzle: Swizzle get() = Swizzle()
}

fun mutableVecOf(x: Float, y: Float): MutableVec2 = MutableVec2(x, y)

operator fun Float.plus(rhs: MutableVec2): MutableVec2 = MutableVec2(this + rhs.x, this + rhs.y)

operator fun Float.minus(rhs: MutableVec2): MutableVec2 = MutableVec2(this - rhs.x, this - rhs.y)

operator fun Float.times(rhs: MutableVec2): MutableVec2 = MutableVec2(this * rhs.x, this * rhs.y)

operator fun Float.div(rhs: MutableVec2): MutableVec2 = MutableVec2(this / rhs.x, this / rhs.y)

operator fun Float.rem(rhs: MutableVec2): MutableVec2 = MutableVec2(this % rhs.x, this % rhs.y)
