emlabcpp
modern opinionated embedded C++ library
physical_quantity.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include "./algorithm.h"
27 #include "./quantity.h"
28 
29 #include <string>
30 
31 namespace emlabcpp
32 {
33 
53 template < int Len, int Mass, int Time, int Current, int Temp, int Mol, int Li, int Angle, int Byte >
55  : quantity< physical_quantity< Len, Mass, Time, Current, Temp, Mol, Li, Angle, Byte >, float >
56 {
57 
58  using quantity<
60  float >::quantity;
61 
62  template < int Exp, char... Unit >
63  static consteval auto get_single_unit()
64  {
65  static_assert( Exp > -10 && Exp < 10 );
66  constexpr std::size_t unit_n = sizeof...( Unit );
67 
68  if constexpr ( Exp == 0 ) {
69  return std::array< char, 0 >{};
70  } else if constexpr ( Exp == 1 ) {
71  return std::array< char, unit_n >{ Unit... };
72  } else {
73  constexpr std::size_t char_n = unit_n + 1 + ( Exp > 0 ? 1 : 2 );
74  std::array< char, char_n > buffer{ Unit... };
75  std::size_t n = sizeof...( Unit );
76  buffer[n++] = '^';
77  if ( Exp < 0 ) {
78  buffer[n++] = '-';
79  buffer[n++] = -Exp + '0';
80  } else {
81  buffer[n++] = Exp + '0';
82  }
83  return buffer;
84  }
85  }
86 
87  template < int Exp, char... Unit >
88  static constexpr std::array single_unit = get_single_unit< Exp, Unit... >();
89 
90  static constexpr std::array unit = merge_arrays(
91  single_unit< Len, 'm' >,
92  single_unit< Mass, 'k', 'g' >,
93  single_unit< Time, 's' >,
94  single_unit< Current, 'A' >,
95  single_unit< Temp, 'K' >,
96  single_unit< Mol, 'm', 'o', 'l' >,
97  single_unit< Li, 'c', 'd' >,
98  single_unit< Angle, 'r', 'a', 'd' >,
99  single_unit< Byte, 'B' > );
100 
101  static std::string_view get_unit()
102  {
103  return { unit.data(), unit.size() };
104  }
105 };
106 
119 using acceleration = physical_quantity< 1, 0, -2, 0, 0, 0, 0, 0, 0 >;
120 using angular_velocity = physical_quantity< 0, 0, -1, 0, 0, 0, 0, 1, 0 >;
123 using velocity = physical_quantity< 1, 0, -1, 0, 0, 0, 0, 0, 0 >;
124 using frequency = physical_quantity< 0, 0, -1, 0, 0, 0, 0, 0, 0 >;
125 using force = physical_quantity< 1, 1, -2, 0, 0, 0, 0, 0, 0 >;
126 using power = physical_quantity< 2, 1, -3, 0, 0, 0, 0, 0, 0 >;
127 using voltage = physical_quantity< 2, 1, -3, -1, 0, 0, 0, 0, 0 >;
128 using resistance = physical_quantity< 2, 1, -3, -2, 0, 0, 0, 0, 0 >;
129 using distance = length;
130 using radius = length;
132 
134 constexpr angle pi = angle{ 3.14159265358979323846f };
135 
139 template <
140  int Len0,
141  int Mass0,
142  int Time0,
143  int Current0,
144  int Temp0,
145  int Mol0,
146  int Li0,
147  int Angle0,
148  int Byte0,
149  int Len1,
150  int Mass1,
151  int Time1,
152  int Current1,
153  int Temp1,
154  int Mol1,
155  int Li1,
156  int Angle1,
157  int Byte1 >
158 constexpr auto operator*(
161 {
162  return physical_quantity<
163  Len0 + Len1,
164  Mass0 + Mass1,
165  Time0 + Time1,
166  Current0 + Current1,
167  Temp0 + Temp1,
168  Mol0 + Mol1,
169  Li0 + Li1,
170  Angle0 + Angle1,
171  Byte0 + Byte1 >{ ( *lh ) * ( *rh ) };
172 }
173 
177 template <
178  int Len0,
179  int Mass0,
180  int Time0,
181  int Current0,
182  int Temp0,
183  int Mol0,
184  int Li0,
185  int Angle0,
186  int Byte0,
187  int Len1,
188  int Mass1,
189  int Time1,
190  int Current1,
191  int Temp1,
192  int Mol1,
193  int Li1,
194  int Angle1,
195  int Byte1 >
196 constexpr auto operator/(
199 {
200  return physical_quantity<
201  Len0 - Len1,
202  Mass0 - Mass1,
203  Time0 - Time1,
204  Current0 - Current1,
205  Temp0 - Temp1,
206  Mol0 - Mol1,
207  Li0 - Li1,
208  Angle0 - Angle1,
209  Byte0 - Byte1 >{ ( *lh ) / ( *rh ) };
210 }
211 
214 template < int Len, int Mass, int Time, int Current, int Temp, int Mol, int Li, int Angle, int Byte >
216 {
217  static_assert(
218  Len % 2 == 0 && Mass % 2 == 0 && Time % 2 == 0 && Current % 2 == 0 && Temp % 2 == 0 &&
219  Mol % 2 == 0 && Li % 2 == 0 && Angle % 2 == 0 && Byte % 2 == 0,
220  "sqrt() over physical_quantity can be used only if all of the units are power of 2" );
221  return physical_quantity<
222  Len / 2,
223  Mass / 2,
224  Time / 2,
225  Current / 2,
226  Temp / 2,
227  Mol / 2,
228  Li / 2,
229  Angle / 2,
230  Byte / 2 >{ float{ std::sqrt( *val ) } };
231 }
232 
235 
236 template <
237  int Power,
238  int Len,
239  int Mass,
240  int Time,
241  int Current,
242  int Temp,
243  int Mol,
244  int Li,
245  int Angle,
246  int Byte >
248 {
249  return physical_quantity<
250  Len * Power,
251  Mass * Power,
252  Time * Power,
253  Current * Power,
254  Temp * Power,
255  Mol * Power,
256  Li * Power,
257  Angle * Power,
258  Byte * Power >{ static_cast< float >( std::pow( *val, Power ) ) };
259 }
260 
261 #ifdef EMLABCPP_USE_OSTREAM
262 template < int Len, int Mass, int Time, int Current, int Temp, int Mol, int Li, int Angle, int Byte >
263 std::ostream& operator<<(
264  std::ostream& os,
265  physical_quantity< Len, Mass, Time, Current, Temp, Mol, Li, Angle, Byte > const& q )
266 {
267  return os << *q
269  get_unit();
270 }
271 #endif
272 
273 } // namespace emlabcpp
Class representing generic quantity.
Definition: quantity.h:63
MIT License.
Definition: impl.h:31
physical_quantity< 1, 0, 0, 0, 0, 0, 0, 0, 0 > length
Definition: physical_quantity.h:110
constexpr auto sqrt(physical_quantity< Len, Mass, Time, Current, Temp, Mol, Li, Angle, Byte > val)
Square root of physical quantity is square root of it's value and the exponents are divided in half.
Definition: physical_quantity.h:215
constexpr point< N > operator*(point< N > a, point< N > const &b)
Multiplication of points multiplies each coordinate of A by coordinate of B on same dimension.
Definition: point.h:74
constexpr angle pi
Constants of units that are relevant for us.
Definition: physical_quantity.h:134
constexpr auto pow(physical_quantity< Len, Mass, Time, Current, Temp, Mol, Li, Angle, Byte > val)
Power of physical quantity is power of root of it's value and the exponents are multiplied by the val...
Definition: physical_quantity.h:247
constexpr Derived operator/(vec_point_base< Derived, N > const &a, T s)
Divides each coordinate of A by item 's' of type T, if T satifies std::is_arithmetic.
Definition: vec_point_base.h:170
constexpr auto merge_arrays(Arr &&first, Arrs &&... arrs)
Expects multiple std::arrays on input, and merges all together into one std::array instance.
Definition: algorithm.h:531
std::ostream & operator<<(std::ostream &os, string_buffer< N > const &sb)
Definition: string_buffer.h:112
physical_quantity represents all physical units defined using the International System of Units and m...
Definition: physical_quantity.h:56
static std::string_view get_unit()
Definition: physical_quantity.h:101
static constexpr std::array single_unit
Definition: physical_quantity.h:88
static consteval auto get_single_unit()
Definition: physical_quantity.h:63
static constexpr std::array unit
Definition: physical_quantity.h:90