Object-oriented Scientific Computing Library: Version 0.910
convert_units.h
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
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.