DUDS
Distributed Update of Data from Something
ExtendedUnit.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 EXTENDEDUNIT_HPP
11 #define EXTENDEDUNIT_HPP
12 
13 #include <duds/general/Errors.hpp>
14 #include <duds/data/Unit.hpp>
15 #include <boost/serialization/split_member.hpp>
16 
17 namespace duds { namespace data {
18 
19 // needed for celsius, liter
20 
26 class ExtendedUnit {
28  union {
35  std::uint32_t scaloff;
36  struct {
40  unsigned int mant : 20;
44  int exp : 7;
48  int sign : 1;
58  int scale : 4;
59  };
60  };
61  // serialization support
63  template <class A>
64  void save(A &a, const unsigned int) const {
65  a & BOOST_SERIALIZATION_NVP(unit);
66  // prevent differences in bitfields across platforms from causing
67  // different values for scaloff; assume for now that the archive will
68  // handle endianness differences
69  std::uint32_t packed = mant | (exp << 20) | (sign << 27) | (scale << 28);
70  a & BOOST_SERIALIZATION_NVP(packed);
71  }
72  template <class A>
73  void load(A &a, const unsigned int) {
74  a & BOOST_SERIALIZATION_NVP(unit);
75  std::uint32_t packed;
76  a & BOOST_SERIALIZATION_NVP(packed);
77  // prevent differences in bitfields across platforms from causing
78  // different values for scaloff; assume for now that the archive will
79  // handle endianness differences
80  mant = packed & 0xFFFFF;
81  exp = (packed >> 20) & 0x7F;
82  sign = (packed >> 27) & 1;
83  scale = packed >> 28;
84  }
93  constexpr ExtendedUnit(Unit u, std::uint32_t s) : unit(u), scaloff(s) { }
94 public:
98  ExtendedUnit() = default;
102  ExtendedUnit(const ExtendedUnit &) = default;
107  constexpr ExtendedUnit(Unit u) : unit(u), scaloff(0) { }
119  template <typename O>
120  ExtendedUnit(Unit u, O o, int s) : unit(u), scale(s) {
121  if ((s > 7) || (s < -8)) {
123  }
124  offset(o);
125  }
130  bool canConvertToUnit() const;
137  void offset(float o);
141  float offsetf() const;
148  void offset(double o);
152  double offset() const;
156  const Unit &base() const {
157  return unit;
158  }
162  int ampere() const {
163  return unit.ampere();
164  }
168  int candela() const {
169  return unit.candela();
170  }
174  int kelvin() const {
175  return unit.kelvin();
176  }
180  int kilogram() const {
181  return unit.kilogram();
182  }
186  int meter() const {
187  return unit.meter();
188  }
192  int mole() const {
193  return unit.mole();
194  }
198  int second() const {
199  return unit.second();
200  }
204  int radian() const {
205  return unit.radian();
206  }
210  int steradian() const {
211  return unit.steradian();
212  }
216  int amp() const {
217  return unit.ampere();
218  }
222  int metre() const {
223  return unit.meter();
224  }
228  int A() const {
229  return unit.ampere();
230  }
234  int cd() const {
235  return unit.candela();
236  }
240  int K() const {
241  return unit.kelvin();
242  }
246  int kg() const {
247  return unit.kilogram();
248  }
252  int m() const {
253  return unit.meter();
254  }
258  int mol() const {
259  return unit.mole();
260  }
264  int s() const {
265  return unit.second();
266  }
270  int rad() const {
271  return unit.radian();
272  }
276  int sr() const {
277  return unit.steradian();
278  }
284  void ampere(int e) {
285  unit.ampere(e);
286  }
292  void candela(int e) {
293  unit.candela(e);
294  }
300  void kelvin(int e) {
301  unit.kelvin(e);
302  }
308  void kilogram(int e) {
309  unit.kilogram(e);
310  }
316  void meter(int e) {
317  unit.meter(e);
318  }
324  void mole(int e) {
325  unit.mole(e);
326  }
332  void second(int e) {
333  unit.second(e);
334  }
339  void radian(int e) {
340  unit.radian(e);
341  }
346  void steradian(int e) {
347  unit.steradian(e);
348  }
354  void amp(int e) {
355  unit.ampere(e);
356  }
362  void metre(int e) {
363  unit.meter(e);
364  }
370  void A(int e) {
371  unit.ampere(e);
372  }
378  void cd(int e) {
379  unit.candela(e);
380  }
386  void K(int e) {
387  unit.kelvin(e);
388  }
394  void kg(int e) {
395  unit.kilogram(e);
396  }
402  void m(int e) {
403  unit.meter(e);
404  }
410  void mol(int e) {
411  unit.mole(e);
412  }
418  void s(int e) {
419  second(e);
420  }
425  void rad(int e) {
426  unit.radian(e);
427  }
432  void sr(int e) {
433  unit.steradian(e);
434  }
440  void setAmpere(int e) {
441  unit.setAmpere(e);
442  }
448  void setCandela(int e) {
449  unit.setCandela(e);
450  }
456  void setKelvin(int e) {
457  unit.setKelvin(e);
458  }
464  void setKilogram(int e) {
465  unit.setKilogram(e);
466  }
472  void setMeter(int e) {
473  unit.setMeter(e);
474  }
480  void setMole(int e) {
481  unit.setMole(e);
482  }
488  void setSecond(int e) {
489  unit.setSecond(e);
490  }
496  void setRadian(int e) {
497  unit.setRadian(e);
498  }
504  void setSteradian(int e) {
505  unit.setSteradian(e);
506  }
512  void setAmp(int e) {
513  unit.setAmpere(e);
514  }
520  void setMetre(int e) {
521  unit.setMeter(e);
522  }
527  bool unitless() const {
528  return unit.unitless();
529  }
534  const ExtendedUnit operator * (const Unit &U) const;
539  const ExtendedUnit operator / (const Unit &U) const;
547  ExtendedUnit &operator *= (const Unit &U);
555  ExtendedUnit &operator /= (const Unit &U);
559  ExtendedUnit &operator = (const Unit &U);
563  bool operator < (const ExtendedUnit &U) const {
564  return ((unit == U.unit) && (scaloff < U.scaloff)) || (unit < U.unit);
565  }
569  bool operator > (const ExtendedUnit &U) const {
570  return ((unit == U.unit) && (scaloff > U.scaloff)) || (unit > U.unit);
571  }
575  bool operator <= (const ExtendedUnit &U) const {
576  return ((unit == U.unit) && (scaloff <= U.scaloff)) || (unit <= U.unit);
577  }
581  bool operator >= (const ExtendedUnit &U) const {
582  return ((unit == U.unit) && (scaloff >= U.scaloff)) || (unit >= U.unit);
583  }
587  bool operator == (const ExtendedUnit &U) const {
588  return (unit == U.unit) && (scaloff == U.scaloff);
589  }
593  bool operator != (const ExtendedUnit &U) const {
594  return (unit != U.unit) || (scaloff != U.scaloff);
595  }
596 };
597 
601 template <class Q = double>
603  Q value;
605 private:
606  // serialization support
607  friend class boost::serialization::access;
608  template <class A>
609  void serialize(A &a, const unsigned int) {
610  a & BOOST_SERIALIZATION_NVP(value);
611  a & BOOST_SERIALIZATION_NVP(unit);
612  }
613 };
614 
615 } }
616 
617 #endif // #ifndef EXTENDEDUNIT_HPP
618 
Indicates that a value is beyond the range allowed by the Unit or ExtendedUnit class.
Definition: Unit.hpp:35
void setSteradian(int e)
Sets the exponent for steradians (solid angle).
int ampere() const
Returns the exponent for the ampere (current) dimension.
Definition: Unit.hpp:240
int m() const
Returns the exponent for the meter (distance) dimension.
void setKilogram(int e)
Sets the exponent for the kilogram (mass) dimension.
ExtendedUnit()=default
Makes an uninitialized ExtendedUnit.
ExtendedUnit & operator*=(const Unit &U)
Combines two units into a new unit.
int cd() const
Returns the exponent for the candela (luminous intensity) dimension.
int sign
The sign flag.
void setKelvin(int e)
Sets the exponent for the kelvin (thermodynamic temperature) dimension.
void kelvin(int e)
Sets the exponent for the kelvin (thermodynamic temperature) dimension without range checking...
bool operator>=(const ExtendedUnit &U) const
Unit objects are compared using the u member.
void s(int e)
Sets the exponent for the second (time) dimension without range checking.
int second() const
Returns the exponent for the second (time) dimension.
Definition: Unit.hpp:276
void setSteradian(int e)
Sets the exponent for steradians (solid angle).
Definition: Unit.cpp:87
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
void setMole(int e)
Sets the exponent for the mole (amount of substance) dimension.
void m(int e)
Sets the exponent for the meter (distance) dimension without range checking.
void setKilogram(int e)
Sets the exponent for the kilogram (mass) dimension.
Definition: Unit.cpp:42
ExtendedUnit & operator=(const Unit &U)
Makes this extended unit equivalent to the given Unit object.
bool canConvertToUnit() const
True if the unit represented by this object can also be represented by a Unit object.
const ExtendedUnit operator*(const Unit &U) const
Combines two units into a new unit.
void setSecond(int e)
Sets the exponent for the second (time) dimension.
Definition: Unit.cpp:69
bool operator<=(const ExtendedUnit &U) const
Unit objects are compared using the u member.
int scale
A value used to represnt most SI prefixes.
constexpr ExtendedUnit(Unit u, std::uint32_t s)
An simple internal constructor that takes the values of it members.
int kilogram() const
Returns the exponent for the kilogram (mass) dimension.
int kg() const
Returns the exponent for the kilogram (mass) dimension.
int radian() const
Returns the exponent for radians (angle).
Definition: Unit.hpp:282
int kelvin() const
Returns the exponent for the kelvin (thermodynamic temperature) dimension.
void setMetre(int e)
Sets the exponent for the meter (distance) dimension.
unsigned int mant
The mantissa, save for the impled leading bit.
void setAmp(int e)
Sets the exponent for the ampere (current) dimension.
int meter() const
Returns the exponent for the meter (distance) dimension.
Definition: Unit.hpp:264
int radian() const
Returns the exponent for radians (angle).
constexpr ExtendedUnit(Unit u)
Makes an ExtendedUnit that is equivalent to the given base Unit.
void setCandela(int e)
Sets the exponent for the candela (luminous intensity) dimension.
void setAmpere(int e)
Sets the exponent for the ampere (current) dimension.
Definition: Unit.cpp:15
int second() const
Returns the exponent for the second (time) dimension.
void cd(int e)
Sets the exponent for the candela (luminous intensity) dimension without range checking.
int mol() const
Returns the exponent for the mole (amount of substance) dimension.
const ExtendedUnit operator/(const Unit &U) const
Combines two units into a new unit.
int ampere() const
Returns the exponent for the ampere (current) dimension.
void setKelvin(int e)
Sets the exponent for the kelvin (thermodynamic temperature) dimension.
Definition: Unit.cpp:33
bool operator>(const ExtendedUnit &U) const
Unit objects are compared using the u member.
Represents an SI unit, either base or derived.
Definition: Unit.hpp:178
void setAmpere(int e)
Sets the exponent for the ampere (current) dimension.
int steradian() const
Returns the exponent for steradians (solid angle).
void K(int e)
Sets the exponent for the kelvin (thermodynamic temperature) dimension without range checking...
bool unitless() const
Returns true if the object represents no units.
void setMeter(int e)
Sets the exponent for the meter (distance) dimension.
Definition: Unit.cpp:51
const Unit & base() const
Returns the base unit as a Unit object.
ExtendedUnit(Unit u, O o, int s)
Constructs an ExtendedUnit with the given values.
void radian(int e)
Sets the exponent for radians (angle) without range checking.
ExtendedUnit & operator/=(const Unit &U)
Combines two units into a new unit.
int mole() const
Returns the exponent for the mole (amount of substance) dimension.
int A() const
Returns the exponent for the ampere (current) dimension.
int sr() const
Returns the exponent for steradians (solid angle).
void candela(int e)
Sets the exponent for the candela (luminous intensity) dimension without range checking.
void save(A &a, const unsigned int) const
int meter() const
Returns the exponent for the meter (distance) dimension.
friend class boost::serialization::access
int kelvin() const
Returns the exponent for the kelvin (thermodynamic temperature) dimension.
Definition: Unit.hpp:252
void mol(int e)
Sets the exponent for the mole (amount of substance) dimension without range checking.
redo: Use floats for scale and offset.
int K() const
Returns the exponent for the kelvin (thermodynamic temperature) dimension.
int amp() const
Returns the exponent for the ampere (current) dimension.
An idea that is not yet implemented; DO NOT USE.
void ampere(int e)
Sets the exponent for the ampere (current) dimension without range checking.
int mole() const
Returns the exponent for the mole (amount of substance) dimension.
Definition: Unit.hpp:270
bool operator==(const ExtendedUnit &U) const
Unit objects are compared using the u member.
float offsetf() const
Query the offset as a float.
void sr(int e)
Sets the exponent for steradians (solid angle) without range checking.
int s() const
Returns the exponent for the second (time) dimension.
void setMeter(int e)
Sets the exponent for the meter (distance) dimension.
void setRadian(int e)
Sets the exponent for radians (angle).
void kg(int e)
Sets the exponent for the kilogram (mass) dimension without range checking.
bool operator<(const ExtendedUnit &U) const
Unit objects are compared using the u member.
int candela() const
Returns the exponent for the candela (luminous intensity) dimension.
Definition: Unit.hpp:246
void setSecond(int e)
Sets the exponent for the second (time) dimension.
void setMole(int e)
Sets the exponent for the mole (amount of substance) dimension.
Definition: Unit.cpp:60
void rad(int e)
Sets the exponent for radians (angle) without range checking.
void mole(int e)
Sets the exponent for the mole (amount of substance) dimension without range checking.
void serialize(A &a, const unsigned int)
int rad() const
Returns the exponent for radians (angle).
bool operator!=(const ExtendedUnit &U) const
Unit objects are compared using the u member.
void A(int e)
Sets the exponent for the ampere (current) dimension without range checking.
bool unitless() const
Returns true if the Unit represents no units.
Definition: Unit.hpp:587
void steradian(int e)
Sets the exponent for steradians (solid angle) without range checking.
int metre() const
Returns the exponent for the meter (distance) dimension.
int exp
The exponent as a signed integer rather than unsigned with bias.
General errors.
double offset() const
Query the offset as a double.
void setRadian(int e)
Sets the exponent for radians (angle).
Definition: Unit.cpp:78
#define DUDS_THROW_EXCEPTION(x)
Works like BOOST_THROW_EXCEPTION, but includes a stack trace if DUDS_ERRORS_VERBOSE is defined...
Definition: Errors.hpp:48
void amp(int e)
Sets the exponent for the ampere (current) dimension without range checking.
void meter(int e)
Sets the exponent for the meter (distance) dimension without range checking.
int candela() const
Returns the exponent for the candela (luminous intensity) dimension.
void metre(int e)
Sets the exponent for the meter (distance) dimension without range checking.
std::uint32_t scaloff
A scaling and offset value packed into four bytes.
void setCandela(int e)
Sets the exponent for the candela (luminous intensity) dimension.
Definition: Unit.cpp:24
void kilogram(int e)
Sets the exponent for the ampere (current)kilogram (mass) dimension without range checking...
void second(int e)
Sets the exponent for the second (time) dimension without range checking.
void load(A &a, const unsigned int)