This class behaves like a numeric type, but 'records' all computations in expression strings
| 236 | |
| 237 | // This class behaves like a numeric type, but 'records' all computations in expression strings |
| 238 | struct CCode { |
| 239 | static std::vector<string> expressions; |
| 240 | static int find( std::vector<string> &v, string val ){ |
| 241 | int i = 0; |
| 242 | for(auto &s : v) { |
| 243 | if(s==val) |
| 244 | return i; |
| 245 | i++; |
| 246 | } |
| 247 | return -1; |
| 248 | } |
| 249 | |
| 250 | static string strip(string s) { |
| 251 | int n = s.size(); |
| 252 | if(n<=1) return s; |
| 253 | if(s[0] == '(' && s[n-1] == ')') return strip(s.substr(1,n-2)); |
| 254 | return s; |
| 255 | } |
| 256 | mutable string s; |
| 257 | |
| 258 | static CCode Par(const CCode &c) { |
| 259 | return c.s; |
| 260 | } |
| 261 | |
| 262 | void Check() { |
| 263 | static string int_num = "var[0-9]*"; |
| 264 | static regex pattern(int_num); |
| 265 | if(s=="") return; |
| 266 | int index = find( expressions, strip(s)); |
| 267 | if(index>=0) { |
| 268 | s = "var"+ToString(index); |
| 269 | } |
| 270 | else { |
| 271 | if(!regex_match(strip(s), pattern)) { |
| 272 | expressions.push_back(strip(s)); |
| 273 | s = "var"+ToString(expressions.size()-1); |
| 274 | } |
| 275 | } |
| 276 | } |
| 277 | |
| 278 | CCode() : s("") { } |
| 279 | |
| 280 | CCode(const CCode &c) : |
| 281 | s(c.s) |
| 282 | { |
| 283 | Check(); |
| 284 | } |
| 285 | |
| 286 | CCode(string as) : s(as) { |
| 287 | Check(); |
| 288 | } |
| 289 | |
| 290 | CCode(double val) { |
| 291 | std::stringstream str; |
| 292 | str << fixed << setprecision( 15 ) << val; |
| 293 | s = str.str(); |
| 294 | Check(); |
| 295 | } |
no outgoing calls
no test coverage detected