forked from cataclysmbnteam/Cataclysm-BN
-
Notifications
You must be signed in to change notification settings - Fork 0
/
units_temperature.h
156 lines (131 loc) · 4.72 KB
/
units_temperature.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#pragma once
#ifndef CATA_SRC_UNITS_TEMPERATURE_H
#define CATA_SRC_UNITS_TEMPERATURE_H
#include <algorithm>
#include "units_def.h"
namespace units
{
constexpr double fahrenheit_to_celsius( double fahrenheit )
{
return ( ( fahrenheit - 32.0 ) * 5.0 / 9.0 );
}
/**
* Convert a temperature from degrees Fahrenheit to Kelvin.
*
* @return Temperature in degrees K.
*/
constexpr double fahrenheit_to_kelvin( double fahrenheit )
{
return fahrenheit_to_celsius( fahrenheit ) + 273.15;
}
/**
* Convert a temperature from Kelvin to degrees Fahrenheit.
*
* @return Temperature in degrees C.
*/
constexpr double kelvin_to_fahrenheit( double kelvin )
{
return 1.8 * ( kelvin - 273.15 ) + 32;
}
/**
* Convert a temperature from Celsius to degrees Fahrenheit.
*
* @return Temperature in degrees F.
*/
constexpr double celsius_to_fahrenheit( double celsius )
{
return celsius * 9 / 5 + 32;
}
/**
* Convert a temperature from Celsius to kelvins.
*
* @return Temperature in degrees F.
*/
constexpr double celsius_to_kelvin( double celsius )
{
return celsius + 273.15;
}
class temperature_in_millidegree_celsius_tag
{
};
using temperature = quantity<int, temperature_in_millidegree_celsius_tag>;
// Temperature contains different units and multiplication can get weird
// Say, 10 * 1_f != 10_f
template<>
struct quantity_details<temperature_in_millidegree_celsius_tag> {
using common_zero_point = std::false_type;
};
const temperature temperature_min = units::temperature(
std::numeric_limits<units::temperature::value_type>::min(),
units::temperature::unit_type{} );
const temperature temperature_max = units::temperature(
std::numeric_limits<units::temperature::value_type>::max(),
units::temperature::unit_type{} );
template<typename value_type>
inline constexpr quantity<value_type, temperature_in_millidegree_celsius_tag>
from_millidegree_celsius(
const value_type v )
{
return quantity<value_type, temperature_in_millidegree_celsius_tag>( v,
temperature_in_millidegree_celsius_tag{} );
}
template<typename value_type>
inline constexpr quantity<value_type, temperature_in_millidegree_celsius_tag> from_celsius(
const value_type v )
{
const value_type max_temperature_celsius = std::numeric_limits<value_type>::max() / 1000;
const value_type temperature = v > max_temperature_celsius ? max_temperature_celsius : v;
return from_millidegree_celsius<value_type>( temperature * 1000 );
}
template<typename value_type>
inline constexpr quantity<value_type, temperature_in_millidegree_celsius_tag> from_fahrenheit(
const value_type v )
{
// Explicit casts to silence warnings about lossy conversions
constexpr value_type max_temperature_fahrenheit = static_cast<value_type>( celsius_to_fahrenheit(
// NOLINTNEXTLINE(bugprone-integer-division)
static_cast<double>( std::numeric_limits<value_type>::max() / 1000 ) ) );
const value_type temperature = v > max_temperature_fahrenheit ? max_temperature_fahrenheit : v;
return from_millidegree_celsius<value_type>(
static_cast<value_type>( fahrenheit_to_celsius( temperature ) * 1000 ) );
}
template<typename value_type>
inline constexpr value_type to_millidegree_celsius( const
quantity<value_type, temperature_in_millidegree_celsius_tag> &v )
{
return v / from_millidegree_celsius<value_type>( 1 );
}
template<typename value_type>
inline constexpr value_type to_celsius( const
quantity<value_type, temperature_in_millidegree_celsius_tag> &v )
{
return to_millidegree_celsius( v ) / 1000.0;
}
template<typename value_type>
inline constexpr value_type to_fahrenheit( const
quantity<value_type, temperature_in_millidegree_celsius_tag> &v )
{
return celsius_to_fahrenheit( to_millidegree_celsius( v ) / 1000.0 );
}
template<typename value_type>
inline constexpr value_type to_kelvins( const
quantity<value_type, temperature_in_millidegree_celsius_tag> &v )
{
return celsius_to_kelvin( to_millidegree_celsius( v ) / 1000.0 );
}
} // namespace units
inline constexpr units::temperature operator"" _mc( const unsigned long long v )
{
// Cast to int because fahrenheit conversion needs it
// Rest gets it for consistency
return units::from_millidegree_celsius<int>( v );
}
inline constexpr units::temperature operator"" _c( const unsigned long long v )
{
return units::from_celsius<int>( v );
}
inline constexpr units::temperature operator"" _f( const unsigned long long v )
{
return units::from_fahrenheit<int>( v );
}
#endif // CATA_SRC_UNITS_TEMPERATURE_H