00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef SST_CORE_UNITALGEBRA_H
00015 #define SST_CORE_UNITALGEBRA_H
00016
00017 #include <sst/core/sst_types.h>
00018 #include <sst/core/serialization.h>
00019
00020 #include <string>
00021 #include <map>
00022 #include <vector>
00023
00024 #if defined(__clang__)
00025 #pragma clang diagnostic push
00026 #pragma clang diagnostic ignored "-Wdeprecated-register"
00027 #endif
00028
00029 #include <boost/multiprecision/cpp_dec_float.hpp>
00030
00031 #if defined(__clang__)
00032 #pragma clang diagnostic pop
00033 #endif
00034
00035 #include <boost/version.hpp>
00036
00037 namespace SST {
00038
00039 typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<40,boost::int16_t> > sst_dec_float;
00040
00041
00042
00043
00044
00045
00046 class Units {
00047
00048 typedef uint8_t unit_id_t;
00049
00050 private:
00051
00052
00053 static std::map<std::string,unit_id_t> valid_base_units;
00054 static std::map<std::string,std::pair<Units,sst_dec_float> > valid_compound_units;
00055 static std::map<unit_id_t,std::string> unit_strings;
00056 static unit_id_t count;
00057 static bool initialized;
00058
00059 static bool initialize();
00060
00061
00062 std::vector<unit_id_t> numerator;
00063 std::vector<unit_id_t> denominator;
00064
00065 void reduce();
00066
00067 void addUnit(std::string, sst_dec_float& multiplier, bool invert);
00068
00069 friend class boost::serialization::access;
00070 template<class Archive>
00071 void
00072 serialize(Archive & ar, const unsigned int version )
00073 {
00074 ar & BOOST_SERIALIZATION_NVP(numerator);
00075 ar & BOOST_SERIALIZATION_NVP(denominator);
00076 }
00077
00078 public:
00079
00080
00081 static void registerBaseUnit(std::string u);
00082
00083 static void registerCompoundUnit(std::string u, std::string v);
00084
00085
00086
00087
00088
00089
00090 Units(std::string units, sst_dec_float& multiplier);
00091 Units() {}
00092 virtual ~Units() {}
00093
00094
00095 Units& operator= (const Units& v);
00096
00097 Units& operator*= (const Units& v);
00098
00099 Units& operator/= (const Units& v);
00100
00101 bool operator== (const Units &lhs) const;
00102
00103 bool operator!= (const Units &lhs) const {return !(*this == lhs);}
00104
00105 Units& invert();
00106
00107
00108 std::string toString() const;
00109 };
00110
00111
00112
00113
00114
00115
00116
00117 class UnitAlgebra {
00118 private:
00119 Units unit;
00120 sst_dec_float value;
00121
00122 static std::string trim(std::string str);
00123 void init(std::string val);
00124
00125 friend class boost::serialization::access;
00126 #if BOOST_VERSION < 105500
00127
00128 template<class Archive>
00129 void save(Archive &ar, const unsigned int version ) const
00130 {
00131 ar & BOOST_SERIALIZATION_NVP(unit);
00132 std::string s = value.str(40, std::ios_base::fixed);
00133 ar & BOOST_SERIALIZATION_NVP(s);
00134 }
00135
00136 template<class Archive>
00137 void load(Archive &ar, const unsigned int version )
00138 {
00139 ar & BOOST_SERIALIZATION_NVP(unit);
00140 std::string s;
00141 ar & BOOST_SERIALIZATION_NVP(s);
00142 value = sst_dec_float(s);
00143 }
00144
00145 BOOST_SERIALIZATION_SPLIT_MEMBER()
00146 #else
00147 template<class Archive>
00148 void
00149 serialize(Archive & ar, const unsigned int version )
00150 {
00151 ar & BOOST_SERIALIZATION_NVP(unit);
00152 ar & BOOST_SERIALIZATION_NVP(value);
00153 }
00154 #endif
00155 public:
00156 UnitAlgebra() {}
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 UnitAlgebra(std::string val);
00173 virtual ~UnitAlgebra();
00174
00175
00176 void print(std::ostream& stream);
00177
00178
00179
00180 void printWithBestSI(std::ostream& stream);
00181
00182 std::string toString() const;
00183
00184
00185
00186 std::string toStringBestSI() const;
00187
00188 UnitAlgebra& operator= (const std::string& v);
00189
00190
00191 UnitAlgebra& operator*= (const UnitAlgebra& v);
00192
00193 template <typename T>
00194 UnitAlgebra& operator*= (const T& v) {
00195 value *= v;
00196 return *this;
00197 }
00198
00199
00200 UnitAlgebra& operator/= (const UnitAlgebra& v);
00201
00202 template <typename T>
00203 UnitAlgebra& operator/= (const T& v) {
00204 value /= v;
00205 return *this;
00206 }
00207
00208
00209 bool operator> (const UnitAlgebra& v);
00210
00211 bool operator>= (const UnitAlgebra& v);
00212
00213 bool operator< (const UnitAlgebra& v);
00214
00215 bool operator<= (const UnitAlgebra& v);
00216
00217 UnitAlgebra& invert();
00218
00219
00220
00221
00222 bool hasUnits(std::string u) const;
00223
00224 sst_dec_float getValue() const {return value;}
00225
00226 int64_t getRoundedValue() const;
00227
00228 };
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 template <typename T>
00246 UnitAlgebra operator* (UnitAlgebra lhs, const T& rhs)
00247 {
00248 lhs *= rhs;
00249 return lhs;
00250 }
00251
00252 template <typename T>
00253 UnitAlgebra operator* (const T& lhs, UnitAlgebra rhs)
00254 {
00255 rhs *= lhs;
00256 return rhs;
00257 }
00258
00259 inline UnitAlgebra operator* (UnitAlgebra& lhs, const UnitAlgebra rhs)
00260 {
00261 lhs *= rhs;
00262 return lhs;
00263 }
00264
00265 template <typename T>
00266 UnitAlgebra operator/ (UnitAlgebra lhs, const T& rhs)
00267 {
00268 lhs /= rhs;
00269 return lhs;
00270 }
00271
00272 inline std::ostream& operator<< (std::ostream& os, const UnitAlgebra& r)
00273 {
00274 os << r.toString();
00275 return os;
00276 }
00277
00278 inline std::ostream& operator<< (std::ostream& os, const Units& r)
00279 {
00280 os << r.toString();
00281 return os;
00282 }
00283
00284 }
00285
00286
00287 BOOST_CLASS_EXPORT_KEY(SST::Units)
00288 BOOST_CLASS_EXPORT_KEY(SST::UnitAlgebra)
00289
00290 #endif //SST_CORE_UNITALGEBRA_H