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

/include/cmdioutil2.h

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