package quantity import "base:intrinsics" // --------------------------------------------------------------------------------------------------------------------- // ----- Constants ------------------------ // --------------------------------------------------------------------------------------------------------------------- @(private = "file") kelvins_celsius_offset :: #force_inline proc "contextless" ( $V: typeid, ) -> V where intrinsics.type_is_numeric(V) { when intrinsics.type_is_float(V) { OFFSET :: 273.15 } else { OFFSET :: 273 } return OFFSET } // --------------------------------------------------------------------------------------------------------------------- // ----- Types ------------------------ // --------------------------------------------------------------------------------------------------------------------- //----- Kelvins ---------------------------------- Kelvins :: struct($V: typeid) where intrinsics.type_is_numeric(V) { v: V, } @(private = "file") kelvins_to_celsius :: #force_inline proc "contextless" ( kelvins: Kelvins($V), ) -> Celsius(V) where intrinsics.type_is_numeric(V) { return Celsius(V){kelvins.v - kelvins_celsius_offset(V)} } @(private = "file") kelvins_to_deci_kelvins :: #force_inline proc "contextless" ( kelvins: Kelvins($V), ) -> Deci_Kelvins(V) where intrinsics.type_is_numeric(V) { return Deci_Kelvins(V){kelvins.v * DECI} } //----- Decikelvins ---------------------------------- Deci_Kelvins :: struct($V: typeid) where intrinsics.type_is_numeric(V) { v: V, } @(private = "file") deci_kelvins_to_kelvins :: #force_inline proc "contextless" ( deci_kelvins: Deci_Kelvins($V), ) -> Kelvins(V) where intrinsics.type_is_numeric(V) { return Kelvins(V){deci_kelvins.v / DECI} } //----- Degrees Celsius ---------------------------------- Celsius :: struct($V: typeid) where intrinsics.type_is_numeric(V) { v: V, } @(private = "file") celsius_to_kelvins :: #force_inline proc "contextless" ( degrees_celsius: Celsius($V), ) -> Kelvins(V) where intrinsics.type_is_numeric(V) { return Kelvins(V){degrees_celsius.v + kelvins_celsius_offset(V)} } @(private = "file") celsius_to_deci_celsius :: #force_inline proc "contextless" ( degrees_celsius: Celsius($V), ) -> Deci_Celsius(V) where intrinsics.type_is_numeric(V) { return Deci_Celsius(V){degrees_celsius.v * DECI} } //----- Deci Degrees Celsius ---------------------------------- Deci_Celsius :: struct($V: typeid) where intrinsics.type_is_numeric(V) { v: V, } @(private = "file") deci_celsius_to_celsius :: #force_inline proc "contextless" ( deci_degrees_celsius: Deci_Celsius($V), ) -> Celsius(V) where intrinsics.type_is_numeric(V) { return Celsius(V){deci_degrees_celsius.v / DECI} } // --------------------------------------------------------------------------------------------------------------------- // ----- Conversion Overloads ------------------------ // --------------------------------------------------------------------------------------------------------------------- to_kelvins :: proc { deci_kelvins_to_kelvins, celsius_to_kelvins, } to_deci_kelvins :: proc { kelvins_to_deci_kelvins, } to_celsius :: proc { kelvins_to_celsius, deci_celsius_to_celsius, } to_deci_celsius :: proc { celsius_to_deci_celsius, } // --------------------------------------------------------------------------------------------------------------------- // ----- Tests ------------------------ // --------------------------------------------------------------------------------------------------------------------- import "core:testing" @(test) test_kelvins_to_celsius :: proc(t: ^testing.T) { kelvins := Kelvins(f32){273.15} celsius := to_celsius(kelvins) testing.expect_value(t, celsius, Celsius(f32){0}) } @(test) test_kelvins_to_deci_kelvins :: proc(t: ^testing.T) { kelvins := Kelvins(int){100} deci_kelvins := to_deci_kelvins(kelvins) testing.expect_value(t, deci_kelvins, Deci_Kelvins(int){1000}) } @(test) test_deci_kelvins_to_kelvins :: proc(t: ^testing.T) { deci_kelvins := Deci_Kelvins(int){1000} kelvins := to_kelvins(deci_kelvins) testing.expect_value(t, kelvins, Kelvins(int){100}) } @(test) test_celsius_to_kelvins :: proc(t: ^testing.T) { degrees_celsius := Celsius(f32){0} kelvins := to_kelvins(degrees_celsius) testing.expect_value(t, kelvins, Kelvins(f32){273.15}) } @(test) test_celsius_to_deci_celsius :: proc(t: ^testing.T) { degrees_celsius := Celsius(int){100} deci_degrees_celsius := to_deci_celsius(degrees_celsius) testing.expect_value(t, deci_degrees_celsius, Deci_Celsius(int){1000}) } @(test) test_deci_celsius_to_celsius :: proc(t: ^testing.T) { deci_degrees_celsius := Deci_Celsius(int){1000} degrees_celsius := to_celsius(deci_degrees_celsius) testing.expect_value(t, degrees_celsius, Celsius(int){100}) }