SST  6.0.0
StructuralSimulationToolkit
unitAlgebra.h
1 // -*- c++ -*-
2 
3 // Copyright 2009-2016 Sandia Corporation. Under the terms
4 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
5 // Government retains certain rights in this software.
6 //
7 // Copyright (c) 2009-2016, Sandia Corporation
8 // All rights reserved.
9 //
10 // This file is part of the SST software package. For license
11 // information, see the LICENSE file in the top level directory of the
12 // distribution.
13 
14 #ifndef SST_CORE_UNITALGEBRA_H
15 #define SST_CORE_UNITALGEBRA_H
16 
17 #include <sst/core/sst_types.h>
18 #include <sst/core/serialization/serializable.h>
19 #include <sst/core/serialization/serializer.h>
20 
21 #include <string>
22 #include <map>
23 #include <vector>
24 #include <mutex>
25 
26 #if defined(__clang__)
27 #pragma clang diagnostic push
28 #pragma clang diagnostic ignored "-Wdeprecated-register"
29 #endif
30 
31 #include <boost/multiprecision/cpp_dec_float.hpp>
32 
33 #if defined(__clang__)
34 #pragma clang diagnostic pop
35 #endif
36 
37 #include <boost/version.hpp>
38 
39 namespace SST {
40 
41 typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<40,boost::int16_t> > sst_dec_float;
42 
43 /**
44  * Helper class internal to UnitAlgebra.
45  *
46  * Contains information on valid units
47  */
48 class Units {
49 
50  typedef uint8_t unit_id_t;
51 
52 private:
53  friend class UnitAlgebra;
54 
55  // Static data members and functions
56  static std::recursive_mutex unit_lock;
57  static std::map<std::string,unit_id_t> valid_base_units;
58  static std::map<std::string,std::pair<Units,sst_dec_float> > valid_compound_units;
59  static std::map<unit_id_t,std::string> unit_strings;
60  static unit_id_t count;
61  static bool initialized;
62 
63  static bool initialize();
64 
65  // Non-static data members and functions
66  std::vector<unit_id_t> numerator;
67  std::vector<unit_id_t> denominator;
68 
69  void reduce();
70  // Used in constructor to incrementally build up unit from string
71  void addUnit(std::string, sst_dec_float& multiplier, bool invert);
72 
73 public:
74  // Static data members and functions
75  /** Create a new Base Unit type */
76  static void registerBaseUnit(std::string u);
77  /** Create a new Compount Unit type */
78  static void registerCompoundUnit(std::string u, std::string v);
79 
80  // Non-static data members and functions
81  /** Create a new instantiation of a Units with a base unit string, and multiplier
82  * \param units String representing the new unit
83  * \param multiplier Value by which to multiply to get to this unit
84  */
85  Units(std::string units, sst_dec_float& multiplier);
86  Units() {}
87  virtual ~Units() {}
88 
89  /** Assignment operator */
90  Units& operator= (const Units& v);
91  /** Self-multiplication operator */
92  Units& operator*= (const Units& v);
93  /** Self-division operator */
94  Units& operator/= (const Units& v);
95  /** Equality Operator */
96  bool operator== (const Units &lhs) const;
97  /** Inequality Operator */
98  bool operator!= (const Units &lhs) const {return !(*this == lhs);}
99  /** Perform a reciprocal operation. Numerator and Denominator swap. */
100  Units& invert();
101 
102  /** Return a String representation if this Unit */
103  std::string toString() const;
104 };
105 
106 /**
107  * Performs Unit math in full precision
108  *
109  * Allows operations such as multiplying a frequency by 2.
110  *
111  */
113  public SST::Core::Serialization::serializable_type<UnitAlgebra> {
114 private:
115  Units unit;
116  sst_dec_float value;
117 
118  static std::string trim(std::string str);
119  void init(std::string val);
120 
121 public:
122  UnitAlgebra() {}
123  /**
124  Create a new UnitAlgebra instance, and pre-populate with a parsed value.
125 
126  \param val Value to parse. It is of the following format:
127  \code
128  val := NUMBER( )?UNITS
129  NUMBER := (-)?[0-9]+(.[0-9]+)?
130  UNITS := UNITGROUP(/UNITGROUP)
131  UNITGROUP := UNIT(-UNIT)*
132  UNIT := (SIPREFIX)?(BASEUNIT|COMPUNIT)
133  SIPREFIX := {a,f,p,n,u,m,[kKMGTPE]i?}
134  BASEUNIT := {s,B,b,events}
135  COMPUNIT := {Hz,hz,Bps,bps,event}
136  \endcode
137  */
138  UnitAlgebra(std::string val);
139  virtual ~UnitAlgebra();
140 
141  /** Print to an ostream the value */
142  void print(std::ostream& stream);
143  /** Print to an ostream the value
144  * Formats the number using SI-prefixes
145  */
146  void printWithBestSI(std::ostream& stream);
147  /** Return a string representation of this value */
148  std::string toString() const;
149  /** Return a string representation of this value
150  * Formats the number using SI-prefixes
151  */
152  std::string toStringBestSI() const;
153 
154  UnitAlgebra& operator= (const std::string& v);
155 
156  /** Multiply by an argument; */
158  /** Multiply by an argument; */
159  template <typename T>
160  UnitAlgebra& operator*= (const T& v) {
161  value *= v;
162  return *this;
163  }
164 
165  /** Divide by an argument; */
167  /** Divide by an argument; */
168  template <typename T>
169  UnitAlgebra& operator/= (const T& v) {
170  value /= v;
171  return *this;
172  }
173 
174  /** Compare if this object is greater than the argument */
175  bool operator> (const UnitAlgebra& v) const;
176  /** Compare if this object is greater than, or equal to, the argument */
177  bool operator>= (const UnitAlgebra& v) const;
178  /** Compare if this object is less than the argument */
179  bool operator< (const UnitAlgebra& v) const;
180  /** Compare if this object is less than, or equal to, the argument */
181  bool operator<= (const UnitAlgebra& v) const;
182  /** Apply a reciprocal operation to the object */
183  UnitAlgebra& invert();
184 
185  /** Returns true if the units in the parameter string are found
186  * in this object.
187  */
188  bool hasUnits(std::string u) const;
189  /** Return the raw value */
190  sst_dec_float getValue() const {return value;}
191  /** Return the rounded value as a 64bit integer */
192  int64_t getRoundedValue() const;
193 
194  void serialize_order(SST::Core::Serialization::serializer &ser) {
195  // Do the unit
196  ser & unit.numerator;
197  ser & unit.denominator;
198 
199  // For value, need to convert cpp_dec_float to string and
200  // reinit from string
201  switch(ser.mode()) {
202  case SST::Core::Serialization::serializer::SIZER:
203  case SST::Core::Serialization::serializer::PACK: {
204  std::string s = value.str(40, std::ios_base::fixed);
205  ser & s;
206  break;
207  }
208  case SST::Core::Serialization::serializer::UNPACK: {
209  std::string s;
210  ser & s;
211  value = sst_dec_float(s);
212  break;
213  }
214  }
215  }
216  ImplementSerializable(SST::UnitAlgebra)
217 };
218 
219 
220 // template <typename T>
221 // UnitAlgebra operator* (UnitAlgebra lhs, const T& rhs);
222 
223 // template <typename T>
224 // UnitAlgebra operator* (const T& lhs, UnitAlgebra rhs);
225 
226 // UnitAlgebra operator* (UnitAlgebra& lhs, const UnitAlgebra rhs);
227 
228 // template <typename T>
229 // UnitAlgebra operator/ (UnitAlgebra lhs, const T& rhs);
230 
231 // std::ostream& operator<< (std::ostream& os, const UnitAlgebra& r);
232 
233 // std::ostream& operator<< (std::ostream& os, const Units& r);
234 
235 template <typename T>
236 UnitAlgebra operator* (UnitAlgebra lhs, const T& rhs)
237 {
238  lhs *= rhs;
239  return lhs;
240 }
241 
242 template <typename T>
243 UnitAlgebra operator* (const T& lhs, UnitAlgebra rhs)
244 {
245  rhs *= lhs;
246  return rhs;
247 }
248 
249 inline UnitAlgebra operator* (UnitAlgebra& lhs, const UnitAlgebra rhs)
250 {
251  lhs *= rhs;
252  return lhs;
253 }
254 
255 template <typename T>
256 UnitAlgebra operator/ (UnitAlgebra lhs, const T& rhs)
257 {
258  lhs /= rhs;
259  return lhs;
260 }
261 
262 inline std::ostream& operator<< (std::ostream& os, const UnitAlgebra& r)
263 {
264  os << r.toString();
265  return os;
266 }
267 
268 inline std::ostream& operator<< (std::ostream& os, const Units& r)
269 {
270  os << r.toString();
271  return os;
272 }
273 
274 } // namespace SST
275 
276 
277 #endif //SST_CORE_UNITALGEBRA_H
bool operator>(const UnitAlgebra &v) const
Compare if this object is greater than the argument.
Definition: unitAlgebra.cc:452
Units & operator*=(const Units &v)
Self-multiplication operator.
Definition: unitAlgebra.cc:257
UnitAlgebra & operator/=(const UnitAlgebra &v)
Divide by an argument;.
Definition: unitAlgebra.cc:444
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:35
void print(std::ostream &stream)
Print to an ostream the value.
Definition: unitAlgebra.cc:386
sst_dec_float getValue() const
Return the raw value.
Definition: unitAlgebra.h:190
bool operator>=(const UnitAlgebra &v) const
Compare if this object is greater than, or equal to, the argument.
Definition: unitAlgebra.cc:464
std::string toString() const
Return a string representation of this value.
Definition: unitAlgebra.cc:397
bool hasUnits(std::string u) const
Returns true if the units in the parameter string are found in this object.
Definition: unitAlgebra.cc:509
Definition: action.cc:17
static void registerBaseUnit(std::string u)
Create a new Base Unit type.
Definition: unitAlgebra.cc:196
int64_t getRoundedValue() const
Return the rounded value as a 64bit integer.
Definition: unitAlgebra.cc:521
static void registerCompoundUnit(std::string u, std::string v)
Create a new Compount Unit type.
Definition: unitAlgebra.cc:207
Units & operator=(const Units &v)
Assignment operator.
Definition: unitAlgebra.cc:250
std::string toStringBestSI() const
Return a string representation of this value Formats the number using SI-prefixes.
Definition: unitAlgebra.cc:406
bool operator==(const Units &lhs) const
Equality Operator.
Definition: unitAlgebra.cc:276
Definition: serializable.h:108
Units & invert()
Perform a reciprocal operation.
Definition: unitAlgebra.cc:290
void printWithBestSI(std::ostream &stream)
Print to an ostream the value Formats the number using SI-prefixes.
Definition: unitAlgebra.cc:391
UnitAlgebra & invert()
Apply a reciprocal operation to the object.
Definition: unitAlgebra.cc:501
std::string toString() const
Return a String representation if this Unit.
Definition: unitAlgebra.cc:299
UnitAlgebra & operator*=(const UnitAlgebra &v)
Multiply by an argument;.
Definition: unitAlgebra.cc:436
bool operator<=(const UnitAlgebra &v) const
Compare if this object is less than, or equal to, the argument.
Definition: unitAlgebra.cc:488
bool operator!=(const Units &lhs) const
Inequality Operator.
Definition: unitAlgebra.h:98
Performs Unit math in full precision.
Definition: unitAlgebra.h:112
Units & operator/=(const Units &v)
Self-division operator.
Definition: unitAlgebra.cc:267
Helper class internal to UnitAlgebra.
Definition: unitAlgebra.h:48
bool operator<(const UnitAlgebra &v) const
Compare if this object is less than the argument.
Definition: unitAlgebra.cc:476
Definition: serializable.h:128