cxxutils.cc
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifdef __GNUC__
00037 #if (__GNUC__<3)
00038 #error your C++ compiler is too old. g++ version 3.0 or higher is required.
00039 #endif
00040 #endif
00041
00042 #include <fstream>
00043 #include <sstream>
00044 #include <iostream>
00045 #include <iomanip>
00046 #include <string>
00047 #include <cstdio>
00048 #include <cctype>
00049 #include "cxxutils.h"
00050 #include "datatypes.h"
00051 #include "openmp_support.h"
00052
00053 using namespace std;
00054
00055 bool file_present (const string &filename)
00056 {
00057 ifstream dummy(filename.c_str());
00058 return dummy;
00059 }
00060
00061 void assert_present (const string &filename)
00062 {
00063 if (file_present(filename)) return;
00064 throw Message_error ("Error: file " + filename + " does not exist!");
00065 }
00066
00067 void assert_not_present (const string &filename)
00068 {
00069 if (!file_present(filename)) return;
00070 throw Message_error ("Error: file " + filename + " already exists!");
00071 }
00072
00073 void remove_file (const string &filename)
00074 {
00075 remove (filename.c_str());
00076 }
00077
00078 string trim (const string &orig)
00079 {
00080 string::size_type p1=orig.find_first_not_of(" \t");
00081 if (p1==string::npos) return "";
00082 string::size_type p2=orig.find_last_not_of(" \t");
00083 return orig.substr(p1,p2-p1+1);
00084 }
00085
00086 template<typename T> string dataToString (const T &x)
00087 {
00088 ostringstream strstrm;
00089 strstrm << x;
00090 return trim(strstrm.str());
00091 }
00092
00093 template<> string dataToString (const bool &x)
00094 { return x ? "T" : "F"; }
00095 template<> string dataToString (const string &x)
00096 { return trim(x); }
00097 template<> string dataToString (const float &x)
00098 {
00099 ostringstream strstrm;
00100 strstrm << setprecision(8) << x;
00101 return trim(strstrm.str());
00102 }
00103 template<> string dataToString (const double &x)
00104 {
00105 ostringstream strstrm;
00106 strstrm << setprecision(16) << x;
00107 return trim(strstrm.str());
00108 }
00109
00110 template string dataToString (const signed char &x);
00111 template string dataToString (const unsigned char &x);
00112 template string dataToString (const short &x);
00113 template string dataToString (const unsigned short &x);
00114 template string dataToString (const int &x);
00115 template string dataToString (const unsigned int &x);
00116 template string dataToString (const long &x);
00117 template string dataToString (const unsigned long &x);
00118 template string dataToString (const long long &x);
00119 template string dataToString (const unsigned long long &x);
00120
00121 string intToString(int x, int width)
00122 {
00123 ostringstream strstrm;
00124 strstrm << setw(width) << setfill('0') << x;
00125 return trim(strstrm.str());
00126 }
00127
00128 template<typename T> void stringToData (const string &x, T &value)
00129 {
00130 string error = string("conversion error in stringToData<")
00131 + type2typename<T>()
00132 +">(\""+x+"\")";
00133 istringstream strstrm(x);
00134 strstrm >> value;
00135 if (!strstrm)
00136 throw Message_error(error);
00137
00138 string rest;
00139 strstrm >> rest;
00140
00141 if (rest.length()>0) throw Message_error(error);
00142 }
00143
00144 template<> void stringToData (const string &x, string &value)
00145 { value = trim(x); }
00146
00147 template<> void stringToData (const string &x, bool &value)
00148 {
00149 if ( x=="F" || x=="f" || x=="n" || x=="N" || x=="false" || x==".false."
00150 || x=="FALSE" || x==".FALSE.")
00151 value=false;
00152 else if (x=="T" || x=="t" || x=="y" || x=="Y" || x=="true" || x==".true."
00153 || x=="TRUE" || x==".TRUE.")
00154 value=true;
00155 else
00156 {
00157 string error = string("conversion error in stringToData<bool>(\"")+x+"\")";
00158 throw Message_error (error);
00159 }
00160 }
00161
00162 template void stringToData (const string &x, signed char &value);
00163 template void stringToData (const string &x, unsigned char &value);
00164 template void stringToData (const string &x, short &value);
00165 template void stringToData (const string &x, unsigned short &value);
00166 template void stringToData (const string &x, int &value);
00167 template void stringToData (const string &x, unsigned int &value);
00168 template void stringToData (const string &x, long &value);
00169 template void stringToData (const string &x, unsigned long &value);
00170 template void stringToData (const string &x, long long &value);
00171 template void stringToData (const string &x, unsigned long long &value);
00172 template void stringToData (const string &x, float &value);
00173 template void stringToData (const string &x, double &value);
00174
00175 bool equal_nocase (const string &a, const string &b)
00176 {
00177 if (a.size()!=b.size()) return false;
00178 for (unsigned int m=0; m<a.size(); ++m)
00179 if (tolower(a[m])!=tolower(b[m])) return false;
00180 return true;
00181 }
00182
00183 string tolower(const string &input)
00184 {
00185 string result=input;
00186 for (unsigned int m=0; m<result.size(); ++m)
00187 result[m]=char(tolower(result[m]));
00188 return result;
00189 }
00190
00191
00192 #define SILENT
00193 #ifdef SILENT
00194
00195 void announce_progress (int, int) {}
00196 void announce_progress (double, double, double) {}
00197 void end_announce_progress () {}
00198
00199 #else
00200
00201 void announce_progress (int now, int total)
00202 {
00203 if ((now%(max(total/100,1)))==0)
00204 cout << "\r " << setw(3) << planck_nint ((now*100.)/total)
00205 << "% done\r" << flush;
00206 }
00207
00208 void announce_progress (double now, double last, double total)
00209 {
00210 int lastpercent = int((last/total)*100),
00211 nowpercent = int(( now/total)*100);
00212 if (nowpercent>lastpercent)
00213 cout << "\r " << setw(3) << nowpercent << "% done\r" << flush;
00214 }
00215
00216 void end_announce_progress ()
00217 { cout << endl; }
00218
00219 #endif
00220
00221 static void openmp_status()
00222 {
00223 if (openmp_enabled())
00224 {
00225 cout << "Application was compiled with OpenMP support," << endl;
00226 if (openmp_max_threads() == 1)
00227 cout << "but running with one process only." << endl;
00228 else
00229 cout << "running with up to " << openmp_max_threads()
00230 << " processes." << endl;
00231 }
00232 else
00233 cout << "Application was compiled without OpenMP support;" << endl
00234 << "running in scalar mode." << endl;
00235 }
00236
00237 void announce (const string &name)
00238 {
00239 cout << endl << "+-";
00240 for (unsigned int m=0; m<name.length(); ++m) cout << "-";
00241 cout << "-+" << endl;
00242 cout << "| " << name << " |" << endl;
00243 cout << "+-";
00244 for (unsigned int m=0; m<name.length(); ++m) cout << "-";
00245 cout << "-+" << endl << endl;
00246 openmp_status();
00247 cout << endl;
00248 }
00249
00250 void module_startup (const string &name, int argc, const char **,
00251 int argc_expected, const string &argv_expected)
00252 {
00253 announce (name);
00254 if (argc==argc_expected) return;
00255 cerr << "Usage: " << name << " " << argv_expected << endl;
00256 throw Message_error();
00257 }
00258
00259 void parse_file (const string &filename, map<string,string> &dict)
00260 {
00261 int lineno=0;
00262 dict.clear();
00263 ifstream inp(filename.c_str());
00264 planck_assert (inp,"Could not open parameter file "+filename);
00265 while (inp)
00266 {
00267 string line;
00268 getline(inp, line);
00269 ++lineno;
00270
00271 line=line.substr(0,line.find_first_of("\r"));
00272 line=line.substr(0,line.find_first_of("#"));
00273 line=trim(line);
00274 if (line.size()>0)
00275 {
00276 string::size_type eqpos=line.find("=");
00277 if (eqpos!=string::npos)
00278 {
00279 string key=trim(line.substr(0,eqpos)),
00280 value=trim(line.substr(eqpos+1,string::npos));
00281 if (key=="")
00282 cerr << "Warning: empty key in " << filename << ", line "
00283 << lineno << endl;
00284 else
00285 {
00286 if (dict.find(key)!=dict.end())
00287 cerr << "Warning: key " << key << " multiply defined in "
00288 << filename << ", line " << lineno << endl;
00289 dict[key]=value;
00290 }
00291 }
00292 else
00293 cerr << "Warning: unrecognized format in " << filename << ", line "
00294 << lineno << ":\n" << line << endl;
00295 }
00296 }
00297 }