UnitConversionEngine.h
1 /* Distributed under the Apache License, Version 2.0.
2  See accompanying NOTICE file for details.*/
3 
4 //----------------------------------------------------------------------------
12 //----------------------------------------------------------------------------
13 #pragma once
14 
15 #include "QuantityTypeDescriptor.h"
16 #include "UnitDescriptor.h"
17 #include "PrefixDescriptor.h"
18 #include "QuantityConversionDescriptor.h"
19 #include "QuantityConversionKey.h"
20 #include "UnitDimension.h"
21 #include <cassert>
22 
23 class CDM_DECL CUnitConversionEngine
24 {
25 private:
27 public:
28  // Define vector types for holding the data structures
29  typedef std::vector<CQuantityTypeDescriptor*> QuantityTypeList;
30  typedef std::vector<CUnitDescriptor*> UnitList;
31  typedef std::vector<CPrefixDescriptor*> PrefixList;
32  typedef std::vector<CQuantityConversionDescriptor*> QuantityConversionList;
33 
34  // Define hash map types for easy lookup of names and symbols
35  typedef std::unordered_map<char,unsigned int> PrefixMap;
36  typedef std::unordered_map<std::string,unsigned int> UnitSymbolMap;
37  typedef std::unordered_map<std::string,unsigned int> QuantityNameMap;
38  typedef std::unordered_map<CQuantityConversionKey, unsigned int> QuantityConversionMap;
39  typedef std::unordered_map<CUnitDimension, unsigned int> DimensionToQuantityMap;
40 
42  {
43  if (uce == nullptr)
44  {
45  uce = new CUnitConversionEngine();
46  uce->LoadDefinitions();
47  }
48  return *uce;
49  }
50 
51  static void DestroyEngine()
52  {
53  SAFE_DELETE(uce);
54  }
55 
56  // Do conversion, using either string or CCompoundUnit specifications, and
57  // either with or without (quick) dimension checking.
58  double ConvertValue(const double &value, const CCompoundUnit &fromUnit, const CCompoundUnit &toUnit) const;
59  double ConvertValue(const double &value, const std::string &fromUnit, const std::string &toUnit) const;
60  double QuickConvertValue(const double &value, const CCompoundUnit &fromUnit, const CCompoundUnit &toUnit) const;
61  double QuickConvertValue(const double &value, const std::string &fromUnit, const std::string &toUnit) const;
62  // ConvertValueInterval basically ignores the biases in order to convert intervals of a
63  // particular unit. Useful for *adding* quantities together
64  double ConvertValueInterval(const double &value, const CCompoundUnit &fromUnit, const CCompoundUnit &toUnit) const;
65  double ConvertValueInterval(const double &value, const std::string &fromUnit, const std::string &toUnit) const;
66  double ConvertQuantityType(const double &value, const CCompoundUnit &fromUnit, const CCompoundUnit &toUnit) const;
67 
68  // Simple direct lookup of a unit symbol.
69  int GetUnitID(const std::string &unitSym) const;
70 
71  // Lookup a quantity type
72  int GetQuantityTypeID(const std::string &qtName) const;
73  int GetQuantityTypeID(const CUnitDimension &ud) const;
74 
75  // Lookup a conversion descriptor
76  int GetQuantityConversionID(const CUnitDimension *fromDim, const CUnitDimension *toDim) const;
77 
78  // Lookup quantity conversion parameters. Will automatically compute inverted parameters
79  // if looking up conversion in opposite direction from that which was defined. The two reference parameters
80  // are modified by this function to return the exponent that the original value (including
81  // its associated compound unit) must be raised to, and the conversion factor as a CCompoundUnit
82  // object that must be factored in as well. The CCompoundUnit object that serves as the
83  // conversion factor contains the mapping unit and has already been raised to the necessary power
84  // as specified by the QuantityConversionDescriptor. In the event that the requested
85  // quantity conversion is the reverse of a defined quantity conversion, the defined
86  // version's conversion parameters are transmogrified into those of the requested
87  // conversion automatically.
88  bool GetQuantityConversionParams(const CUnitDimension *fromDim, const CUnitDimension *toDim, double &fromExp, CCompoundUnit &mappingUnit) const;
89 
90  // Returns a CompoundUnit corresponding to the string representation.
91  // Dynamically allocated, and caller must delete.
92  CCompoundUnit *GetCompoundUnit(const std::string &unitString) const;
93 
94  // More robust symbol lookup, allows symbols with prefixes attached, and returns
95  // (via references) both the unit ID and the prefix scale factor.
96  bool LookupFullUnit(const std::string &fullUnitSym, int &unitID, double &prefixScaleFac) const
97  {
98  int prefixID;
99  bool rc = LookupFullUnit(fullUnitSym, unitID, prefixID);
100  if (rc)
101  {
102  if (prefixID != -1)
103  {
104  CPrefixDescriptor *pd = (*m_PList)[prefixID];
105  prefixScaleFac = pd->GetScaleFactor();
106  }
107  else
108  {
109  prefixScaleFac = 1.0;
110  }
111  return true;
112  }
113  else
114  {
115  return false;
116  }
117  }
118 
119  bool LookupFullUnit(const std::string &fullUnitSym, int &unitID, int &prefixID) const;
120 
121  // Accessor convenience methods
122  const CUnitDescriptor &GetUnitDescriptor(int unitID) const
123  {
124  assert((unitID >= 0) && (unitID < static_cast<int>(m_UList->size())));
125  return *(*m_UList)[unitID];
126  };
127 
129  {
130  assert((qtID >= 0) && (qtID < static_cast<int>(m_QTList->size())));
131  return *(*m_QTList)[qtID];
132  };
133 
134  const CPrefixDescriptor &GetPrefixDescriptor(int pfxID) const
135  {
136  assert((pfxID >= 0) && (pfxID < static_cast<int>(m_PList->size())));
137  return *(*m_PList)[pfxID];
138  };
139 
141  {
142  assert((qcID >= 0) && (qcID < static_cast<int>(m_QCList->size())));
143  return *(*m_QCList)[qcID];
144  }
145 
147  {
148  return m_iNumQuantities;
149  }
150 
152  {
153  return m_iNumFundamentalQuantities;
154  }
155 
156  void LoadDefinitions();
157 
158  // These are the methods that the LoadDefinitions methods call to build up the
159  // internal database of units information
160  CUnitDescriptor *NewUnit(const std::string &name, const std::string &symbol, unsigned int quantityTypeId, const std::string &targetUnit,
161  const double &convFac, const double &bias, CUnitDescriptor::PrefixModeType mode, const std::string &prefixSet);
162  CQuantityTypeDescriptor *NewQuantityType(const std::string &name, const std::string &expansion = "", bool twentyLog = false);
163 
164  CPrefixDescriptor *NewPrefix(const std::string &name, const std::string &sym, const double &scaleFac);
165  CQuantityConversionDescriptor *NewQuantityConversion(const std::string &fromTypeName, double fromExp, const std::string &toTypeName,
166  const std::string &mappingUnit);
167 
168 protected:
169 
170 
171 
172 private:
173  // Only want one unit conversion engine, so declare constructors private
177 
178  // Make these pointers rather than the actual vectors to avoid compiler warnings
179  // about exporting STL classes
180  QuantityTypeList *m_QTList;
181  UnitList *m_UList;
182  PrefixList *m_PList;
183  QuantityConversionList *m_QCList;
184  PrefixMap *m_PMap;
185  UnitSymbolMap *m_USMap;
186  QuantityNameMap *m_QNMap;
187  QuantityConversionMap *m_QCMap;
188  DimensionToQuantityMap *m_D2QMap;
189 
192 
193  std::stringstream m_UCEdefs;
194  void GetUCEdefs();
195 };
Definition: QuantityConversionDescriptor.h:13
const CUnitDescriptor & GetUnitDescriptor(int unitID) const
Definition: UnitConversionEngine.h:122
UnitSymbolMap * m_USMap
Definition: UnitConversionEngine.h:185
PrefixModeType
Definition: UnitDescriptor.h:16
double GetScaleFactor() const
Definition: PrefixDescriptor.h:38
const CQuantityConversionDescriptor & GetQuantityConversionDescriptor(int qcID) const
Definition: UnitConversionEngine.h:140
std::unordered_map< std::string, unsigned int > QuantityNameMap
Definition: UnitConversionEngine.h:37
void LoadDefinitions()
Definition: UnitConversionEngine.cpp:86
int m_iNumFundamentalQuantities
Definition: UnitConversionEngine.h:190
PrefixMap * m_PMap
Definition: UnitConversionEngine.h:184
std::unordered_map< char, unsigned int > PrefixMap
Definition: UnitConversionEngine.h:35
DimensionToQuantityMap * m_D2QMap
Definition: UnitConversionEngine.h:188
Definition: UnitDescriptor.h:12
std::vector< CQuantityTypeDescriptor * > QuantityTypeList
Definition: UnitConversionEngine.h:29
const CPrefixDescriptor & GetPrefixDescriptor(int pfxID) const
Definition: UnitConversionEngine.h:134
UnitList * m_UList
Definition: UnitConversionEngine.h:181
QuantityConversionMap * m_QCMap
Definition: UnitConversionEngine.h:187
QuantityConversionList * m_QCList
Definition: UnitConversionEngine.h:183
CUnitConversionEngine(const CUnitConversionEngine &)
Definition: UnitConversionEngine.h:175
std::unordered_map< std::string, unsigned int > UnitSymbolMap
Definition: UnitConversionEngine.h:36
Definition: PrefixDescriptor.h:13
static CUnitConversionEngine * uce
Definition: UnitConversionEngine.h:26
std::unordered_map< CQuantityConversionKey, unsigned int > QuantityConversionMap
Definition: UnitConversionEngine.h:38
static CUnitConversionEngine & GetEngine(void)
Definition: UnitConversionEngine.h:41
QuantityTypeList * m_QTList
Definition: UnitConversionEngine.h:180
int GetNumQuantities()
Definition: UnitConversionEngine.h:146
std::vector< CUnitDescriptor * > UnitList
Definition: UnitConversionEngine.h:30
std::stringstream m_UCEdefs
Definition: UnitConversionEngine.h:193
QuantityNameMap * m_QNMap
Definition: UnitConversionEngine.h:186
Definition: QuantityTypeDescriptor.h:16
bool LookupFullUnit(const std::string &fullUnitSym, int &unitID, double &prefixScaleFac) const
Definition: UnitConversionEngine.h:96
std::vector< CPrefixDescriptor * > PrefixList
Definition: UnitConversionEngine.h:31
static void DestroyEngine()
Definition: UnitConversionEngine.h:51
int m_iNumQuantities
Definition: UnitConversionEngine.h:191
Definition: UnitConversionEngine.h:23
std::vector< CQuantityConversionDescriptor * > QuantityConversionList
Definition: UnitConversionEngine.h:32
int GetNumFundamentalQuantities()
Definition: UnitConversionEngine.h:151
std::unordered_map< CUnitDimension, unsigned int > DimensionToQuantityMap
Definition: UnitConversionEngine.h:39
Definition: UnitDimension.h:21
Definition: CompoundUnit.h:39
const CQuantityTypeDescriptor & GetQuantityTypeDescriptor(int qtID) const
Definition: UnitConversionEngine.h:128
PrefixList * m_PList
Definition: UnitConversionEngine.h:182