-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsiunits.hpp
117 lines (105 loc) · 3.38 KB
/
siunits.hpp
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
//
// siunits.hpp
// units-cxx14
//
// Copyright (c) 2016 Félix Cloutier
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef SIUNITS_HPP
#define SIUNITS_HPP
#define _USE_MATH_DEFINES
#include <cmath>
#include <ratio>
#include "units.hpp"
#ifndef UNITSCXX_SI_ARITHMETIC_TYPE
#define UNITSCXX_SI_ARITHMETIC_TYPE double
#endif
namespace unitscxx
{
namespace si
{
#pragma mark - Base units
enum units
{
meter,
gram, // the actual "base" unit is the kilogram
second,
ampere,
kelvin,
mole,
candela,
};
template<units U>
using si_base = unit_base<UNITSCXX_SI_ARITHMETIC_TYPE, units, U>;
constexpr si_base<units::meter> m(1);
constexpr si_base<units::gram> g(1);
constexpr si_base<units::second> s(1);
constexpr si_base<units::ampere> A(1);
constexpr si_base<units::kelvin> K(1);
constexpr si_base<units::mole> mol(1);
constexpr si_base<units::candela> cd(1);
// (little bit of cheating here)
constexpr auto kg = std::kilo() * g;
#pragma mark - Named derived units
// skipping radian: rad = m / m
// skipping steradian: sr = (m*m) / (m*m)
constexpr auto Hz = 1 / s;
constexpr auto N = kg * m / (s * s);
constexpr auto Pa = N / (m * m);
constexpr auto J = N * m;
constexpr auto W = J / s;
constexpr auto C = s * A;
constexpr auto V = W / A;
constexpr auto F = C / V;
constexpr auto Ohm = V / A; // for lack of a better Ω replacement
constexpr auto S = A / V;
constexpr auto Wb = V * s;
constexpr auto T = Wb / (m * m);
constexpr auto H = Wb / A;
// skipping lumen: lm = (cd * sr)
constexpr auto lx = cd / (m * m);
// skipping becquerel: Bq = 1 / s
constexpr auto Gy = J / kg;
// skipping sievert: Sv = J / kg
constexpr auto kat = mol / s;
// special treatment for Celsius
constexpr auto Czero = 273.15 * K;
constexpr decltype(K) C2K(UNITSCXX_SI_ARITHMETIC_TYPE celsiusTemperature)
{
return celsiusTemperature * K + Czero;
}
constexpr UNITSCXX_SI_ARITHMETIC_TYPE K2C(decltype(K) kelvinTemperature)
{
return (kelvinTemperature - Czero) / K;
}
#pragma mark - Commonly-accepted non-standard units
namespace detail
{
constexpr auto dm = std::deci() * m;
constexpr auto hm = std::hecto() * m;
}
constexpr auto deg = UNITSCXX_SI_ARITHMETIC_TYPE(M_PI / 180);
constexpr auto ha = detail::hm * detail::hm;
constexpr auto L = detail::dm * detail::dm * detail::dm;
constexpr auto t = std::kilo() * kg;
constexpr auto au = 1.496e11 * m;
}
}
#endif