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
00064 in >> skipcomments >> std::ws;
00065 charT c;
00066 std::string name;
00067 bool readEq = false;
00068
00069 if (!in.good()) break;
00070
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
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
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
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
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
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 }
00146
00147 }
00148
00149 #endif