Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

properties.hpp

Go to the documentation of this file.
00001 #ifndef _PROPERTIES_H
00002 #define _PROPERTIES_H
00003 
00004 #include <ios>
00005 #include <iostream>
00006 #include <string>
00007 #include <sstream>
00008 #include <stdexcept>
00009 #include <map>
00010 #include "global.hpp"
00011 
00012 namespace Arak {
00013 
00014   namespace Util {
00015 
00020     typedef std::map<std::string, std::string> PropertyMap;
00021 
00025     inline const std::string& getp(const PropertyMap& props,
00026            const std::string& name) 
00027       throw (std::invalid_argument) {
00028       PropertyMap::const_iterator it = props.find(name);
00029       if (it == props.end()) {
00030   std::cerr << "Value not specified for property \'"
00031       << name << "\'." << std::endl;
00032   throw std::invalid_argument(name);
00033       } else
00034   return it->second;
00035     }
00036 
00040     inline bool hasp(const PropertyMap& props,
00041          const std::string& name) {
00042       return (props.find(name) != props.end());
00043     }
00044 
00059     template<typename charT, typename traits>
00060     std::basic_istream<charT,traits>&
00061     operator>>(std::basic_istream<charT,traits>& in, PropertyMap& pm) {
00062       while (in.good()) {
00063   // Skip comments and leading whitespace.
00064   in >> skipcomments >> std::ws;
00065   charT c;
00066   std::string name;
00067   bool readEq = false;
00068   // Check that the stream is good.
00069   if (!in.good()) break;
00070   // Read the name.
00071   while (in.get(c)) {
00072     if (c == '=') {
00073       readEq = true;
00074       break;
00075     } else if (std::isspace(c, std::locale("")))
00076       break;
00077     name += c;
00078   }
00079   if (in.bad()) {
00080     in.setstate(std::ios_base::failbit);
00081     break;
00082   }
00083   // If the equal sign has not been read off, read it.
00084   if (!readEq) {
00085     in >> skipcomments >> std::ws >> c;
00086     if (in.bad() || (c != '=')) {
00087       in.setstate(std::ios_base::failbit);
00088       break;
00089     }
00090   }
00091   // Read the value.
00092   std::string value;
00093   in >> skipcomments >> std::ws >> value;
00094   if (in.bad()) {
00095     in.setstate(std::ios_base::failbit);
00096     break;
00097   }
00098   // Store the pair.
00099   pm[name] = value;
00100       }
00101       return in;
00102     }
00103 
00111     template<typename charT, typename traits>
00112     std::basic_ostream<charT,traits>&
00113     operator<<(std::basic_ostream<charT,traits>& out, const PropertyMap& pm) {
00114       // Compute the width of the widest name.
00115       int width = 0;
00116       for (PropertyMap::const_iterator it = pm.begin(); it != pm.end(); it++) {
00117   const PropertyMap::value_type& pair = *it;
00118   const std::string& name = pair.first;
00119   width = std::max<int>(width, name.length());
00120       }
00121       // Print the pairs.
00122       for (PropertyMap::const_iterator it = pm.begin(); it != pm.end(); it++) {
00123   const PropertyMap::value_type& pair = *it;
00124   out << pair.first;
00125   for (int i = pair.first.length(); i < width; i++) out.put(' ');
00126   out << " = " << pair.second << std::endl;
00127       }
00128       return out;
00129     }
00130 
00138     template<typename T>
00139     bool parse(const std::string& str, T& value) {
00140       std::istringstream in(str);
00141       in >> value;
00142       return (!in.bad());
00143     }
00144 
00145   } // End of namespace: Arak::Util
00146 
00147 } // End of namespace: Arak
00148 
00149 #endif

Generated on Wed May 25 14:39:18 2005 for Arak by doxygen 1.3.6