158 lines
4.7 KiB
Odin
158 lines
4.7 KiB
Odin
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})
|
|
}
|