PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/include/cmdioutil.h

http://cmdioutil.googlecode.com/
C Header | 935 lines | 662 code | 93 blank | 180 comment | 194 complexity | 5d2b1221f1ba40711117bfb3640c680f MD5 | raw file
  1. // ///////////////////////////// MIT License //////////////////////////////////// //
  2. // //
  3. // Copyright (c) 2010 David Zsolt Manrique //
  4. // david.zsolt.manrique@gmail.com //
  5. // //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy //
  7. // of this software and associated documentation files (the "Software"), to deal //
  8. // in the Software without restriction, including without limitation the rights //
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell //
  10. // copies of the Software, and to permit persons to whom the Software is //
  11. // furnished to do so, subject to the following conditions: //
  12. // //
  13. // The above copyright notice and this permission notice shall be included in //
  14. // all copies or substantial portions of the Software. //
  15. // //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE //
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, //
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN //
  22. // THE SOFTWARE. //
  23. // //
  24. // ////////////////////////////////////////////////////////////////////////////// //
  25. #ifndef CMDIOUTIL_H
  26. #define CMDIOUTIL_H
  27. // standard headers
  28. #include <iostream>
  29. #include <sstream>
  30. #include <fstream>
  31. #include <string>
  32. #include <vector>
  33. #include <list>
  34. #include <set>
  35. #include <map>
  36. #include <iomanip>
  37. #include <cmath>
  38. #include <cstdarg>
  39. #include <stdexcept>
  40. #include <utility>
  41. #include <tuple>
  42. namespace util
  43. {
  44. //! Sort and swap. As result: a < b
  45. template<typename T>
  46. inline void sort(T &a,T &b) { if(b < a) std::swap(a,b); }
  47. //! Sort and swap three variables. As result: a < b < c
  48. template<typename T>
  49. inline void sort(T &a,T &b,T &c)
  50. { if(b < a) std::swap(a,b); if(c < a) std::swap(a,c); if(c < b) std::swap(b,c); }
  51. template<typename Fr,typename To>
  52. bool to(const Fr & fr,To & to)
  53. {
  54. std::stringstream ss;
  55. ss<<fr;
  56. return ss>>to;
  57. }
  58. template<typename T1,typename T2,char d=','>
  59. struct pair_expression : std::tuple<T1,T2>
  60. {
  61. pair_expression() {}
  62. pair_expression(std::string e) { get(e); }
  63. bool get(std::string e)
  64. {
  65. if(e.find_first_of(d) == std::string::npos) return false;
  66. return to(e.substr(0,e.find_first_of(d)),std::get<0>(*this) ) &&
  67. to(e.substr(e.find_first_of(d)+1),std::get<1>(*this));
  68. }
  69. };
  70. template<typename T1,typename T2,char d>
  71. std::istream & operator >> (std::istream & is,pair_expression<T1,T2,d> & x)
  72. {
  73. std::string e; is >> e; if (!x.get(e)) is.setstate(std::ios_base::failbit);
  74. return is;
  75. }
  76. /*
  77. template<typename T1,typename T2,typename T3,char d=','>
  78. struct triple_expression : std::tuple<T1,T2,T3>
  79. {
  80. triple_expression() {}
  81. triple_expression(std::string e) { get(e); }
  82. bool get(std::string e)
  83. {
  84. size_t pos1 = e.find_first_of(d);
  85. size_t pos2 = e.find_first_of(d,pos1+1);
  86. if( (pos1 == std::string::npos) || (pos2 == std::string::npos) ) return false;
  87. return to(e.substr(0,pos1),std::get<0>(*this) ) &&
  88. to(e.substr(pos1+1,pos2-pos1-1),std::get<1>(*this)) &&
  89. to(e.substr(pos2+1),std::get<2>(*this));
  90. }
  91. };
  92. template<typename T1,typename T2,typename T3,char d>
  93. std::istream & operator >> (std::istream & is,triple_expression<T1,T2,T3,d> & x)
  94. {
  95. std::string e; is >> e; if (!x.get(e)) is.setstate(std::ios_base::failbit);
  96. return is;
  97. }
  98. */
  99. template<typename T1,typename T2,typename T3,char d1=',',char d2=d1>
  100. struct triple_expression : std::tuple<T1,T2,T3>
  101. {
  102. triple_expression() {}
  103. triple_expression(std::string e) { get(e); }
  104. bool get(std::string e)
  105. {
  106. size_t pos1 = e.find_first_of(d1);
  107. size_t pos2 = e.find_first_of(d2,pos1+1);
  108. if( (pos1 == std::string::npos) || (pos2 == std::string::npos) ) return false;
  109. return to(e.substr(0,pos1),std::get<0>(*this) ) &&
  110. to(e.substr(pos1+1,pos2-pos1-1),std::get<1>(*this)) &&
  111. to(e.substr(pos2+1),std::get<2>(*this));
  112. }
  113. };
  114. template<typename T1,typename T2,typename T3,char d1,char d2>
  115. std::istream & operator >> (std::istream & is,triple_expression<T1,T2,T3,d1,d2> & x)
  116. {
  117. std::string e; is >> e; if (!x.get(e)) is.setstate(std::ios_base::failbit);
  118. return is;
  119. }
  120. template<typename T,typename A,char d>
  121. void pair2array(const pair_expression<T,T,d> & ex,A & arr)
  122. {
  123. arr[0] = std::get<0>(ex);
  124. arr[1] = std::get<1>(ex);
  125. }
  126. template<typename T,typename A,char d1,char d2>
  127. void triple2array(const triple_expression<T,T,T,d1,d2> & ex,A & arr)
  128. {
  129. arr[0] = std::get<0>(ex);
  130. arr[1] = std::get<1>(ex);
  131. arr[2] = std::get<2>(ex);
  132. }
  133. template<typename T1,typename T2,typename T3,typename T4,char d1=',',char d2=d1,char d3=d2>
  134. struct quad_expression : std::tuple<T1,T2,T3,T4>
  135. {
  136. quad_expression() {}
  137. quad_expression(std::string e) { get(e); }
  138. bool get(std::string e)
  139. {
  140. size_t pos1 = e.find_first_of(d1);
  141. size_t pos2 = e.find_first_of(d2,pos1+1);
  142. size_t pos3 = e.find_first_of(d3,pos2+1);
  143. if( (pos1 == std::string::npos) || (pos2 == std::string::npos) || (pos3 == std::string::npos) ) return false;
  144. return to(e.substr(0,pos1),std::get<0>(*this) ) &&
  145. to(e.substr(pos1+1,pos2-pos1-1),std::get<1>(*this)) &&
  146. to(e.substr(pos2+1,pos3-pos2-1),std::get<2>(*this)) &&
  147. to(e.substr(pos3+1),std::get<3>(*this)); ;
  148. }
  149. };
  150. template<typename T1,typename T2,typename T3,typename T4,char d1,char d2,char d3>
  151. std::istream & operator >> (std::istream & is,quad_expression<T1,T2,T3,T4,d1,d2,d3> & x)
  152. {
  153. std::string e; is >> e; if (!x.get(e)) is.setstate(std::ios_base::failbit);
  154. return is;
  155. }
  156. template<typename T, char d=',', char r=':'>
  157. struct list_expression : std::list<T>
  158. {
  159. list_expression() {}
  160. list_expression(std::string e) { get(e); }
  161. bool get(std::string e)
  162. {
  163. size_t pos = 0;
  164. do
  165. {
  166. size_t pd = e.find_first_of(d,pos);
  167. std::string s = e.substr(pos,pd-pos);
  168. size_t pr = s.find_first_of(r);
  169. if(pr == std::string::npos)
  170. {
  171. T i;
  172. if(to(s,i) == false) return false;
  173. this->push_back(i);
  174. }
  175. else
  176. {
  177. T br,er;
  178. if( to(s.substr(0,pr),br) && to(s.substr(pr+1),er) == false ) return false;
  179. if(br < er)
  180. for(T i = br; i<= er; i++) this->push_back(i);
  181. else
  182. for(T i = br; i>= er; i--) this->push_back(i);
  183. }
  184. pos = pd + 1;
  185. } while (pos-1 != std::string::npos);
  186. return true;
  187. }
  188. };
  189. template<typename T, char d, char r>
  190. std::istream & operator >> (std::istream & is,list_expression<T,d,r> & x)
  191. {
  192. std::string e; is >> e; if (!x.get(e)) is.setstate(std::ios_base::failbit);
  193. return is;
  194. }
  195. //! marked expression class
  196. //! it can be marked or not marked variable with one prefix character
  197. //! note that the expression cannot contain whitespace
  198. template<typename T,char prefix='*'>
  199. struct prefix_expression : std::tuple<T,bool>
  200. {
  201. prefix_expression() {}
  202. prefix_expression(std::string e) { get(e); }
  203. bool get(std::string e)
  204. {
  205. if(e[0] == prefix)
  206. {
  207. std::get<1>(*this) = true;
  208. return to(e.substr(1),std::get<0>(*this));
  209. }
  210. return to(e,std::get<0>(*this));
  211. }
  212. const T & operator* () const { return std::get<0>(*this); }
  213. T & operator* () { return std::get<0>(*this); }
  214. bool operator~ () const { return std::get<1>(*this); }
  215. };
  216. template<typename T, char prefix>
  217. std::istream & operator >> (std::istream & is,prefix_expression<T,prefix> & x)
  218. {
  219. std::string e; is >> e; if (!x.get(e)) is.setstate(std::ios_base::failbit);
  220. return is;
  221. }
  222. //! match function
  223. //! it matches a pattern against a string
  224. //! @param pattern contains the pattern, the output pattern %1 (%2,%3,...)
  225. //! @param m contains the string
  226. //! @param p1 output pointer with T type that takes the value form %1
  227. //! @return true if match was succesfull
  228. //! TODO if it does not match it should not change the parameters
  229. //! TODO temmplate specialization for string->faster
  230. //! TODO c++0x standard variadic template...
  231. inline void trim(std::string & s,const char* chars = "\n\t\v\f\r ")
  232. {
  233. s.erase(s.find_last_not_of(chars)+1);
  234. s.erase(0, s.find_first_not_of(chars));
  235. }
  236. inline void tokenize(const std::string& str,std::vector<std::string>& tokens,const std::string& delimiters = " ")
  237. {
  238. // Skip delimiters at beginning.
  239. std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
  240. // Find first "non-delimiter".
  241. std::string::size_type pos = str.find_first_of(delimiters, lastPos);
  242. while (std::string::npos != pos || std::string::npos != lastPos)
  243. {
  244. // Found a token, add it to the vector.
  245. tokens.push_back(str.substr(lastPos, pos - lastPos));
  246. // Skip delimiters. Note the "not_of"
  247. lastPos = str.find_first_not_of(delimiters, pos);
  248. // Find next "non-delimiter"
  249. pos = str.find_first_of(delimiters, lastPos);
  250. }
  251. }
  252. inline bool match_tokens(const std::vector<std::string> & p_tokens,const std::vector<std::string> & m_tokens,size_t from)
  253. {
  254. size_t i;
  255. for(i = from; i < p_tokens.size(); i++)
  256. if(p_tokens[i] == "%" ) return false;
  257. else if(p_tokens[i] == "+%" ) return false;
  258. else if (p_tokens[i] != m_tokens[i] ) return false;
  259. return true;
  260. }
  261. template<typename Arg>
  262. bool match_tokens(const std::vector<std::string> & p_tokens,const std::vector<std::string> & m_tokens,size_t from,std::vector<Arg>* arg)
  263. {
  264. size_t i;
  265. for(i = from; i < p_tokens.size(); i++)
  266. if(p_tokens[i] == "%" ) throw std::runtime_error("match: unhandled type");
  267. else if(p_tokens[i] == "+%")
  268. {
  269. arg->clear();
  270. for(size_t j = i; j < m_tokens.size(); j++)
  271. {
  272. Arg arg_item;
  273. if(!to(m_tokens[j],arg_item)) return false;
  274. arg->push_back(arg_item);
  275. }
  276. return true;
  277. }
  278. else if (p_tokens[i] != m_tokens[i] ) return false;
  279. return true;
  280. }
  281. template <typename Arg,typename... Args>
  282. bool match_tokens(const std::vector<std::string> & p_tokens,const std::vector<std::string> & m_tokens,size_t from,Arg arg, Args... args)
  283. {
  284. size_t i;
  285. for(i = from; i < p_tokens.size(); i++)
  286. if(p_tokens[i] == "%")
  287. {
  288. if (to(m_tokens[i],*arg)) return match_tokens(p_tokens,m_tokens,i+1,args...);
  289. else return false;
  290. }
  291. else if (p_tokens[i] != m_tokens[i] ) return false;
  292. return true;
  293. }
  294. template <typename... Args>
  295. bool match(const std::string & pattern,const std::string & m,Args & ... args)
  296. {
  297. if(m.size()==0) return false;
  298. std::vector<std::string> p_tokens;
  299. std::vector<std::string> m_tokens;
  300. tokenize(pattern,p_tokens);
  301. tokenize(m,m_tokens);
  302. // >>>> 2010 dec 8
  303. if(m_tokens.size() < p_tokens.size() ) return false;
  304. // <<<<
  305. return match_tokens(p_tokens,m_tokens,0,&args...);
  306. }
  307. }
  308. namespace io
  309. {
  310. //! load each line from a file ignoring commented parts
  311. //! @param ifn input file name
  312. //! @param comment comment string literal, everyting after comment will be ignored
  313. //! @param lines output string vector that contains each line in the file
  314. inline void load(std::string ifn,std::string comment,std::vector<std::string> & lines)
  315. {
  316. std::ifstream ifs(ifn.c_str());
  317. std::string line;
  318. lines.clear();
  319. while(std::getline(ifs,line))
  320. {
  321. line = line.substr(0,line.find(comment));
  322. line.erase(line.find_last_not_of("\n\t\v\f\r ")+1);
  323. line.erase(0, line.find_first_not_of("\n\t\v\f\r "));
  324. lines.push_back(line);
  325. }
  326. ifs.close();
  327. }
  328. //! load each line from a file ignoring commented parts
  329. //! @param ifn input file name
  330. //! @param comment comment string literal, everyting after comment will be ignored
  331. //! @param lines output string vector that contains each line in the file
  332. template<typename T1,typename T2>
  333. inline void load(std::string ifn,std::string comment,std::vector<std::tuple<T1,T2>> & lines)
  334. {
  335. std::ifstream ifs(ifn.c_str());
  336. std::string line;
  337. lines.clear();
  338. while(std::getline(ifs,line))
  339. {
  340. line = line.substr(0,line.find(comment));
  341. T1 item1;
  342. T2 item2;
  343. std::istringstream iss(line);
  344. if(!(iss >> item1)) continue;
  345. if(!(iss >> item2)) continue;
  346. lines.push_back(std::tuple<T1,T2>(item1,item2));
  347. }
  348. ifs.close();
  349. }
  350. //! load each line from a file ignoring commented parts
  351. //! @param is input stream
  352. //! @param comment comment string literal, everyting after comment will be ignored
  353. //! @param lines output string vector that contains each line in the file
  354. inline void load(std::istream & is,std::string comment,std::vector<std::string> & lines)
  355. {
  356. std::string line;
  357. lines.clear();
  358. while(std::getline(is,line))
  359. {
  360. line = line.substr(0,line.find(comment));
  361. line.erase(line.find_last_not_of("\n\t\v\f\r ")+1);
  362. line.erase(0, line.find_first_not_of("\n\t\v\f\r "));
  363. lines.push_back(line);
  364. }
  365. }
  366. //! extract lines between two block markers
  367. //! @param block_begin a string that marks the begining of the block
  368. //! @param block_end marks the end of the block
  369. //! @param lines input lines that may contains the marked block
  370. //! @param blocklines output lines between the block markers
  371. inline bool parse_block(const std::string & block_begin,const std::string & block_end,
  372. const std::vector<std::string> & lines,std::vector<std::string> & blocklines)
  373. {
  374. blocklines.clear();
  375. size_t i = 0;
  376. while(i < lines.size())
  377. if(lines[i].size() > 0)
  378. {
  379. if(lines[i] == block_begin)
  380. {
  381. i++;
  382. while(i < lines.size())
  383. if(lines[i].size() > 0)
  384. {
  385. if(lines[i] == block_end)
  386. break;
  387. blocklines.push_back(lines[i]);
  388. i++;
  389. }
  390. else i++;
  391. if(lines[i].empty()) return false;
  392. else if(lines[i] != block_end) return false;
  393. }
  394. i++;
  395. }
  396. else i++;
  397. return true;
  398. }
  399. inline bool parse_block(const std::string & block_begin,const std::string & block_end,
  400. const std::vector<std::string> & lines,std::vector<std::vector<std::string> > & blocklines_array)
  401. {
  402. std::vector<std::string> blocklines;
  403. blocklines_array.clear();
  404. size_t i = 0;
  405. while(i < lines.size())
  406. if(lines[i].size() > 0)
  407. {
  408. if(lines[i] == block_begin)
  409. {
  410. i++;
  411. while(i < lines.size())
  412. if(lines[i].size() > 0)
  413. {
  414. if(lines[i] == block_end)
  415. {
  416. blocklines_array.push_back(blocklines);
  417. blocklines.clear();
  418. break;
  419. }
  420. blocklines.push_back(lines[i]);
  421. i++;
  422. }
  423. else i++;
  424. if(lines[i].empty()) return false;
  425. else if(lines[i] != block_end) return false;
  426. }
  427. i++;
  428. }
  429. else i++;
  430. return true;
  431. }
  432. }
  433. namespace cmd
  434. {
  435. //!
  436. //! command line argument class
  437. //! this contains the argc and argv, and the help message.
  438. //!
  439. class arguments
  440. {
  441. private:
  442. std::list<std::string> arglist;
  443. std::list<std::vector<std::string> > help;
  444. public:
  445. //! constructor
  446. //! @param argc argc from main
  447. //! @param argv argv from main
  448. arguments(int argc,char** argv)
  449. {
  450. for(int i = 1; i < argc; i++)
  451. arglist.push_back(argv[i]);
  452. arglist.push_back("--");
  453. }
  454. template<typename T>
  455. friend class posarg;
  456. template<typename T>
  457. friend class vararg;
  458. template<typename T1,typename T2>
  459. friend class varargxx;
  460. template<typename T1,typename T2,typename T3>
  461. friend class varargxxx;
  462. template<typename T1,typename T2,typename T3,typename T4>
  463. friend class varargxxxx;
  464. template<bool def>
  465. friend class switcharg;
  466. template<typename T>
  467. friend class multivararg;
  468. //! print input
  469. void print()
  470. {
  471. for(std::list<std::string>::iterator it = arglist.begin(); it != arglist.end(); it++)
  472. std::cout << *it << std::endl;
  473. std::cout << std::endl;
  474. }
  475. //! print help messgae
  476. //! @param os stream
  477. //! @param name program name
  478. void print_help(std::ostream & os,const std::string & name)
  479. {
  480. int n = 0;
  481. os << "Usage: " << name << ' ';
  482. for(std::list<std::vector<std::string> > :: iterator it = help.begin(); it != help.end(); it++)
  483. if(it->size() == 1) os << "<arg-" << ++n << ">" << ' ';
  484. os << " -[option] <option-arg>" << std::endl;
  485. n = 0;
  486. for(std::list<std::vector<std::string> > :: iterator it = help.begin(); it != help.end(); it++)
  487. if(it->size() == 1)
  488. {
  489. std::ostringstream oss;
  490. oss << "<arg-" << ++n << ">";
  491. os << " " << std::left << std::setw(15) << oss.str() << ' ' << std::left << std::setw(50) << (*it)[0] << std::endl;
  492. }
  493. for(std::list<std::vector<std::string> > :: iterator it = help.begin(); it != help.end(); it++)
  494. if(it->size() == 3)
  495. {
  496. os << " " << std::left << std::setw(5) << (*it)[0] << ' ';
  497. os << std::left << std::setw(20) << (*it)[1] << ' ';
  498. os << std::left << std::setw(50) << (*it)[2] << std::endl;
  499. }
  500. }
  501. };
  502. //! positioned cmd line arguments
  503. template<typename T>
  504. class posarg
  505. {
  506. private:
  507. T var;
  508. bool found;
  509. public:
  510. //! constructor
  511. //! @param args arguments type that contains the command line input
  512. //! @param help simple help message for this input
  513. //! @param def default value of this input
  514. template<typename Tdef>
  515. posarg(arguments & args,const char* help,const Tdef & def) : var(def)
  516. {
  517. std::vector<std::string> help_message;
  518. help_message.push_back(help);
  519. args.help.push_back(help_message);
  520. found = false;
  521. for(std::list<std::string>::iterator it = args.arglist.begin(); it != args.arglist.end(); it++)
  522. if(*it != "--")
  523. {
  524. std::istringstream is(*it);
  525. if ( !(is >> var) )
  526. throw std::runtime_error("Wrong command line arguments. Try --help!");
  527. args.arglist.erase(it);
  528. found = true;
  529. break;
  530. } else break;
  531. }
  532. //! * operator returns with the parsed value
  533. //! @return parsed value
  534. const T & operator * () const { return var; }
  535. //! ~ operator returns if this input was found in the cmd line.
  536. //! @return true if it was found
  537. bool operator ~ () const { return found; }
  538. };
  539. //! optional switch cmd line argument class
  540. //! tempate def contains the default value true/false, if the switch was found
  541. //! it negates
  542. template<bool def>
  543. class switcharg
  544. {
  545. private:
  546. bool var;
  547. bool found;
  548. public:
  549. //! constructor
  550. //! @param args arguments type that contains the command line input
  551. //! @param s short version of the switch
  552. //! @param l long version of the switch
  553. //! @param help simple help message for this input
  554. switcharg(arguments & args,const char* s,const char* l,const char* help) : var(def)
  555. {
  556. std::vector<std::string> help_message;
  557. help_message.push_back(s);
  558. help_message.push_back(l);
  559. help_message.push_back(help);
  560. args.help.push_back(help_message);
  561. found = false;
  562. for(std::list<std::string>::iterator it = args.arglist.begin(); it != args.arglist.end(); it++)
  563. if(*it != "--") {
  564. if( (*it == s) || (*it == l) )
  565. {
  566. args.arglist.erase(it);
  567. var = !var;
  568. found = true;
  569. break;
  570. }} else break;
  571. }
  572. //! * operator returns with the switch value
  573. //! @return switched value
  574. const bool & operator * () const { return var; }
  575. //! ~ operator returns if the switch was found in the cmd line.
  576. //! @return true if it was found
  577. bool operator ~ () const { return found; }
  578. };
  579. //!
  580. //! simple optional variable input argument class
  581. template<typename T>
  582. class vararg
  583. {
  584. private:
  585. T var;
  586. bool found;
  587. public:
  588. //! constructor
  589. //! @param args arguments type that contains the command line input
  590. //! @param s short version of the switch
  591. //! @param l long version of the switch
  592. //! @param help simple help message for this input
  593. //! @param def defualt value of this input
  594. template<typename Tdef>
  595. vararg(arguments & args,const char* s,const char* l,const char* help,const Tdef & def) : var(def)
  596. {
  597. std::vector<std::string> help_message;
  598. help_message.push_back(s);
  599. help_message.push_back(l);
  600. help_message.push_back(help);
  601. args.help.push_back(help_message);
  602. found = false;
  603. for(std::list<std::string>::iterator it = args.arglist.begin(); it != args.arglist.end(); it++)
  604. if(*it != "--") {
  605. if( (*it == s) || (*it == l) )
  606. {
  607. if( *++it == "--")
  608. throw std::runtime_error("Wrong command line arguments. Try --help!");
  609. std::istringstream is(*it);
  610. if ( !(is >> var) )
  611. throw std::runtime_error("Wrong command line arguments. Try --help!");
  612. it = args.arglist.erase(it);
  613. args.arglist.erase(--it);
  614. found = true;
  615. break;
  616. }} else break;
  617. }
  618. //! * operator returns with the parsed value
  619. //! @return parsed value
  620. const T & operator * () const { return var; }
  621. //! ~ operator returns if the input was found in the cmd line.
  622. //! @return true if it was found
  623. bool operator ~ () const { return found; }
  624. };
  625. //!
  626. //! simple optional variable input argument class
  627. template<typename T1,typename T2>
  628. class varargxx
  629. {
  630. public:
  631. //private:
  632. T1 var1;
  633. T2 var2;
  634. bool found;
  635. public:
  636. //! constructor
  637. //! @param args arguments type that contains the command line input
  638. //! @param s short version of the switch
  639. //! @param l long version of the switch
  640. //! @param help simple help message for this input
  641. //! @param def defualt value of this input
  642. template<typename Tdef1,typename Tdef2>
  643. varargxx(arguments & args,const char* s,const char* l,const char* help,const Tdef1 & def1,const Tdef2 & def2) : var1(def1), var2(def2)
  644. {
  645. std::vector<std::string> help_message;
  646. help_message.push_back(s);
  647. help_message.push_back(l);
  648. help_message.push_back(help);
  649. args.help.push_back(help_message);
  650. found = false;
  651. for(std::list<std::string>::iterator it = args.arglist.begin(); it != args.arglist.end(); it++)
  652. if(*it != "--") {
  653. if( (*it == s) || (*it == l) )
  654. {
  655. if( *++it == "--")
  656. throw std::runtime_error("Wrong command line arguments. Try --help!");
  657. std::istringstream is1(*it);
  658. if ( !(is1 >> var1) )
  659. throw std::runtime_error("Wrong command line arguments. Try --help!");
  660. it = args.arglist.erase(it);
  661. std::istringstream is2(*it);
  662. if ( !(is2 >> var2) )
  663. throw std::runtime_error("Wrong command line arguments. Try --help!");
  664. it = args.arglist.erase(it);
  665. args.arglist.erase(--it);
  666. found = true;
  667. break;
  668. }} else break;
  669. }
  670. //! * operator returns with the parsed value
  671. //! @return parsed value
  672. // const std::tuple<T1,T2> operator * () const { return std::tie(var1,var2); }
  673. //! ~ operator returns if the input was found in the cmd line.
  674. //! @return true if it was found
  675. bool operator ~ () const { return found; }
  676. };
  677. //!
  678. //! simple optional variable input argument class
  679. template<typename T1,typename T2,typename T3>
  680. class varargxxx
  681. {
  682. public:
  683. //private:
  684. T1 var1;
  685. T2 var2;
  686. T3 var3;
  687. bool found;
  688. public:
  689. //! constructor
  690. //! @param args arguments type that contains the command line input
  691. //! @param s short version of the switch
  692. //! @param l long version of the switch
  693. //! @param help simple help message for this input
  694. //! @param def defualt value of this input
  695. template<typename Tdef1,typename Tdef2,typename Tdef3>
  696. varargxxx(arguments & args,const char* s,const char* l,const char* help,const Tdef1 & def1,const Tdef2 & def2,const Tdef3 & def3) : var1(def1), var2(def2), var3(def3)
  697. {
  698. std::vector<std::string> help_message;
  699. help_message.push_back(s);
  700. help_message.push_back(l);
  701. help_message.push_back(help);
  702. args.help.push_back(help_message);
  703. found = false;
  704. for(std::list<std::string>::iterator it = args.arglist.begin(); it != args.arglist.end(); it++)
  705. if(*it != "--") {
  706. if( (*it == s) || (*it == l) )
  707. {
  708. if( *++it == "--")
  709. throw std::runtime_error("Wrong command line arguments. Try --help!");
  710. std::istringstream is1(*it);
  711. if ( !(is1 >> var1) )
  712. throw std::runtime_error("Wrong command line arguments. Try --help!");
  713. it = args.arglist.erase(it);
  714. std::istringstream is2(*it);
  715. if ( !(is2 >> var2) )
  716. throw std::runtime_error("Wrong command line arguments. Try --help!");
  717. it = args.arglist.erase(it);
  718. std::istringstream is3(*it);
  719. if ( !(is3 >> var3) )
  720. throw std::runtime_error("Wrong command line arguments. Try --help!");
  721. it = args.arglist.erase(it);
  722. args.arglist.erase(--it);
  723. found = true;
  724. break;
  725. }} else break;
  726. }
  727. //! * operator returns with the parsed value
  728. //! @return parsed value
  729. const std::tuple<T1,T2,T3> operator * () const { return std::tie(var1,var2,var3); }
  730. //! ~ operator returns if the input was found in the cmd line.
  731. //! @return true if it was found
  732. bool operator ~ () const { return found; }
  733. };
  734. //!
  735. //! simple optional variable input argument class
  736. template<typename T1,typename T2,typename T3,typename T4>
  737. class varargxxxx
  738. {
  739. public:
  740. T1 var1;
  741. T2 var2;
  742. T3 var3;
  743. T4 var4;
  744. bool found;
  745. public:
  746. //! constructor
  747. //! @param args arguments type that contains the command line input
  748. //! @param s short version of the switch
  749. //! @param l long version of the switch
  750. //! @param help simple help message for this input
  751. //! @param def defualt value of this input
  752. template<typename Tdef1,typename Tdef2,typename Tdef3,typename Tdef4>
  753. varargxxxx(arguments & args,const char* s,const char* l,const char* help,const Tdef1 & def1,const Tdef2 & def2,const Tdef3 & def3,const Tdef4 & def4) : var1(def1), var2(def2), var3(def3), var4(def4)
  754. {
  755. std::vector<std::string> help_message;
  756. help_message.push_back(s);
  757. help_message.push_back(l);
  758. help_message.push_back(help);
  759. args.help.push_back(help_message);
  760. found = false;
  761. for(std::list<std::string>::iterator it = args.arglist.begin(); it != args.arglist.end(); it++)
  762. if(*it != "--") {
  763. if( (*it == s) || (*it == l) )
  764. {
  765. if( *++it == "--")
  766. throw std::runtime_error("Wrong command line arguments. Try --help!");
  767. std::istringstream is1(*it);
  768. if ( !(is1 >> var1) )
  769. throw std::runtime_error("Wrong command line arguments. Try --help!");
  770. it = args.arglist.erase(it);
  771. std::istringstream is2(*it);
  772. if ( !(is2 >> var2) )
  773. throw std::runtime_error("Wrong command line arguments. Try --help!");
  774. it = args.arglist.erase(it);
  775. std::istringstream is3(*it);
  776. if ( !(is3 >> var3) )
  777. throw std::runtime_error("Wrong command line arguments. Try --help!");
  778. it = args.arglist.erase(it);
  779. std::istringstream is4(*it);
  780. if ( !(is4 >> var4) )
  781. throw std::runtime_error("Wrong command line arguments. Try --help!");
  782. it = args.arglist.erase(it);
  783. args.arglist.erase(--it);
  784. found = true;
  785. break;
  786. }} else break;
  787. }
  788. //! * operator returns with the parsed value
  789. //! @return parsed value
  790. const std::tuple<T1,T2,T3,T4> operator * () const { return std::tie(var1,var2,var3,var4); }
  791. //! ~ operator returns if the input was found in the cmd line.
  792. //! @return true if it was found
  793. bool operator ~ () const { return found; }
  794. };
  795. //! optional variable input argument that can occur more than once
  796. template<typename T>
  797. class multivararg
  798. {
  799. private:
  800. typename std::vector<T> var;
  801. bool found;
  802. public:
  803. //! constructor
  804. //! @param args arguments type that contains the command line input
  805. //! @param s short version of the switch
  806. //! @param l long version of the switch
  807. //! @param help simple help message for this input
  808. //! @param def defualt value of this input
  809. multivararg(arguments & args,const char* s,const char* l,const char* help)
  810. {
  811. std::vector<std::string> help_message;
  812. help_message.push_back(s);
  813. help_message.push_back(l);
  814. help_message.push_back(help);
  815. args.help.push_back(help_message);
  816. found = false;
  817. for(std::list<std::string>::iterator it = args.arglist.begin(); it != args.arglist.end(); it++)
  818. if(*it != "--") {
  819. if( (*it == s) || (*it == l) )
  820. {
  821. if( *++it == "--")
  822. throw std::runtime_error("Wrong command line arguments. Try --help!");
  823. std::istringstream is(*it);
  824. T v;
  825. if ( !(is >> v) )
  826. throw std::runtime_error("Wrong command line arguments. Try --help!");
  827. var.push_back(v);
  828. it = args.arglist.erase(it);
  829. it = args.arglist.erase(--it);
  830. it--;
  831. found = true;
  832. }} else break;
  833. }
  834. //! * operator returns with the parsed value vector
  835. //! @return parsed value vector
  836. const std::vector<T> & operator * () const { return var; }
  837. //! ~ operator returns if the input was found at least once in the cmd line.
  838. //! @return true if it was found
  839. bool operator ~ () const { return found; }
  840. };
  841. }
  842. #endif // CMDIOUTIL_H