![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2008-2012, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_CONVERT_UNITS_H 00024 #define O2SCL_CONVERT_UNITS_H 00025 00026 #include <cstdio> 00027 #include <cstdlib> 00028 #include <iostream> 00029 #include <map> 00030 00031 #include <o2scl/err_hnd.h> 00032 #include <o2scl/misc.h> 00033 #include <o2scl/constants.h> 00034 #include <o2scl/string_conv.h> 00035 00036 #ifndef DOXYGENP 00037 namespace o2scl { 00038 #endif 00039 00040 /** \brief Convert units 00041 00042 Allow the user to convert between two different units after 00043 specifying a conversion factor. This class will also 00044 automatically combine two conversion factors to create a new 00045 unit conversion (but it cannot combine more than two). 00046 00047 Conversions are performed by the \ref convert() function and 00048 the conversion factors must be specified beforehand using the 00049 \ref insert_cache() function. 00050 00051 If the GNU units command is not in the local path, the user may 00052 modify \ref units_cmd_string to specify the full pathname. One 00053 can also modify \ref units_cmd_string to specify a different 00054 <tt>units.dat</tt> file. 00055 00056 Example: 00057 \code 00058 convert_units cu; 00059 cu.insert_cache("in","cm",2.54); 00060 cout << "12 in is " << cu.convert("in","cm",12.0) << " cm. " << endl; 00061 \endcode 00062 00063 \note Combining two conversions allows for some surprising 00064 apparent contradictions from numerical precision errors. If 00065 there are two matching unit conversion pairs which give the same 00066 requested conversion factor, then one can arrange a situation 00067 where the same conversion factor is reported with slightly 00068 different values after adding a related conversion to the table. 00069 One way to fix this is to force the class not to combine two 00070 conversions by setting \ref combine_two_conv to false. 00071 Alternatively, one can ensure that no combination is necessary 00072 by manually adding the desired combination conversion to the 00073 cache after it is first computed. 00074 00075 \future Ideally, a real C++ API for the GNU units command 00076 would be better. 00077 */ 00078 class convert_units { 00079 00080 #ifndef DOXYGEN_INTERNAL 00081 00082 protected: 00083 00084 /// The type for caching unit conversions 00085 typedef struct { 00086 /// The input unit 00087 std::string f; 00088 /// The output unit 00089 std::string t; 00090 /// The conversion factor 00091 double c; 00092 } unit_t; 00093 00094 /// The cache where unit conversions are stored 00095 std::map<std::string,unit_t,string_comp> mcache; 00096 00097 /// The iterator type 00098 typedef std::map<std::string,unit_t,string_comp>::iterator miter; 00099 00100 #endif 00101 00102 public: 00103 00104 /// Verbosity (default 0) 00105 int verbose; 00106 00107 /// (default true) 00108 bool use_gnu_units; 00109 00110 /// (default true) 00111 bool err_on_fail; 00112 00113 /// If true, allow combinations of two conversions (default true) 00114 bool combine_two_conv; 00115 00116 /// Default 'units' 00117 std::string units_cmd_string; 00118 00119 convert_units() { 00120 verbose=0; 00121 use_gnu_units=true; 00122 units_cmd_string="units"; 00123 err_on_fail=true; 00124 combine_two_conv=true; 00125 } 00126 00127 virtual ~convert_units() {} 00128 00129 /** \brief Return the value \c val after converting using units \c 00130 from and \c to 00131 */ 00132 virtual double convert(std::string from, std::string to, double val); 00133 00134 /// Manually insert a unit conversion into the cache 00135 int insert_cache(std::string from, std::string to, double conv); 00136 00137 /// Manually remove a unit conversion into the cache 00138 int remove_cache(std::string from, std::string to); 00139 00140 /// Print the present unit cache to std::cout 00141 int print_cache(); 00142 00143 /// Add conversion factors for energy equivalents 00144 int energy_conv(); 00145 00146 }; 00147 00148 #ifndef DOXYGENP 00149 } 00150 #endif 00151 00152 #endif
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).