﻿:: {v:v, g:g, s:s, b:b, d:d, t:t, n:n, r8:r8, r4:r4, i:i, i8:i8, i4:i4, i2:i2, i1:i1, u8:u8, u4:u4, u2:u2, u1:u1}

ToU4(g)
ToU4(s)
ToU4(d)
ToU8(t)
ToU8(n)
ToU8(r8)
ToU8(r4)
ToU4(i)
ToU8(i8)
ToU4(i4)
ToU2(i2)
ToU1(i1)
ToU4(u8)
ToU2(u4)
ToU1(u2)

ToU4(v)
ToU1(b)
ToU8(d)
ToU8(u8)
ToU8(u4)
ToU4(u4)
ToU4(u2)
ToU2(u2)
ToU2(u1)
ToU1(u1)

:: {o:o, qb:b?, qd:d?, qt:t?, qn:n?, qr8:r8?, qr4:r4?, qi:i?, qi8:i8?, qi4:i4?, qi2:i2?, qi1:i1?, qu8:u8?, qu4:u4?, qu2:u2?, qu1:u1?}

ToU4(qd)
ToU8(qt)
ToU8(qn)
ToU8(qr8)
ToU8(qr4)
ToU8(qi)
ToU8(qi8)
ToU4(qi4)
ToU2(qi2)
ToU1(qi1)
ToU4(qu8)
ToU2(qu4)
ToU1(qu2)

ToU8(o)
ToU1(qb)
ToU8(qd)
ToU8(qu8)
ToU8(qu4)
ToU4(qu4)
ToU4(qu2)
ToU2(qu2)
ToU2(qu1)
ToU1(qu1)

:: {g:g, v:v, o:o, u2:u2, qu2:u2?, u4:u4, qu4:u4?, r4:r4, qr4:r4?, u8:u8, qu8:u8?}

ToU4(v)
ToU4(v, v)
ToU4(v, o)
ToU4(v, qu2)
ToU4(v, u2)

ToU4(u2)
ToU4(u2, v)
ToU4(u2, o)
ToU4(u2, qu2)
ToU4(u2, u2)

ToU4(u8)
ToU4(u8, v)
ToU4(u8, o)
ToU4(u8, qu2)
ToU4(u8, u2)

ToU4(o)
ToU4(o, v)
ToU4(o, o)
ToU4(o, qu2)
ToU4(o, u2)

ToU4(qu2)
ToU4(qu2, v)
ToU4(qu2, o)
ToU4(qu2, qu2)
ToU4(qu2, u2)

ToU4(qu8)
ToU4(qu8, v)
ToU4(qu8, o)
ToU4(qu8, qu2)
ToU4(qu8, u2)

To(g, qu4)
To(g, u4)

To(v, qu4)
To(v, u4)
To(r4, qu4)
To(r4, u4)

To(o, qu4)
To(o, u4)
To(qr4, qu4)
To(qr4, u4)

// Lifting.
:: {g:g*, v:v*, s:s*, b:b*, d:d*, t:t*, n:n*, r8:r8*, r4:r4*, i:i*, i8:i8*, i4:i4*, i2:i2*, i1:i1*, u8:u8*, u4:u4*, u2:u2*, u1:u1*}

ToU4(g)
ToU4(s)
ToU4(d)
ToU8(t)
ToU8(n)
ToU8(r8)
ToU8(r4)
ToU4(i)
ToU8(i8)
ToU4(i4)
ToU2(i2)
ToU1(i1)
ToU4(u8)
ToU2(u4)
ToU1(u2)

ToU4(v)
ToU1(b)
ToU8(d)
ToU8(u8)
ToU8(u4)
ToU4(u4)
ToU4(u2)
ToU2(u2)
ToU2(u1)
ToU1(u1)

:: {o:o*, qb:b?*, qd:d?*, qt:t?*, qn:n?*, qr8:r8?*, qr4:r4?*, qi:i?*, qi8:i8?*, qi4:i4?*, qi2:i2?*, qi1:i1?*, qu8:u8?*, qu4:u4?*, qu2:u2?*, qu1:u1?*}

ToU4(qd)
ToU8(qt)
ToU8(qn)
ToU8(qr8)
ToU8(qr4)
ToU8(qi)
ToU8(qi8)
ToU4(qi4)
ToU2(qi2)
ToU1(qi1)
ToU4(qu8)
ToU2(qu4)
ToU1(qu2)

ToU8(o)
ToU1(qb)
ToU8(qd)
ToU8(qu8)
ToU8(qu4)
ToU4(qu4)
ToU4(qu2)
ToU2(qu2)
ToU2(qu1)
ToU1(qu1)

// Invocation variations

ToU4(3.14)
ToU4(1/0)
ToU4(3.14, null)
ToU4(1/0,  null)
ToU4(3.14, Null(5u2))
ToU4(3.14, Opt (5u2))
ToU4(1/0,  Null(5u2))
ToU4(1/0,  Opt (5u2))
ToU4(3.14, 5u2)
ToU4(1/0,  5u2)

ToU4(Null(3.14))
ToU4(Opt (3.14))
ToU4(Opt (1/0 ))
ToU4(Null(3.14), null)
ToU4(Opt (3.14), null)
ToU4(Opt (1/0 ), null)
ToU4(Null(3.14), Null(5u2))
ToU4(Null(3.14), Opt (5u2))
ToU4(Opt (3.14), Null(5u2))
ToU4(Opt (3.14), Opt (5u2))
ToU4(Opt (1/0 ), Null(5u2))
ToU4(Opt (1/0 ), Opt (5u2))
ToU4(Null(3.14), 5u2)
ToU4(Opt (3.14), 5u2)
ToU4(Opt (1/0 ), 5u2)

To(3.14, Null(5u4))
To(3.14, Opt (5u4))
To(1/0,  Null(5u4))
To(1/0 , Opt (5u4))
To(3.14, 5u4)
To(1/0,  5u4)

To(Null(3.14), Null(5u4))
To(Null(3.14), Opt (5u4))
To(Opt (3.14), Null(5u4))
To(Opt (3.14), Opt (5u4))
To(Opt (1/0 ), Null(5u4))
To(Opt (1/0 ), Opt (5u4))
To(Null(3.14), 5u4)
To(Opt (3.14), 5u4)
To(Opt (1/0 ), 5u4)

// Integer boundaries

ToU1(false)
ToU1(true)

ToU1(-1)
ToU1(0)
ToU1(255)
ToU1(256)
To(-1, 5u1)

ToU2(-1)
ToU2(0)
ToU2(65535)
ToU2(65536)
To(0, 5u2)

ToU4(-1i8)
ToU4(0i8)
ToU4(4294967295i8)
ToU4(4294967296i8)
To(4294967295i8, 5u4)

ToU8(-1ia)
ToU8(0ia)
ToU8(18446744073709551615ia)
ToU8(18446744073709551616ia)
To(18446744073709551616ia, 5u8)

// Floating point

ToU4(-1/0)
ToU4(1/0)
ToU4(0/0)
To(-1/0, 1u4)
To(1/0, 2u4)
ToU4(0/0, 3u2)

// Floating-point boundaries

ToU1(-0x10000000000000 * 2.0 ^ -52)
ToU1(-0x1FFFFFFFFFFFFF * 2.0 ^ -53)
ToU1(ToR4(-0x7FFFFF    * 2.0 ^ -23))
ToU1(ToR4( 0xFFFFFF    * 2.0 ^ -16))
ToU1( 0x1FFFFFFFFFFFFF * 2.0 ^ -45)
ToU1( 0x10000000000000 * 2.0 ^ -44)

ToU2(-0x10000000000000 * 2.0 ^ -52)
ToU2(-0x1FFFFFFFFFFFFF * 2.0 ^ -53)
ToU2(ToR4(-0x7FFFFF    * 2.0 ^ -23))
ToU2(ToR4( 0xFFFFFF    * 2.0 ^ -8))
ToU2( 0x1FFFFFFFFFFFFF * 2.0 ^ -37)
ToU2( 0x10000000000000 * 2.0 ^ -36)

ToU4(-0x10000000000000 * 2.0 ^ -52)
ToU4(-0x1FFFFFFFFFFFFF * 2.0 ^ -53)
ToU4(ToR4(-0x7FFFFF    * 2.0 ^ -23))
ToU4(ToR4( 0xFFFFFF    * 2.0 ^ 8))
ToU4( 0x1FFFFFFFFFFFFF * 2.0 ^ -21)
ToU4( 0x10000000000000 * 2.0 ^ -20)

ToU8(-0x10000000000000 * 2.0 ^ -52)
ToU8(-0x1FFFFFFFFFFFFF * 2.0 ^ -53)
ToU8(ToR4(-0x7FFFFF    * 2.0 ^ -23))
ToU8(ToR4( 0xFFFFFF    * 2.0 ^ 40))
ToU8( 0x1FFFFFFFFFFFFF * 2.0 ^ 11)
ToU8( 0x10000000000000 * 2.0 ^ 12)

// String

ToU4("")
ToU4(" ")
To("", 1u2)
ToU4(" ", 2u2)

// Integer strings

ToU4("false")
ToU4("true")
To("false", 0u4)
ToU4("true", 1u2)

ToU4("1_234")
To("1_234", 5u4)

ToU4("-0")

// String boundaries

ToU1("-1 ")
ToU1("(0)")
ToU1("255")
ToU1("256")
To("-1", 5u1)

ToU2("(1)")
ToU2("-0 ")
ToU2("65535")
ToU2("65536")
To("0", 5u2)

ToU4("-1 ")
ToU4("(0)")
ToU4("4,294,967,295")
ToU4("4,294,967,296")
To("4294967295", 5u4)

ToU8("(1)")
ToU8(" 0 ")
ToU8("18,446,744,073,709,551,615")
ToU8("18,446,744,073,709,551,616")
To("18,446,744,073,709,551,616", 5u8)

// Fractional strings

ToU4("-0.0")
ToU4("12.34")
ToU4("2e20")
ToU4("∞")
ToU4("Infinity")
ToU4("NaN")
To("-0.0", 5u4)
To("12.34", 5u4)
To("2e20", 5u4)
ToU4("∞", 5u2)
ToU4("Infinity", 5u2)
ToU4("NaN", 5u2)

// Date and TimeSpan

ToU1(Date(1, 1, 1, 0, 0, 0, 1, 0))

ToU8(Time(23, 59, 59))
