pelib
2.0.0
|
00001 /* 00002 Copyright 2015 Nicolas Melot 00003 00004 This file is part of Pelib. 00005 00006 Pelib is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 Pelib is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with Pelib. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 #include <iostream> 00021 #include <pelib/AmplInputData.hpp> 00022 #include <pelib/Vector.hpp> 00023 #include <pelib/CastException.hpp> 00024 #include <pelib/NoDecimalFloatException.hpp> 00025 00026 #ifndef PELIB_AMPLINPUTVECTOR 00027 #define PELIB_AMPLINPUTVECTOR 00028 00029 #ifdef debug 00030 #undef debug 00031 #endif 00032 00033 #define debug(var) std::cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << (var) << "\"" << std::endl; 00034 00035 namespace pelib 00036 { 00038 template <class Key, class Value> 00039 class AmplInputVector: public AmplInputData 00040 { 00041 typedef std::map<Key, Value> VectorType; 00042 00043 public: 00048 AmplInputVector(bool strict = true) 00049 { 00050 this->strict = strict; 00051 } 00052 00054 virtual 00055 AmplInputVector* 00056 clone() const 00057 { 00058 return new AmplInputVector(); 00059 } 00060 00064 virtual 00065 AlgebraData* 00066 parse(std::istream &in) 00067 { 00068 VectorType values; 00069 00070 std::string str((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>()); 00071 boost::cmatch match; // = AlgebraDataParser::match(getDetailedPattern(), str); 00072 if(!boost::regex_match(str.c_str(), match, boost::regex(getDetailedPattern()))) 00073 { 00074 throw ParseException(std::string("String \"").append(str).append("\" doesn't match regex \"").append(getDetailedPattern()).append("\". ")); 00075 } 00076 00077 boost::regex param_vector("(?:\\s*([^\\s]+)\\s+([^\\s]+))"); 00078 std::string remain = match[2]; 00079 const int subs[] = {1, 2}; 00080 boost::sregex_token_iterator iter = make_regex_token_iterator(remain, param_vector, subs, boost::regex_constants::match_default); 00081 boost::sregex_token_iterator end; 00082 00083 int integer_values = 0, total_values = 0; 00084 for(; iter != end; ++iter ) 00085 { 00086 Key key; 00087 Value value; 00088 00089 try 00090 { 00091 key = AlgebraDataParser::convert<Key>(*iter++, strict); 00092 } catch(NoDecimalFloatException &e) 00093 { 00094 std::ostringstream ss; 00095 ss << e.getValue(); 00096 throw ParseException(std::string("Asked a decimal conversion, but \"").append(ss.str()).append("\" is integer.")); 00097 } 00098 00099 try 00100 { 00101 value = AlgebraDataParser::convert<Value>(*iter, strict); 00102 } catch(NoDecimalFloatException &e) 00103 { 00104 std::stringstream ss; 00105 ss << e.getValue(); 00106 ss >> value; 00107 integer_values++; 00108 } 00109 00110 values.insert(std::pair<Key, Value>(key, value)); 00111 total_values++; 00112 } 00113 00114 // If all values could have been parsed as integer, then this is obviously an integer vector rather to a float one 00115 if(integer_values == total_values) 00116 { 00117 //throw NoDecimalFloatException(std::string("Vector only composed of integer-parsable values."), 0); 00118 throw ParseException(std::string("Vector only composed of integer-parsable values.")); 00119 } 00120 00121 return new Vector<Key, Value>(match[1], values); 00122 } 00123 00128 virtual 00129 void 00130 dump(std::ostream &o, const AlgebraData *data) const 00131 { 00132 const Vector<Key, Value> *vector = dynamic_cast<const Vector<Key, Value>*>(data); 00133 if(vector == NULL) throw CastException("parameter \"data\" was not of type \"Vector<Key, Value>\"."); 00134 00135 o << "param: " << vector->getName() << " :=" << std::endl; 00136 VectorType values = vector->getValues(); 00137 00138 for(typename std::map<Key, Value>::const_iterator iter = values.begin(); iter != values.end(); iter++) 00139 { 00140 o << iter->first << " " << iter->second << std::endl; 00141 } 00142 00143 o << ";" << std::endl; 00144 } 00145 00147 virtual 00148 std::string 00149 getDetailedPattern() 00150 { 00151 return "param\\s*:\\s*([^\\s\\n]+)\\s*:=(.+)"; 00152 } 00153 00155 virtual 00156 std::string 00157 getGlobalPattern() 00158 { 00159 return "param\\s*:\\s*[^\\s\\n]+\\s*:=.+"; 00160 } 00161 00162 protected: 00164 bool strict; 00165 private: 00166 }; 00167 } 00168 00169 #undef debug 00170 #endif