DUDS
Distributed Update of Data from Something
Unit.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of the DUDS project. It is subject to the BSD-style
3  * license terms in the LICENSE file found in the top-level directory of this
4  * distribution and at https://github.com/jjackowski/duds/blob/master/LICENSE.
5  * No part of DUDS, including this file, may be copied, modified, propagated,
6  * or distributed except according to the terms contained in the LICENSE file.
7  *
8  * Copyright (C) 2017 Jeff Jackowski
9  */
10 #ifndef UNIT_HPP
11 #define UNIT_HPP
12 
13 #include <boost/serialization/nvp.hpp>
14 #include <boost/exception/exception.hpp>
15 #include <boost/exception/info.hpp>
17 #include <stdexcept>
18 #include <cstdint>
19 
20 namespace duds { namespace data {
21 
23 
28 struct UnitError : virtual std::exception, virtual boost::exception { };
29 
36 
40 typedef boost::error_info<struct Info_unitexp, int> BadUnitExponent;
41 
45 typedef boost::error_info<struct Info_unitname, std::string> BadUnit;
46 
51 struct UnitMismatch : UnitError { };
52 
62 
178 class Unit {
182  std::int32_t u;
186  friend class boost::serialization::access;
192  template <class A>
193  void serialize(A &a, const unsigned int) {
194  a & BOOST_SERIALIZATION_NVP(u);
195  }
196 public:
200  std::int32_t value() const {
201  return u;
202  }
207  Unit() = default;
211  Unit(const Unit &) = default;
220  constexpr Unit(std::int32_t U) : u(U) { }
235  Unit(int A, int cd, int K, int kg, int m, int mol, int s,
236  int rad = 0, int sr = 0);
240  int ampere() const {
241  return SignExtend<4>(u & 0xF);
242  }
246  int candela() const {
247  return SignExtend<4>((u & 0xF0) >> 4);
248  }
252  int kelvin() const {
253  return SignExtend<4>((u & 0xF00) >> 8);
254  }
258  int kilogram() const {
259  return SignExtend<4>((u & 0xF000) >> 12);
260  }
264  int meter() const {
265  return SignExtend<4>((u & 0xF0000) >> 16);
266  }
270  int mole() const {
271  return SignExtend<4>((u & 0xF00000) >> 20);
272  }
276  int second() const {
277  return SignExtend<4>((u & 0xF000000) >> 24);
278  }
282  int radian() const {
283  return SignExtend<2>((u & 0x30000000) >> 28);
284  }
288  int steradian() const {
289  return SignExtend<2>((u & 0xC0000000) >> 30);
290  }
294  int amp() const {
295  return ampere();
296  }
300  int metre() const {
301  return meter();
302  }
306  int A() const {
307  return ampere();
308  }
312  int cd() const {
313  return candela();
314  }
318  int K() const {
319  return kelvin();
320  }
324  int kg() const {
325  return kilogram();
326  }
330  int m() const {
331  return meter();
332  }
336  int mol() const {
337  return mole();
338  }
342  int s() const {
343  return second();
344  }
348  int rad() const {
349  return radian();
350  }
354  int sr() const {
355  return steradian();
356  }
362  void ampere(int e) {
363  u = (u & 0xFFFFFFF0) | (e & 0xF);
364  }
370  void candela(int e) {
371  u = (u & 0xFFFFFF0F) | ((e & 0xF) << 4);
372  }
378  void kelvin(int e) {
379  u = (u & 0xFFFFF0FF) | ((e & 0xF) << 8);
380  }
386  void kilogram(int e) {
387  u = (u & 0xFFFF0FFF) | ((e & 0xF) << 12);
388  }
394  void meter(int e) {
395  u = (u & 0xFFF0FFFF) | ((e & 0xF) << 16);
396  }
402  void mole(int e) {
403  u = (u & 0xFF0FFFFF) | ((e & 0xF) << 20);
404  }
410  void second(int e) {
411  u = (u & 0xF0FFFFFF) | ((e & 0xF) << 24);
412  }
417  void radian(int e) {
418  u = (u & 0xCFFFFFFF) | ((e & 0x3) << 28);
419  }
424  void steradian(int e) {
425  u = (u & 0x3FFFFFFF) | ((e & 0x3) << 30);
426  }
432  void amp(int e) {
433  ampere(e);
434  }
440  void metre(int e) {
441  meter(e);
442  }
448  void A(int e) {
449  ampere(e);
450  }
456  void cd(int e) {
457  candela(e);
458  }
464  void K(int e) {
465  kelvin(e);
466  }
472  void kg(int e) {
473  kilogram(e);
474  }
480  void m(int e) {
481  meter(e);
482  }
488  void mol(int e) {
489  mole(e);
490  }
496  void s(int e) {
497  second(e);
498  }
503  void rad(int e) {
504  radian(e);
505  }
510  void sr(int e) {
511  steradian(e);
512  }
518  void setAmpere(int e);
524  void setCandela(int e);
530  void setKelvin(int e);
536  void setKilogram(int e);
542  void setMeter(int e);
548  void setMole(int e);
554  void setSecond(int e);
560  void setRadian(int e);
566  void setSteradian(int e);
572  void setAmp(int e) {
573  setAmpere(e);
574  }
580  void setMetre(int e) {
581  setMeter(e);
582  }
587  bool unitless() const {
588  return u == 0;
589  }
593  void clear() {
594  u = 0;
595  }
600  const Unit operator * (const Unit &U) const;
605  const Unit operator / (const Unit &U) const;
613  Unit &operator *= (const Unit &U);
621  Unit &operator /= (const Unit &U);
625  bool operator < (const Unit &U) const {
626  return u < U.u;
627  }
631  bool operator > (const Unit &U) const {
632  return u > U.u;
633  }
637  bool operator <= (const Unit &U) const {
638  return u <= U.u;
639  }
643  bool operator >= (const Unit &U) const {
644  return u >= U.u;
645  }
649  bool operator == (const Unit &U) const {
650  return u == U.u;
651  }
655  bool operator != (const Unit &U) const {
656  return u != U.u;
657  }
658 };
659 
660 } }
661 
678 #define DUDS_UNIT_VALUE(A, cd, K, kg, m, mol, s, rad, sr) \
679  (((A) & 0xF) | (((cd) & 0xF) << 4) | (((K) & 0xF) << 8) | \
680  (((kg) & 0xF) << 12) | (((m) & 0xF) << 16) | (((mol) & 0xF) << 20) | \
681  (((s) & 0xF) << 24) | (((rad) & 3) << 28) | (((sr) & 3) << 30))
682 
683 #endif // #ifndef UNIT_HPP
void clear()
Makes the Unit unitless.
Definition: Unit.hpp:593
void mol(int e)
Sets the exponent for the mole (amount of substance) dimension without range checking.
Definition: Unit.hpp:488
Indicates that a value is beyond the range allowed by the Unit or ExtendedUnit class.
Definition: Unit.hpp:35
int cd() const
Returns the exponent for the candela (luminous intensity) dimension.
Definition: Unit.hpp:312
int ampere() const
Returns the exponent for the ampere (current) dimension.
Definition: Unit.hpp:240
void candela(int e)
Sets the exponent for the candela (luminous intensity) dimension without range checking.
Definition: Unit.hpp:370
int m() const
Returns the exponent for the meter (distance) dimension.
Definition: Unit.hpp:330
void serialize(A &a, const unsigned int)
Serialize the unit data.
Definition: Unit.hpp:193
constexpr bool operator==(const DigitalPinCap &cap, const DigitalPinCap::Flags &flg)
int rad() const
Returns the exponent for radians (angle).
Definition: Unit.hpp:348
int second() const
Returns the exponent for the second (time) dimension.
Definition: Unit.hpp:276
int kilogram() const
Returns the exponent for the kilogram (mass) dimension.
Definition: Unit.hpp:258
int steradian() const
Returns the exponent for steradians (solid angle).
Definition: Unit.hpp:288
int sr() const
Returns the exponent for steradians (solid angle).
Definition: Unit.hpp:354
Indicates that two different Unit objects were used in an operation that requires identical Unit obje...
Definition: Unit.hpp:51
void amp(int e)
Sets the exponent for the ampere (current) dimension without range checking.
Definition: Unit.hpp:432
void setAmp(int e)
Sets the exponent for the ampere (current) dimension.
Definition: Unit.hpp:572
int radian() const
Returns the exponent for radians (angle).
Definition: Unit.hpp:282
std::int32_t value() const
Returns the internal exponent fields.
Definition: Unit.hpp:200
int meter() const
Returns the exponent for the meter (distance) dimension.
Definition: Unit.hpp:264
void s(int e)
Sets the exponent for the second (time) dimension without range checking.
Definition: Unit.hpp:496
void kelvin(int e)
Sets the exponent for the kelvin (thermodynamic temperature) dimension without range checking...
Definition: Unit.hpp:378
int mol() const
Returns the exponent for the mole (amount of substance) dimension.
Definition: Unit.hpp:336
int K() const
Returns the exponent for the kelvin (thermodynamic temperature) dimension.
Definition: Unit.hpp:318
void steradian(int e)
Sets the exponent for steradians (solid angle) without range checking.
Definition: Unit.hpp:424
constexpr bool operator!=(const DigitalPinCap &cap, const DigitalPinCap::Flags &flg)
void meter(int e)
Sets the exponent for the meter (distance) dimension without range checking.
Definition: Unit.hpp:394
int amp() const
Returns the exponent for the ampere (current) dimension.
Definition: Unit.hpp:294
int kg() const
Returns the exponent for the kilogram (mass) dimension.
Definition: Unit.hpp:324
Represents an SI unit, either base or derived.
Definition: Unit.hpp:178
void kg(int e)
Sets the exponent for the kilogram (mass) dimension without range checking.
Definition: Unit.hpp:472
boost::error_info< struct Info_unitname, std::string > BadUnit
The name of the bad unit.
Definition: Unit.hpp:45
A conversion between units was attempted that cannot be performed.
Definition: Unit.hpp:61
void metre(int e)
Sets the exponent for the meter (distance) dimension without range checking.
Definition: Unit.hpp:440
boost::error_info< struct Info_unitexp, int > BadUnitExponent
The out-of-range exponent.
Definition: Unit.hpp:40
void m(int e)
Sets the exponent for the meter (distance) dimension without range checking.
Definition: Unit.hpp:480
void second(int e)
Sets the exponent for the second (time) dimension without range checking.
Definition: Unit.hpp:410
Quantity operator*(double s, const Quantity &q)
Multiplies a Quantity by a scalar.
Definition: Quantity.hpp:225
void K(int e)
Sets the exponent for the kelvin (thermodynamic temperature) dimension without range checking...
Definition: Unit.hpp:464
int kelvin() const
Returns the exponent for the kelvin (thermodynamic temperature) dimension.
Definition: Unit.hpp:252
void A(int e)
Sets the exponent for the ampere (current) dimension without range checking.
Definition: Unit.hpp:448
int mole() const
Returns the exponent for the mole (amount of substance) dimension.
Definition: Unit.hpp:270
void mole(int e)
Sets the exponent for the mole (amount of substance) dimension without range checking.
Definition: Unit.hpp:402
std::make_signed< T >::type SignExtend(const T x)
Performs a sign extention operation.
Definition: SignExtend.hpp:24
void sr(int e)
Sets the exponent for steradians (solid angle) without range checking.
Definition: Unit.hpp:510
int metre() const
Returns the exponent for the meter (distance) dimension.
Definition: Unit.hpp:300
int A() const
Returns the exponent for the ampere (current) dimension.
Definition: Unit.hpp:306
void cd(int e)
Sets the exponent for the candela (luminous intensity) dimension without range checking.
Definition: Unit.hpp:456
void ampere(int e)
Sets the exponent for the ampere (current) dimension without range checking.
Definition: Unit.hpp:362
int candela() const
Returns the exponent for the candela (luminous intensity) dimension.
Definition: Unit.hpp:246
void rad(int e)
Sets the exponent for radians (angle) without range checking.
Definition: Unit.hpp:503
bool unitless() const
Returns true if the Unit represents no units.
Definition: Unit.hpp:587
std::int32_t u
Stores the exponent fields.
Definition: Unit.hpp:182
void setMetre(int e)
Sets the exponent for the meter (distance) dimension.
Definition: Unit.hpp:580
void radian(int e)
Sets the exponent for radians (angle) without range checking.
Definition: Unit.hpp:417
int s() const
Returns the exponent for the second (time) dimension.
Definition: Unit.hpp:342
void kilogram(int e)
Sets the exponent for the ampere (current)kilogram (mass) dimension without range checking...
Definition: Unit.hpp:386
constexpr Unit(std::int32_t U)
Make a new Unit set to a specific unit value; intended for making common unit constants with DUDS_UNI...
Definition: Unit.hpp:220
Quantity operator/(double s, const Quantity &q)
Divides a Quantity by a scalar.
Definition: Quantity.hpp:232
A general unit related error.
Definition: Unit.hpp:28