Physical Quantities  v1.0.0
C++ library of physical quantities, physical models, and units of measure for scientific computing. https://github.com/acodcha/phq
UnitSystem.hpp
Go to the documentation of this file.
1 // Copyright © 2020-2024 Alexandre Coderre-Chabot
2 //
3 // This file is part of Physical Quantities (PhQ), a C++ library of physical quantities, physical
4 // models, and units of measure for scientific computing.
5 //
6 // Physical Quantities is hosted at:
7 // https://github.com/acodcha/phq
8 //
9 // Physical Quantities is licensed under the MIT License:
10 // https://mit-license.org
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
13 // associated documentation files (the "Software"), to deal in the Software without restriction,
14 // including without limitation the rights to use, copy, modify, merge, publish, distribute,
15 // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 // - The above copyright notice and this permission notice shall be included in all copies or
18 // substantial portions of the Software.
19 // - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
20 // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 #ifndef PHQ_UNIT_SYSTEM_HPP
26 #define PHQ_UNIT_SYSTEM_HPP
27 
28 #include <cstdint>
29 #include <map>
30 #include <optional>
31 #include <ostream>
32 #include <string_view>
33 #include <unordered_map>
34 
35 #include "Base.hpp"
36 
37 namespace PhQ {
38 
39 /// \brief Systems of units of measure. All units of measure in a unit system are standard units of
40 /// measure. When a physical quantity is expressed in terms of a standard unit of measure, its value
41 /// does not need to be converted when used in mathematical expressions with other physical
42 /// quantities expressed in standard units of measure.
43 enum class UnitSystem : int8_t {
44  /// \brief Metre-kilogram-second-kelvin (m·kg·s·K) system
46 
47  /// \brief Millimetre-gram-second-kelvin (mm·g·s·K) system
49 
50  /// \brief Foot-pound-second-rankine (ft·lbf·s·°R) system
52 
53  /// \brief Inch-pound-second-rankine (in·lbf·s·°R) system
55 };
56 
57 /// \brief Standard unit of measure of a given type. Standard units of measure of different types
58 /// can be combined with each other without the need for conversions. When a physical quantity is
59 /// expressed in terms of a standard unit of measure, its value does not need to be converted when
60 /// used in mathematical expressions with other physical quantities expressed in standard units of
61 /// measure. For example, the standard unit of time is the second and the standard unit of length is
62 /// the metre. Correspondingly, the standard unit of speed is the metre per second. Thus, when
63 /// forming a speed quantity from a length quantity and a time quantity, if all quantities are
64 /// expressed in these standard units, no unit conversions are needed.
65 template <typename Type>
66 inline constexpr const Type Standard;
67 
68 /// \brief The standard unit system: the International System of Units (SI). It uses the following
69 /// standard units: second (s) for time, metre (m) for length, kilogram (kg) for mass, ampere (A)
70 /// for electric current, kelvin (K) for temperature, mole (mol) for substance amount, and candela
71 /// (cd) for luminous intensity.
72 template <>
74 
75 namespace Internal {
76 
77 // clang-format off
78 
79 template <>
80 inline const std::map<UnitSystem, std::string_view> Abbreviations<UnitSystem>{
81  {UnitSystem::MetreKilogramSecondKelvin, "m·kg·s·K" },
83  {UnitSystem::FootPoundSecondRankine, "ft·lbf·s·°R"},
84  {UnitSystem::InchPoundSecondRankine, "in·lbf·s·°R"},
85 };
86 
87 template <>
88 inline const std::unordered_map<std::string_view, UnitSystem> Spellings<UnitSystem>{
89  {"m·kg·s·K", UnitSystem::MetreKilogramSecondKelvin },
93  {"m, kg, s, K", UnitSystem::MetreKilogramSecondKelvin },
123  {"ft·lbf·s·°R", UnitSystem::FootPoundSecondRankine },
124  {"ft-lbf-s-°R", UnitSystem::FootPoundSecondRankine },
125  {"ft*lbf*s*°R", UnitSystem::FootPoundSecondRankine },
126  {"ft lbf s °R", UnitSystem::FootPoundSecondRankine },
127  {"ft, lbf, s, °R", UnitSystem::FootPoundSecondRankine },
128  {"ft·lb·s·°R", UnitSystem::FootPoundSecondRankine },
129  {"ft-lb-s-°R", UnitSystem::FootPoundSecondRankine },
130  {"ft*lb*s*°R", UnitSystem::FootPoundSecondRankine },
131  {"ft lb s °R", UnitSystem::FootPoundSecondRankine },
132  {"ft, lb, s, °R", UnitSystem::FootPoundSecondRankine },
133  {"ft·lbf·s·R", UnitSystem::FootPoundSecondRankine },
134  {"ft-lbf-s-R", UnitSystem::FootPoundSecondRankine },
135  {"ft*lbf*s*R", UnitSystem::FootPoundSecondRankine },
136  {"ft lbf s R", UnitSystem::FootPoundSecondRankine },
137  {"ft, lbf, s, R", UnitSystem::FootPoundSecondRankine },
138  {"ft·lb·s·R", UnitSystem::FootPoundSecondRankine },
139  {"ft-lb-s-R", UnitSystem::FootPoundSecondRankine },
140  {"ft*lb*s*R", UnitSystem::FootPoundSecondRankine },
141  {"ft lb s R", UnitSystem::FootPoundSecondRankine },
142  {"ft, lb, s, R", UnitSystem::FootPoundSecondRankine },
143  {"ft·lbf·s", UnitSystem::FootPoundSecondRankine },
144  {"ft-lbf-s", UnitSystem::FootPoundSecondRankine },
145  {"ft*lbf*s", UnitSystem::FootPoundSecondRankine },
146  {"ft lbf s", UnitSystem::FootPoundSecondRankine },
147  {"ft, lbf, s", UnitSystem::FootPoundSecondRankine },
148  {"ft·lb·s", UnitSystem::FootPoundSecondRankine },
152  {"ft, lb, s", UnitSystem::FootPoundSecondRankine },
164  {"in·lbf·s·°R", UnitSystem::InchPoundSecondRankine },
165  {"in-lbf-s-°R", UnitSystem::InchPoundSecondRankine },
166  {"in*lbf*s*°R", UnitSystem::InchPoundSecondRankine },
167  {"in lbf s °R", UnitSystem::InchPoundSecondRankine },
168  {"in, lbf, s, °R", UnitSystem::InchPoundSecondRankine },
169  {"in·lb·s·°R", UnitSystem::InchPoundSecondRankine },
170  {"in-lb-s-°R", UnitSystem::InchPoundSecondRankine },
171  {"in*lb*s*°R", UnitSystem::InchPoundSecondRankine },
172  {"in lb s °R", UnitSystem::InchPoundSecondRankine },
173  {"in, lb, s, °R", UnitSystem::InchPoundSecondRankine },
174  {"in·lbf·s·R", UnitSystem::InchPoundSecondRankine },
175  {"in-lbf-s-R", UnitSystem::InchPoundSecondRankine },
176  {"in*lbf*s*R", UnitSystem::InchPoundSecondRankine },
177  {"in lbf s R", UnitSystem::InchPoundSecondRankine },
178  {"in, lbf, s, R", UnitSystem::InchPoundSecondRankine },
179  {"in·lb·s·R", UnitSystem::InchPoundSecondRankine },
180  {"in-lb-s-R", UnitSystem::InchPoundSecondRankine },
181  {"in*lb*s*R", UnitSystem::InchPoundSecondRankine },
182  {"in lb s R", UnitSystem::InchPoundSecondRankine },
183  {"in, lb, s, R", UnitSystem::InchPoundSecondRankine },
184  {"in·lbf·s", UnitSystem::InchPoundSecondRankine },
185  {"in-lbf-s", UnitSystem::InchPoundSecondRankine },
186  {"in*lbf*s", UnitSystem::InchPoundSecondRankine },
187  {"in lbf s", UnitSystem::InchPoundSecondRankine },
188  {"in, lbf, s", UnitSystem::InchPoundSecondRankine },
189  {"in·lb·s", UnitSystem::InchPoundSecondRankine },
193  {"in, lb, s", UnitSystem::InchPoundSecondRankine },
205 };
206 
207 // clang-format on
208 
209 /// \brief Map of unit systems to their corresponding units. This is an internal implementation
210 /// detail and is not intended to be used except by the PhQ::ConsistentUnit function.
211 template <typename Unit>
212 inline const std::map<UnitSystem, Unit> ConsistentUnits;
213 
214 /// \brief Map of units to their corresponding unit systems. This is an internal implementation
215 /// detail and is not intended to be used except by the PhQ::RelatedUnitSystem function.
216 template <typename Unit>
217 inline const std::map<Unit, UnitSystem> RelatedUnitSystems;
218 
219 } // namespace Internal
220 
221 /// \brief Returns the unit of a given type that corresponds to a given unit system. For example,
222 /// PhQ::ConsistentUnit<Force>(PhQ::UnitSystem::MetreKilogramSecondKelvin) returns
223 /// PhQ::Unit::Force::Newton.
224 template <typename Unit>
225 inline Unit ConsistentUnit(const UnitSystem& system) {
226  return Internal::ConsistentUnits<Unit>.at(system);
227 }
228 
229 /// \brief Returns the unit system, if any, that corresponds to a given unit, or std::nullptr
230 /// otherwise. For example, PhQ::RelatedUnitSystem(PhQ::Unit::Length::Millimetre) returns
231 /// PhQ::UnitSystem::MillimetreGramSecondKelvin.
232 template <typename Unit>
233 inline std::optional<UnitSystem> RelatedUnitSystem(const Unit& unit) {
234  const typename std::map<Unit, UnitSystem>::const_iterator system{
235  Internal::RelatedUnitSystems<Unit>.find(unit)};
236  if (system != Internal::RelatedUnitSystems<Unit>.cend()) {
237  return system->second;
238  }
239  return std::nullopt;
240 }
241 
242 inline std::ostream& operator<<(std::ostream& stream, const UnitSystem unit_system) {
243  stream << Abbreviation(unit_system);
244  return stream;
245 }
246 
247 } // namespace PhQ
248 
249 #endif // PHQ_UNIT_SYSTEM_HPP
Namespace that encompasses all of the Physical Quantities library's content.
UnitSystem
Systems of units of measure. All units of measure in a unit system are standard units of measure....
Definition: UnitSystem.hpp:43
@ FootPoundSecondRankine
Foot-pound-second-rankine (ft·lbf·s·°R) system.
@ MillimetreGramSecondKelvin
Millimetre-gram-second-kelvin (mm·g·s·K) system.
@ MetreKilogramSecondKelvin
Metre-kilogram-second-kelvin (m·kg·s·K) system.
@ InchPoundSecondRankine
Inch-pound-second-rankine (in·lbf·s·°R) system.
Unit ConsistentUnit(const UnitSystem &system)
Returns the unit of a given type that corresponds to a given unit system. For example,...
Definition: UnitSystem.hpp:225
constexpr const UnitSystem Standard< UnitSystem >
The standard unit system: the International System of Units (SI). It uses the following standard unit...
Definition: UnitSystem.hpp:73
std::optional< UnitSystem > RelatedUnitSystem(const Unit &unit)
Returns the unit system, if any, that corresponds to a given unit, or std::nullptr otherwise....
Definition: UnitSystem.hpp:233
constexpr const Type Standard
Standard unit of measure of a given type. Standard units of measure of different types can be combine...
Definition: UnitSystem.hpp:66
std::string_view Abbreviation(const Enumeration enumeration)
Returns the abbreviation of a given enumeration value. For example, PhQ::Abbreviation(PhQ::Unit::Time...
Definition: Base.hpp:89
std::ostream & operator<<(std::ostream &stream, const Acceleration< NumericType > &acceleration)