PageRenderTime 59ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 2ms

/strtk.hpp

http://nanocalc.codeplex.com
C++ Header | 13952 lines | 12870 code | 1030 blank | 52 comment | 867 complexity | 19de77f2d0d1a844554dff52a287624f MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. *****************************************************************
  3. * String Toolkit Library *
  4. * *
  5. * Author: Arash Partow (2002-2014) *
  6. * URL: http://www.partow.net/programming/strtk/index.html *
  7. * *
  8. * Copyright notice: *
  9. * Free use of the String Toolkit Library is permitted under the *
  10. * guidelines and in accordance with the most current version of *
  11. * the Common Public License. *
  12. * http://www.opensource.org/licenses/cpl1.0.php *
  13. * *
  14. *****************************************************************
  15. */
  16. #ifndef INCLUDE_STRTK_HPP
  17. #define INCLUDE_STRTK_HPP
  18. #include <algorithm>
  19. #include <cctype>
  20. #include <cerrno>
  21. #include <cmath>
  22. #include <cstddef>
  23. #include <cstring>
  24. #include <deque>
  25. #include <exception>
  26. #include <fstream>
  27. #include <iostream>
  28. #include <iterator>
  29. #include <limits>
  30. #include <list>
  31. #include <map>
  32. #include <queue>
  33. #include <set>
  34. #include <sstream>
  35. #include <stack>
  36. #include <stdexcept>
  37. #include <string>
  38. #include <utility>
  39. #include <vector>
  40. #ifndef strtk_no_tr1_or_boost
  41. #define strtk_enable_lexical_cast
  42. #define strtk_enable_random
  43. #define strtk_enable_regex
  44. #endif
  45. #ifdef strtk_enable_lexical_cast
  46. #include <boost/lexical_cast.hpp>
  47. #endif
  48. #ifdef strtk_enable_random
  49. // Requires definition of a TR1 compatible random library header
  50. //#include <random>
  51. #include <boost/random.hpp>
  52. #endif
  53. #ifdef strtk_enable_regex
  54. // Requires definition of a TR1 compatible regex library header
  55. //#include <regex>
  56. #include <boost/regex.hpp>
  57. #endif
  58. namespace strtk
  59. {
  60. static const std::size_t one_kilobyte = 1024;
  61. static const std::size_t one_megabyte = 1024 * one_kilobyte;
  62. static const std::size_t one_gigabyte = 1024 * one_megabyte;
  63. static const std::size_t magic_seed = 0xA5A5A5A5;
  64. template <typename Tokenizer, typename Function>
  65. inline std::size_t for_each_token(const std::string& buffer,
  66. Tokenizer& tokenizer,
  67. Function function)
  68. {
  69. std::size_t token_count = 0;
  70. tokenizer.assign(buffer);
  71. typename Tokenizer::iterator itr = tokenizer.begin();
  72. typename Tokenizer::const_iterator end = tokenizer.end();
  73. while (end != itr)
  74. {
  75. function(*itr);
  76. ++itr;
  77. ++token_count;
  78. }
  79. return token_count;
  80. }
  81. template <typename Function>
  82. inline std::size_t for_each_line(std::istream& stream,
  83. Function function,
  84. const std::size_t& buffer_size = one_kilobyte)
  85. {
  86. std::string buffer;
  87. buffer.reserve(buffer_size);
  88. std::size_t line_count = 0;
  89. while (std::getline(stream,buffer))
  90. {
  91. function(buffer);
  92. ++line_count;
  93. }
  94. return line_count;
  95. }
  96. template <typename Function>
  97. inline std::size_t for_each_line_n(std::istream& stream,
  98. const std::size_t& n,
  99. Function function,
  100. const std::size_t& buffer_size = one_kilobyte)
  101. {
  102. std::string buffer;
  103. buffer.reserve(buffer_size);
  104. std::size_t line_count = 0;
  105. while (std::getline(stream,buffer))
  106. {
  107. function(buffer);
  108. if (n == ++line_count)
  109. break;
  110. }
  111. return line_count;
  112. }
  113. template <typename Function>
  114. inline std::size_t for_each_line(const std::string& file_name,
  115. Function function,
  116. const std::size_t& buffer_size = one_kilobyte)
  117. {
  118. std::ifstream stream(file_name.c_str());
  119. if (stream)
  120. return for_each_line(stream,function,buffer_size);
  121. else
  122. return 0;
  123. }
  124. template <typename Function>
  125. inline std::size_t for_each_line_n(const std::string& file_name,
  126. const std::size_t& n,
  127. Function function,
  128. const std::size_t& buffer_size = one_kilobyte)
  129. {
  130. std::ifstream stream(file_name.c_str());
  131. if (stream)
  132. return for_each_line_n(stream,n,function,buffer_size);
  133. else
  134. return 0;
  135. }
  136. template <typename Function>
  137. inline std::size_t for_each_line_conditional(std::istream& stream,
  138. Function function,
  139. const std::size_t& buffer_size = one_kilobyte)
  140. {
  141. std::string buffer;
  142. buffer.reserve(buffer_size);
  143. std::size_t line_count = 0;
  144. while (std::getline(stream,buffer))
  145. {
  146. if (!function(buffer))
  147. {
  148. return line_count;
  149. }
  150. ++line_count;
  151. }
  152. return line_count;
  153. }
  154. template <typename Function>
  155. inline std::size_t for_each_line_n_conditional(std::istream& stream,
  156. const std::size_t& n,
  157. Function function,
  158. const std::size_t& buffer_size = one_kilobyte)
  159. {
  160. std::string buffer;
  161. buffer.reserve(buffer_size);
  162. std::size_t line_count = 0;
  163. while (std::getline(stream,buffer))
  164. {
  165. if (!function(buffer))
  166. {
  167. return line_count;
  168. }
  169. if (n == ++line_count)
  170. break;
  171. }
  172. return line_count;
  173. }
  174. template <typename Function>
  175. inline std::size_t for_each_line_conditional(const std::string& file_name,
  176. Function function,
  177. const std::size_t& buffer_size = one_kilobyte)
  178. {
  179. std::ifstream stream(file_name.c_str());
  180. if (stream)
  181. return for_each_line_conditional(stream,function,buffer_size);
  182. else
  183. return 0;
  184. }
  185. template <typename Function>
  186. inline std::size_t for_each_line_n_conditional(const std::string& file_name,
  187. const std::size_t& n,
  188. Function function,
  189. const std::size_t& buffer_size = one_kilobyte)
  190. {
  191. std::ifstream stream(file_name.c_str());
  192. if (stream)
  193. return for_each_line_n_conditional(stream,n,function,buffer_size);
  194. else
  195. return 0;
  196. }
  197. template <typename T>
  198. inline bool read_line_as_value(std::istream& stream,
  199. T& t,
  200. const std::size_t& buffer_size = one_kilobyte)
  201. {
  202. std::string buffer;
  203. buffer.reserve(buffer_size);
  204. if (!std::getline(stream,buffer))
  205. return false;
  206. else
  207. return string_to_type_converter(buffer,t);
  208. }
  209. namespace details
  210. {
  211. struct not_supported_type_tag {};
  212. struct unsigned_type_tag {};
  213. struct signed_type_tag {};
  214. struct real_type_tag {};
  215. struct byte_type_tag {};
  216. struct bool_type_tag {};
  217. struct hex_number_type_tag {};
  218. struct hex_string_type_tag {};
  219. struct base64_type_tag {};
  220. struct ignore_token_type_tag {};
  221. struct stdstring_type_tag {};
  222. struct stdstring_range_type_tag {};
  223. struct value_type_tag {};
  224. struct sink_type_tag {};
  225. struct stl_seq_type_tag {};
  226. struct attribute_type_tag {};
  227. struct semantic_action_type_tag {};
  228. struct expect_type_tag {};
  229. struct like_type_tag {};
  230. struct inrange_type_tag {};
  231. struct trim_type_tag {};
  232. struct lcase_type_tag {};
  233. struct ucase_type_tag {};
  234. struct fillchararray_type_tag {};
  235. struct truncint_type_tag {};
  236. struct decsink_type_tag {};
  237. template <typename RealType> struct real_type {};
  238. template <> struct real_type<float> { typedef double type; };
  239. template <> struct real_type<double> { typedef double type; };
  240. template <> struct real_type<long double> { typedef long double type; };
  241. template <typename T>
  242. struct supported_conversion_to_type
  243. {
  244. typedef not_supported_type_tag type;
  245. };
  246. template <typename T>
  247. struct supported_conversion_from_type
  248. {
  249. typedef not_supported_type_tag type;
  250. };
  251. template <bool, typename T = void>
  252. struct enable_if {};
  253. template <typename T>
  254. struct enable_if<true, T> { typedef T type; };
  255. template <typename T>
  256. struct supported_iterator_type
  257. {
  258. enum { value = false };
  259. };
  260. template <typename T>
  261. struct is_valid_iterator
  262. {
  263. typedef typename details::enable_if<details::supported_iterator_type<T>::value,T>::type type;
  264. };
  265. template <typename T> struct numeric;
  266. template <typename T> inline std::size_t type_length(const T&);
  267. struct no_t {};
  268. struct yes_t {};
  269. template <typename T>
  270. struct is_pod
  271. {
  272. typedef no_t result_t;
  273. enum { result = false };
  274. };
  275. template <typename T>
  276. struct is_stl_container
  277. { typedef no_t result_t; };
  278. #define register_stl_container1(C) \
  279. template <typename T1, typename T2>struct is_stl_container<C<T1,T2> >{ typedef yes_t result_t; };
  280. #define register_stl_container2(C) \
  281. template <typename T1, typename T2, typename T3>struct is_stl_container<C<T1,T2,T3> >{ typedef yes_t result_t; };
  282. register_stl_container1(std::vector)
  283. register_stl_container1(std::deque)
  284. register_stl_container1(std::list)
  285. register_stl_container1(std::queue)
  286. register_stl_container1(std::stack)
  287. register_stl_container2(std::set)
  288. register_stl_container2(std::multiset)
  289. register_stl_container2(std::priority_queue)
  290. #undef register_stl_container1
  291. #undef register_stl_container2
  292. template <typename T>
  293. void convert_type_assert(){}
  294. } // namespace details
  295. template <typename Iterator, typename T>
  296. inline bool string_to_type_converter(const Iterator begin, const Iterator end, T& t)
  297. {
  298. typedef typename details::is_valid_iterator<Iterator>::type itr_type;
  299. typename details::supported_conversion_to_type<T>::type type;
  300. details::convert_type_assert<itr_type>();
  301. Iterator itr = begin;
  302. return string_to_type_converter_impl(itr,end,t,type);
  303. }
  304. template <typename Iterator, typename T>
  305. inline bool string_to_type_converter(const std::pair<Iterator,Iterator>& range, T& t)
  306. {
  307. return string_to_type_converter(range.first,range.second,t);
  308. }
  309. template <typename T, typename Iterator>
  310. inline T string_to_type_converter(const Iterator begin, const Iterator end)
  311. {
  312. typedef typename details::is_valid_iterator<Iterator>::type itr_type;
  313. typename details::supported_conversion_to_type<T>::type type;
  314. details::convert_type_assert<itr_type>();
  315. T t;
  316. Iterator itr = begin;
  317. if (string_to_type_converter_impl(itr,end,t,type))
  318. return t;
  319. else
  320. throw std::invalid_argument("string_to_type_converter() - Failed to convert: " +
  321. std::string(begin,end));
  322. }
  323. template <typename T, typename Iterator>
  324. inline T string_to_type_converter(const std::pair<Iterator,Iterator>& range)
  325. {
  326. return string_to_type_converter<T>(range.first,range.second);
  327. }
  328. template <typename T>
  329. inline bool string_to_type_converter(const std::string& s, T& t)
  330. {
  331. return string_to_type_converter<const char*,T>(s.data(),s.data() + s.size(),t);
  332. }
  333. template <typename T>
  334. inline T string_to_type_converter(const std::string& s)
  335. {
  336. return string_to_type_converter<T>(s.data(),s.data() + s.size());
  337. }
  338. template <typename T>
  339. inline bool type_to_string(const T& t, std::string& s)
  340. {
  341. typename details::supported_conversion_from_type<T>::type type;
  342. return type_to_string_converter_impl(t,s,type);
  343. }
  344. template <typename T>
  345. inline std::string type_to_string(const T& t)
  346. {
  347. std::string s;
  348. if (type_to_string<T>(t,s))
  349. return s;
  350. else
  351. throw std::invalid_argument("type_to_string() - Failed to convert type to string");
  352. }
  353. #define strtk_begin_register_string_to_type \
  354. namespace strtk { namespace details { \
  355. #define strtk_end_register_string_to_type \
  356. }} \
  357. #define strtk_string_to_type_begin(Type) \
  358. namespace strtk { namespace details { template <typename Iterator> \
  359. inline bool string_to_type_converter_impl(const Iterator& begin, const Iterator& end, \
  360. Type& t, details::not_supported_type_tag&) { \
  361. #define strtk_string_to_type_end() \
  362. }}} \
  363. template <typename T,
  364. typename Allocator,
  365. template <typename,typename> class Sequence>
  366. inline std::size_t load_from_text_file(std::istream& stream,
  367. Sequence<T,Allocator>& sequence,
  368. const std::size_t& buffer_size = one_kilobyte)
  369. {
  370. if (!stream) return 0;
  371. std::string buffer;
  372. buffer.reserve(buffer_size);
  373. std::size_t line_count = 0;
  374. while (std::getline(stream,buffer))
  375. {
  376. ++line_count;
  377. sequence.push_back(string_to_type_converter<T>(buffer));
  378. }
  379. return line_count;
  380. }
  381. template <typename T,
  382. typename Comparator,
  383. typename Allocator>
  384. inline std::size_t load_from_text_file(std::istream& stream,
  385. std::set<T,Comparator,Allocator>& set,
  386. const std::size_t& buffer_size = one_kilobyte)
  387. {
  388. if (!stream) return 0;
  389. std::string buffer;
  390. buffer.reserve(buffer_size);
  391. std::size_t line_count = 0;
  392. while (std::getline(stream,buffer))
  393. {
  394. ++line_count;
  395. set.insert(string_to_type_converter<T>(buffer));
  396. }
  397. return line_count;
  398. }
  399. template <typename T,
  400. typename Comparator,
  401. typename Allocator>
  402. inline std::size_t load_from_text_file(std::istream& stream,
  403. std::multiset<T,Comparator,Allocator>& multiset,
  404. const std::size_t& buffer_size = one_kilobyte)
  405. {
  406. if (!stream) return 0;
  407. std::string buffer;
  408. buffer.reserve(buffer_size);
  409. std::size_t line_count = 0;
  410. while (std::getline(stream,buffer))
  411. {
  412. ++line_count;
  413. multiset.insert(string_to_type_converter<T>(buffer));
  414. }
  415. return line_count;
  416. }
  417. template <typename T, typename Container>
  418. inline std::size_t load_from_text_file(std::istream& stream,
  419. std::queue<T,Container>& queue,
  420. const std::size_t& buffer_size = one_kilobyte)
  421. {
  422. if (!stream) return 0;
  423. std::string buffer;
  424. buffer.reserve(buffer_size);
  425. std::size_t line_count = 0;
  426. while (std::getline(stream,buffer))
  427. {
  428. ++line_count;
  429. queue.push(string_to_type_converter<T>(buffer));
  430. }
  431. return line_count;
  432. }
  433. template <typename T, typename Container>
  434. inline std::size_t load_from_text_file(std::istream& stream,
  435. std::stack<T,Container>& stack,
  436. const std::size_t& buffer_size = one_kilobyte)
  437. {
  438. if (!stream) return 0;
  439. std::string buffer;
  440. buffer.reserve(buffer_size);
  441. std::size_t line_count = 0;
  442. while (std::getline(stream,buffer))
  443. {
  444. ++line_count;
  445. stack.push(string_to_type_converter<T>(buffer));
  446. }
  447. return line_count;
  448. }
  449. template <typename T,
  450. typename Container,
  451. typename Comparator>
  452. inline std::size_t load_from_text_file(std::istream& stream,
  453. std::priority_queue<T,Container,Comparator>& priority_queue,
  454. const std::size_t& buffer_size = one_kilobyte)
  455. {
  456. if (!stream) return 0;
  457. std::string buffer;
  458. buffer.reserve(buffer_size);
  459. std::size_t line_count = 0;
  460. while (std::getline(stream,buffer))
  461. {
  462. ++line_count;
  463. priority_queue.push(string_to_type_converter<T>(buffer));
  464. }
  465. return line_count;
  466. }
  467. template <typename T,
  468. typename Allocator,
  469. template <typename,typename> class Sequence>
  470. inline std::size_t load_from_text_file(const std::string& file_name,
  471. Sequence<T,Allocator>& sequence,
  472. const std::size_t& buffer_size = one_kilobyte)
  473. {
  474. std::ifstream stream(file_name.c_str());
  475. if (!stream)
  476. return 0;
  477. else
  478. return load_from_text_file(stream,sequence,buffer_size);
  479. }
  480. template <typename T,
  481. typename Comparator,
  482. typename Allocator>
  483. inline std::size_t load_from_text_file(const std::string& file_name,
  484. std::set<T,Comparator,Allocator>& set,
  485. const std::size_t& buffer_size = one_kilobyte)
  486. {
  487. std::ifstream stream(file_name.c_str());
  488. if (!stream)
  489. return 0;
  490. else
  491. return load_from_text_file(stream,set,buffer_size);
  492. }
  493. template <typename T,
  494. typename Comparator,
  495. typename Allocator>
  496. inline std::size_t load_from_text_file(const std::string& file_name,
  497. std::multiset<T,Comparator,Allocator>& multiset,
  498. const std::size_t& buffer_size = one_kilobyte)
  499. {
  500. std::ifstream stream(file_name.c_str());
  501. if (!stream)
  502. return 0;
  503. else
  504. return load_from_text_file(stream,multiset,buffer_size);
  505. }
  506. template <typename T, typename Container>
  507. inline std::size_t load_from_text_file(const std::string& file_name,
  508. std::queue<T,Container>& queue,
  509. const std::size_t& buffer_size = one_kilobyte)
  510. {
  511. std::ifstream stream(file_name.c_str());
  512. if (!stream)
  513. return 0;
  514. else
  515. return load_from_text_file(stream,queue,buffer_size);
  516. }
  517. template <typename T, typename Container>
  518. inline std::size_t load_from_text_file(const std::string& file_name,
  519. std::stack<T,Container>& stack,
  520. const std::size_t& buffer_size = one_kilobyte)
  521. {
  522. std::ifstream stream(file_name.c_str());
  523. if (!stream)
  524. return 0;
  525. else
  526. return load_from_text_file(stream,stack,buffer_size);
  527. }
  528. template <typename T,
  529. typename Container,
  530. typename Comparator>
  531. inline std::size_t load_from_text_file(const std::string& file_name,
  532. std::priority_queue<T,Container,Comparator>& priority_queue,
  533. const std::size_t& buffer_size = one_kilobyte)
  534. {
  535. std::ifstream stream(file_name.c_str());
  536. if (!stream)
  537. return 0;
  538. else
  539. return load_from_text_file(stream,priority_queue,buffer_size);
  540. }
  541. template <typename T,
  542. typename Allocator,
  543. template <typename,typename> class Sequence>
  544. inline std::size_t write_to_text_file(std::ostream& stream,
  545. const Sequence<T,Allocator>& sequence,
  546. const std::string& delimiter = "")
  547. {
  548. if (!stream) return 0;
  549. std::size_t count = 0;
  550. typename Sequence<T,Allocator>::const_iterator itr = sequence.begin();
  551. typename Sequence<T,Allocator>::const_iterator end = sequence.end();
  552. if (!delimiter.empty())
  553. {
  554. while (end != itr)
  555. {
  556. stream << (*itr) << delimiter;
  557. ++itr;
  558. ++count;
  559. }
  560. }
  561. else
  562. {
  563. while (end != itr)
  564. {
  565. stream << (*itr);
  566. ++itr;
  567. ++count;
  568. }
  569. }
  570. return count;
  571. }
  572. template <typename T,
  573. typename Comparator,
  574. typename Allocator>
  575. inline std::size_t write_to_text_file(std::ostream& stream,
  576. const std::set<T,Comparator,Allocator>& set,
  577. const std::string& delimiter = "")
  578. {
  579. if (!stream) return 0;
  580. std::size_t count = 0;
  581. typename std::set<T,Comparator,Allocator>::const_iterator itr = set.begin();
  582. typename std::set<T,Comparator,Allocator>::const_iterator end = set.end();
  583. if (!delimiter.empty())
  584. {
  585. while (end != itr)
  586. {
  587. stream << (*itr) << delimiter;
  588. ++itr;
  589. ++count;
  590. }
  591. }
  592. else
  593. {
  594. while (end != itr)
  595. {
  596. stream << (*itr);
  597. ++itr;
  598. ++count;
  599. }
  600. }
  601. return count;
  602. }
  603. template <typename T,
  604. typename Comparator,
  605. typename Allocator>
  606. inline std::size_t write_to_text_file(std::ostream& stream,
  607. const std::multiset<T,Comparator,Allocator>& multiset,
  608. const std::string& delimiter = "")
  609. {
  610. if (!stream) return 0;
  611. std::size_t count = 0;
  612. typename std::multiset<T,Comparator,Allocator>::const_iterator itr = multiset.begin();
  613. typename std::multiset<T,Comparator,Allocator>::const_iterator end = multiset.end();
  614. if (!delimiter.empty())
  615. {
  616. while (end != itr)
  617. {
  618. stream << (*itr) << delimiter;
  619. ++itr;
  620. ++count;
  621. }
  622. }
  623. else
  624. {
  625. while (end != itr)
  626. {
  627. stream << (*itr);
  628. ++itr;
  629. ++count;
  630. }
  631. }
  632. return count;
  633. }
  634. template <typename T,
  635. typename Allocator,
  636. template <typename,typename> class Sequence>
  637. inline std::size_t write_to_text_file(const std::string& file_name,
  638. const Sequence<T,Allocator>& sequence,
  639. const std::string& delimiter = "")
  640. {
  641. std::ofstream stream(file_name.c_str());
  642. if (!stream)
  643. return 0;
  644. else
  645. return write_to_text_file(stream,sequence,delimiter);
  646. }
  647. template <typename T,
  648. typename Comparator,
  649. typename Allocator>
  650. inline std::size_t write_to_text_file(const std::string& file_name,
  651. const std::set<T,Comparator,Allocator>& set,
  652. const std::string& delimiter = "")
  653. {
  654. std::ofstream stream(file_name.c_str());
  655. if (!stream)
  656. return 0;
  657. else
  658. return write_to_text_file(stream,set,delimiter);
  659. }
  660. template <typename T,
  661. typename Comparator,
  662. typename Allocator>
  663. inline std::size_t write_to_text_file(const std::string& file_name,
  664. const std::multiset<T,Comparator,Allocator>& multiset,
  665. const std::string& delimiter = "")
  666. {
  667. std::ofstream stream(file_name.c_str());
  668. if (!stream)
  669. return 0;
  670. else
  671. return write_to_text_file(stream,multiset,delimiter);
  672. }
  673. template <typename InputIterator, typename OutputIterator>
  674. inline void copy_n(InputIterator itr, std::size_t n, OutputIterator out)
  675. {
  676. while (n)
  677. {
  678. (*out) = (*itr);
  679. ++itr;
  680. ++out;
  681. --n;
  682. }
  683. }
  684. template <typename Predicate,
  685. typename InputIterator,
  686. typename OutputIterator>
  687. inline void copy_if(Predicate predicate,
  688. const InputIterator begin, const InputIterator end,
  689. OutputIterator out)
  690. {
  691. InputIterator itr = begin;
  692. while (end != itr)
  693. {
  694. if (predicate(*itr))
  695. {
  696. *(out++) = (*itr);
  697. }
  698. ++itr;
  699. }
  700. }
  701. template <typename Predicate,
  702. typename InputIterator,
  703. typename OutputIterator>
  704. inline InputIterator copy_while(Predicate predicate,
  705. const InputIterator begin, const InputIterator end,
  706. OutputIterator out)
  707. {
  708. InputIterator itr = begin;
  709. while (end != itr)
  710. {
  711. if (!predicate(*itr))
  712. return itr;
  713. *(out++) = *(itr++);
  714. }
  715. return end;
  716. }
  717. template <typename Predicate,
  718. typename InputIterator,
  719. typename OutputIterator>
  720. inline InputIterator copy_until(Predicate predicate,
  721. const InputIterator begin, const InputIterator end,
  722. OutputIterator out)
  723. {
  724. InputIterator itr = begin;
  725. while (end != itr)
  726. {
  727. if (predicate(*itr))
  728. return itr;
  729. *(out++) = *(itr++);
  730. }
  731. return end;
  732. }
  733. template <typename InputIterator, typename OutputIterator>
  734. inline void extract_unique(const InputIterator begin, const InputIterator end,
  735. OutputIterator out)
  736. {
  737. typedef typename std::iterator_traits<InputIterator>::value_type T;
  738. std::vector<T> buffer(begin,end);
  739. std::sort(buffer.begin(),buffer.end());
  740. std::unique_copy(buffer.begin(),buffer.end(),out);
  741. }
  742. template <typename Predicate, typename InputIterator>
  743. inline bool range_only_contains(Predicate predicate,
  744. const InputIterator begin,
  745. const InputIterator end)
  746. {
  747. InputIterator itr = begin;
  748. while (end != itr)
  749. {
  750. if (!predicate(*itr))
  751. {
  752. return false;
  753. }
  754. ++itr;
  755. }
  756. return true;
  757. }
  758. namespace range
  759. {
  760. template <typename T>
  761. class adapter
  762. {
  763. public:
  764. typedef T value_type;
  765. typedef T* iterator;
  766. typedef const iterator const_iterator;
  767. adapter(T* const begin, T* const end)
  768. : begin_(begin),
  769. end_(end)
  770. {}
  771. adapter(const std::pair<T*,T*>& r)
  772. : begin_(r.first),
  773. end_(r.second)
  774. {}
  775. adapter(T* const begin, const std::size_t length)
  776. : begin_(begin),
  777. end_(begin_ + length)
  778. {}
  779. inline iterator begin() const
  780. {
  781. return begin_;
  782. }
  783. inline iterator end() const
  784. {
  785. return end_;
  786. }
  787. inline std::size_t size() const
  788. {
  789. return std::distance(begin_,end_);
  790. }
  791. inline operator std::string() const
  792. {
  793. return stringify(begin_,end_);
  794. }
  795. inline const T& operator[](const std::size_t& index) const
  796. {
  797. return *(begin_ + index);
  798. }
  799. inline T& operator[](const std::size_t& index)
  800. {
  801. return *(begin_ + index);
  802. }
  803. private:
  804. template <typename Type>
  805. static inline std::string stringify(Type*,Type*)
  806. {
  807. static std::string result = "";
  808. return result;
  809. }
  810. static inline std::string stringify(const char* begin, const char* end)
  811. {
  812. return std::string(begin,end);
  813. }
  814. iterator begin_;
  815. iterator end_;
  816. };
  817. typedef adapter<const char> string;
  818. typedef adapter<const unsigned char> ustring;
  819. template <typename T>
  820. inline adapter<T> type(const T* begin, const T* end)
  821. {
  822. return adapter<T>(begin,end);
  823. }
  824. template <typename T, std::size_t N>
  825. inline adapter<T> type(const T (&t)[N])
  826. {
  827. return adapter<T>(t,N);
  828. }
  829. static inline adapter<const char> type(const std::string& s)
  830. {
  831. return adapter<const char>(s.data(),s.size());
  832. }
  833. template <typename T,
  834. typename Allocator,
  835. template <typename,typename> class Sequence>
  836. inline adapter<typename Sequence<T,Allocator>::iterator> type(const Sequence<T,Allocator>& seq)
  837. {
  838. return adapter<typename Sequence<T,Allocator>::iterator>(seq.begin(),seq.end());
  839. }
  840. inline std::string as_string(const adapter<const char>& a)
  841. {
  842. return std::string(a.begin(),a.end());
  843. }
  844. inline std::string as_string(const adapter<const unsigned char>& a)
  845. {
  846. return std::string(a.begin(),a.end());
  847. }
  848. } // namespace range
  849. template <typename T>
  850. struct single_delimiter_predicate
  851. {
  852. public:
  853. typedef T value_type;
  854. single_delimiter_predicate(const T& d)
  855. : delimiter_(d)
  856. {}
  857. inline bool operator()(const T& d) const
  858. {
  859. return delimiter_ == d;
  860. }
  861. private:
  862. single_delimiter_predicate<T>& operator=(const single_delimiter_predicate<T>&);
  863. const T delimiter_;
  864. };
  865. template <typename T>
  866. struct multiple_delimiter_predicate
  867. {
  868. public:
  869. typedef T value_type;
  870. multiple_delimiter_predicate(const T* d_begin, const T* d_end)
  871. : length_(std::distance(d_begin,d_end)),
  872. delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
  873. delimiter_end_(delimiter_ + length_)
  874. {
  875. std::copy(d_begin,d_end, delimiter_);
  876. }
  877. multiple_delimiter_predicate(const T d[], const std::size_t& length)
  878. : length_(length),
  879. delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
  880. delimiter_end_(delimiter_ + length_)
  881. {
  882. std::copy(d,d + length, delimiter_);
  883. }
  884. template <typename Iterator>
  885. multiple_delimiter_predicate(const Iterator begin, const Iterator end)
  886. : length_(std::distance(begin,end)),
  887. delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
  888. delimiter_end_(delimiter_ + length_)
  889. {
  890. //static_assert(T == std::iterator_traits<Iterator>::value_type);
  891. std::copy(begin,end, delimiter_);
  892. }
  893. template <typename Type>
  894. multiple_delimiter_predicate(const range::adapter<Type>& r)
  895. : length_(std::distance(r.begin(),r.end())),
  896. delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
  897. delimiter_end_(delimiter_ + length_)
  898. {
  899. //static_assert(T == std::iterator_traits<Iterator>::value_type);
  900. std::copy(r.begin(),r.end(), delimiter_);
  901. }
  902. ~multiple_delimiter_predicate()
  903. {
  904. if (length_ > sbo_buffer_size)
  905. {
  906. delete[] delimiter_;
  907. }
  908. }
  909. inline bool operator()(const T& d) const
  910. {
  911. return (std::find(delimiter_,delimiter_end_,d) != delimiter_end_);
  912. }
  913. private:
  914. multiple_delimiter_predicate(const multiple_delimiter_predicate<T>& mdp);
  915. multiple_delimiter_predicate& operator=(const multiple_delimiter_predicate<T>& mdp);
  916. std::size_t length_;
  917. T* delimiter_;
  918. T* delimiter_end_;
  919. enum { sbo_buffer_size = 32 };
  920. T sbo_buffer[sbo_buffer_size];
  921. };
  922. struct multiple_char_delimiter_predicate
  923. {
  924. public:
  925. template <typename Iterator>
  926. multiple_char_delimiter_predicate(const Iterator begin, const Iterator end)
  927. {
  928. setup_delimiter_table(begin,end);
  929. }
  930. multiple_char_delimiter_predicate(const std::string& s)
  931. {
  932. setup_delimiter_table(s.data(),s.data() + s.size());
  933. }
  934. inline bool operator()(const unsigned char& c) const
  935. {
  936. return (delimiter_table_[c]);
  937. }
  938. inline bool operator()(const char& c) const
  939. {
  940. return operator()(static_cast<unsigned char>(c));
  941. }
  942. private:
  943. static const std::size_t table_size = 256;
  944. template <typename Iterator>
  945. inline void setup_delimiter_table(const Iterator begin, const Iterator end)
  946. {
  947. std::fill_n(delimiter_table_,table_size,false);
  948. for (Iterator itr = begin; itr != end; ++itr)
  949. {
  950. delimiter_table_[static_cast<unsigned char>(*itr)] = true;
  951. }
  952. }
  953. bool delimiter_table_[table_size];
  954. };
  955. namespace details
  956. {
  957. template <typename Allocator,
  958. template <typename,typename> class Sequence>
  959. struct index_remover_impl
  960. {
  961. typedef Sequence<std::size_t,Allocator> sequence_t;
  962. index_remover_impl(const sequence_t& sequence)
  963. : itr_(sequence.begin()),
  964. end_(sequence.end()),
  965. current_index_(0),
  966. check_(true)
  967. {}
  968. template <typename T>
  969. inline bool operator()(const T&)
  970. {
  971. if (check_)
  972. {
  973. if (current_index_++ == *itr_)
  974. {
  975. if (end_ == ++itr_)
  976. {
  977. check_ = false;
  978. }
  979. return true;
  980. }
  981. }
  982. return false;
  983. }
  984. typename sequence_t::const_iterator itr_;
  985. typename sequence_t::const_iterator end_;
  986. std::size_t current_index_;
  987. bool check_;
  988. };
  989. }
  990. template <typename Allocator,
  991. template <typename,typename> class Sequence>
  992. inline details::index_remover_impl<Allocator,Sequence> index_remover(const Sequence<std::size_t,Allocator>& sequence)
  993. {
  994. return details::index_remover_impl<Allocator,Sequence>(sequence);
  995. }
  996. template <typename Iterator, typename Predicate>
  997. inline std::size_t remove_inplace(Predicate predicate,
  998. Iterator begin,
  999. Iterator end)
  1000. {
  1001. Iterator itr1 = begin;
  1002. Iterator itr2 = begin;
  1003. std::size_t removal_count = 0;
  1004. while (end != itr1)
  1005. {
  1006. if (predicate(*itr1))
  1007. {
  1008. ++itr1;
  1009. ++removal_count;
  1010. }
  1011. else
  1012. {
  1013. if (itr1 != itr2)
  1014. {
  1015. (*itr2) = (*itr1);
  1016. }
  1017. ++itr1;
  1018. ++itr2;
  1019. }
  1020. }
  1021. return removal_count;
  1022. }
  1023. template <typename T, typename Predicate>
  1024. inline std::size_t remove_inplace(Predicate predicate, const range::adapter<T>& r)
  1025. {
  1026. return remove_inplace(predicate,r.begin(),r.end());
  1027. }
  1028. template <typename Predicate,
  1029. typename T,
  1030. typename Allocator,
  1031. template <typename,typename> class Sequence>
  1032. inline std::size_t remove_inplace(Predicate predicate, Sequence<T,Allocator>& sequence)
  1033. {
  1034. const std::size_t removal_count = remove_inplace(predicate,sequence.begin(),sequence.end());
  1035. sequence.resize(sequence.size() - removal_count);
  1036. return removal_count;
  1037. }
  1038. inline void remove_inplace(const std::string::value_type c, std::string& s)
  1039. {
  1040. const std::size_t removal_count = remove_inplace(single_delimiter_predicate<std::string::value_type>(c),
  1041. const_cast<char*>(s.data()),
  1042. const_cast<char*>(s.data() + s.size()));
  1043. if (removal_count > 0)
  1044. {
  1045. s.resize(s.size() - removal_count);
  1046. }
  1047. }
  1048. template <typename Predicate>
  1049. inline void remove_inplace(Predicate predicate, std::string& s)
  1050. {
  1051. const std::size_t removal_count = remove_inplace(predicate,
  1052. const_cast<char*>(s.data()),
  1053. const_cast<char*>(s.data() + s.size()));
  1054. if (removal_count > 0)
  1055. {
  1056. s.resize(s.size() - removal_count);
  1057. }
  1058. }
  1059. template <typename Iterator, typename Predicate>
  1060. inline std::size_t remove_consecutives_inplace(Predicate predicate,
  1061. Iterator begin,
  1062. Iterator end)
  1063. {
  1064. if (0 == std::distance(begin,end)) return 0;
  1065. Iterator itr1 = begin;
  1066. Iterator itr2 = begin;
  1067. typename std::iterator_traits<Iterator>::value_type prev = *begin;
  1068. std::size_t removal_count = 0;
  1069. ++itr1;
  1070. ++itr2;
  1071. while (end != itr1)
  1072. {
  1073. while ((end != itr1) && (!predicate(*itr1) || !predicate(prev)))
  1074. {
  1075. if (itr1 != itr2)
  1076. {
  1077. (*itr2) = (*itr1);
  1078. }
  1079. prev = (*itr1);
  1080. ++itr1;
  1081. ++itr2;
  1082. }
  1083. while ((end != itr1) && predicate(*itr1))
  1084. {
  1085. ++itr1;
  1086. ++removal_count;
  1087. }
  1088. }
  1089. return removal_count;
  1090. }
  1091. template <typename T, typename Predicate>
  1092. inline std::size_t remove_consecutives_inplace(Predicate predicate, const range::adapter<T>& r)
  1093. {
  1094. return remove_consecutives_inplace(predicate,r.begin(),r.end());
  1095. }
  1096. inline void remove_consecutives_inplace(const std::string::value_type c, std::string& s)
  1097. {
  1098. if (s.empty()) return;
  1099. const std::size_t removal_count = remove_consecutives_inplace(single_delimiter_predicate<std::string::value_type>(c),
  1100. const_cast<char*>(s.data()),
  1101. const_cast<char*>(s.data() + s.size()));
  1102. if (removal_count > 0)
  1103. {
  1104. s.resize(s.size() - removal_count);
  1105. }
  1106. }
  1107. inline void remove_consecutives_inplace(const std::string& rem_chars, std::string& s)
  1108. {
  1109. if (s.empty()) return;
  1110. const std::size_t removal_count = remove_consecutives_inplace(multiple_char_delimiter_predicate(rem_chars),
  1111. const_cast<char*>(s.data()),
  1112. const_cast<char*>(s.data() + s.size()));
  1113. if (removal_count > 0)
  1114. {
  1115. s.resize(s.size() - removal_count);
  1116. }
  1117. }
  1118. namespace details
  1119. {
  1120. #if (defined(__MINGW32_VERSION)) || \
  1121. (defined(__CYGWIN__) || defined(__CYGWIN32__)) || \
  1122. (defined(__APPLE__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)) || \
  1123. (defined(_WIN32) && (_MSC_VER < 1400))
  1124. inline std::size_t strnlength(const char* s, const std::size_t& n)
  1125. {
  1126. const char *end = reinterpret_cast<const char*>(memchr(s, '\0', n));
  1127. return end ? (size_t) (end - s) : n;
  1128. }
  1129. #else
  1130. inline std::size_t strnlength(const char* s, const std::size_t& n)
  1131. {
  1132. return strnlen(s,n);
  1133. }
  1134. #endif
  1135. }
  1136. inline void remove_consecutives_inplace(const char* rem_chars, std::string& s)
  1137. {
  1138. if (s.empty()) return;
  1139. const std::size_t removal_count = remove_consecutives_inplace(multiple_char_delimiter_predicate(
  1140. rem_chars,
  1141. rem_chars + details::strnlength(rem_chars,256)),
  1142. const_cast<char*>(s.data()),
  1143. const_cast<char*>(s.data() + s.size()));
  1144. if (removal_count > 0)
  1145. {
  1146. s.resize(s.size() - removal_count);
  1147. }
  1148. }
  1149. template <typename Predicate>
  1150. inline void remove_consecutives_inplace(Predicate predicate, std::string& s)
  1151. {
  1152. if (s.empty()) return;
  1153. const std::size_t removal_count = remove_consecutives_inplace(predicate,
  1154. const_cast<char*>(s.data()),
  1155. const_cast<char*>(s.data() + s.size()));
  1156. if (removal_count > 0)
  1157. {
  1158. s.resize(s.size() - removal_count);
  1159. }
  1160. }
  1161. template <typename Iterator>
  1162. inline std::size_t remove_consecutives_inplace(Iterator begin, Iterator end)
  1163. {
  1164. if (0 == std::distance(begin,end)) return 0;
  1165. Iterator itr1 = begin; ++itr1;
  1166. Iterator itr2 = begin; ++itr2;
  1167. typename std::iterator_traits<Iterator>::value_type prev = *begin;
  1168. std::size_t removal_count = 0;
  1169. while (end != itr1)
  1170. {
  1171. while ((end != itr1) && (prev != (*itr1)))
  1172. {
  1173. if (itr1 != itr2)
  1174. {
  1175. (*itr2) = (*itr1);
  1176. }
  1177. prev = (*itr1);
  1178. ++itr1;
  1179. ++itr2;
  1180. }
  1181. while ((end != itr1) && (prev == (*itr1)))
  1182. {
  1183. ++itr1;
  1184. ++removal_count;
  1185. }
  1186. }
  1187. return removal_count;
  1188. }
  1189. template <typename T>
  1190. inline std::size_t remove_consecutives_inplace(const range::adapter<T>& r)
  1191. {
  1192. return remove_consecutives_inplace(r.begin(),r.end());
  1193. }
  1194. template <typename T,
  1195. typename Allocator,
  1196. template <typename,typename> class Sequence>
  1197. inline void remove_consecutives_inplace(Sequence<T,Allocator>& sequence)
  1198. {
  1199. const std::size_t removal_count = remove_consecutives_inplace(sequence.begin(),sequence.end());
  1200. sequence.resize(sequence.size() - removal_count);
  1201. }
  1202. inline void remove_consecutives_inplace(std::string& s)
  1203. {
  1204. std::size_t removal_count = remove_consecutives_inplace(const_cast<char*>(s.data()),
  1205. const_cast<char*>(s.data() + s.size()));
  1206. if (removal_count > 0)
  1207. {
  1208. s.resize(s.size() - removal_count);
  1209. }
  1210. }
  1211. inline std::string remove_duplicates(const std::string& str)
  1212. {
  1213. std::string::value_type table[0xFF];
  1214. std::fill_n(table,0xFF,static_cast<char>(0));
  1215. std::string result;
  1216. result.reserve(str.size());
  1217. for (std::size_t i = 0; i < str.size(); ++i)
  1218. {
  1219. const char c = str[i];
  1220. if (0 == table[static_cast<std::size_t>(c)])
  1221. {
  1222. table[static_cast<std::size_t>(c)] = 0x01;
  1223. result += c;
  1224. }
  1225. }
  1226. return result;
  1227. }
  1228. inline std::string remove_duplicates_inplace(std::string& str)
  1229. {
  1230. return remove_duplicates(str);
  1231. }
  1232. template <typename Iterator, typename Predicate>
  1233. inline std::size_t remove_trailing(Predicate predicate,
  1234. Iterator begin,
  1235. Iterator end)
  1236. {
  1237. const std::size_t length = std::distance(begin,end);
  1238. if (0 == length)
  1239. return 0;
  1240. Iterator itr = begin + (length - 1);
  1241. std::size_t removal_count = 0;
  1242. while ((begin != itr) && predicate(*itr))
  1243. {
  1244. --itr;
  1245. ++removal_count;
  1246. }
  1247. return removal_count;
  1248. }
  1249. template <typename T, typename Predicate>
  1250. inline std::size_t remove_trailing(Predicate predicate, const range::adapter<T>& r)
  1251. {
  1252. return remove_trailing(predicate,r.begin(),r.end());
  1253. }
  1254. inline void remove_trailing(const std::string::value_type c, std::string& s)
  1255. {
  1256. if (s.empty()) return;
  1257. const std::size_t removal_count = remove_trailing(single_delimiter_predicate<std::string::value_type>(c),
  1258. const_cast<char*>(s.data()),
  1259. const_cast<char*>(s.data() + s.size()));
  1260. if (removal_count > 0)
  1261. {
  1262. s.resize(s.size() - removal_count);
  1263. }
  1264. }
  1265. inline void remove_trailing(const std::string& rem_chars, std::string& s)
  1266. {
  1267. if (s.empty()) return;
  1268. const std::size_t removal_count = remove_trailing(multiple_char_delimiter_predicate(rem_chars),
  1269. const_cast<char*>(s.data()),
  1270. const_cast<char*>(s.data() + s.size()));
  1271. if (removal_count > 0)
  1272. {
  1273. s.resize(s.size() - removal_count);
  1274. }
  1275. }
  1276. inline void remove_trailing(const char* rem_chars, std::string& s)
  1277. {
  1278. const std::size_t removal_count = remove_trailing(multiple_char_delimiter_predicate(
  1279. rem_chars,
  1280. rem_chars + details::strnlength(rem_chars,256)),
  1281. const_cast<char*>(s.data()),
  1282. const_cast<char*>(s.data() + s.size()));
  1283. if (removal_count > 0)
  1284. {
  1285. s.resize(s.size() - removal_count);
  1286. }
  1287. }
  1288. template <typename Predicate>
  1289. inline void remove_trailing(Predicate predicate, std::string& s)
  1290. {
  1291. if (s.empty()) return;
  1292. const std::size_t removal_count = remove_trailing(predicate,
  1293. const_cast<char*>(s.data()),
  1294. const_cast<char*>(s.data() + s.size()));
  1295. if (removal_count > 0)
  1296. {
  1297. s.resize(s.size() - removal_count);
  1298. }
  1299. }
  1300. template <typename Iterator, typename Predicate>
  1301. inline std::size_t remove_leading(Predicate predicate,
  1302. Iterator begin,
  1303. Iterator end)
  1304. {
  1305. const std::size_t length = std::distance(begin,end);
  1306. if (0 == length)
  1307. return 0;
  1308. Iterator itr = begin;
  1309. std::size_t removal_count = 0;
  1310. while ((end != itr) && predicate(*itr))
  1311. {
  1312. ++itr;
  1313. ++removal_count;
  1314. }
  1315. std::copy(itr,end,begin);
  1316. return removal_count;
  1317. }
  1318. template <typename T, typename Predicate>
  1319. inline std::size_t remove_leading(Predicate predicate, const range::adapter<T>& r)
  1320. {
  1321. return remove_leading(predicate,r.begin(),r.end());
  1322. }
  1323. inline void remove_leading(const std::string::value_type c, std::string& s)
  1324. {
  1325. if (s.empty()) return;
  1326. const std::size_t removal_count = remove_leading(single_delimiter_predicate<std::string::value_type>(c),
  1327. const_cast<char*>(s.data()),
  1328. const_cast<char*>(s.data() + s.size()));
  1329. if (removal_count > 0)
  1330. {
  1331. s.resize(s.size() - removal_count);
  1332. }
  1333. }
  1334. inline void remove_leading(const std::string& rem_chars, std::string& s)
  1335. {
  1336. if (s.empty()) return;
  1337. const std::size_t removal_count = remove_leading(multiple_char_delimiter_predicate(rem_chars),
  1338. const_cast<char*>(s.data()),
  1339. const_cast<char*>(s.data() + s.size()));
  1340. if (removal_count > 0)
  1341. {
  1342. s.resize(s.size() - removal_count);
  1343. }
  1344. }
  1345. inline void remove_leading(const char* rem_chars, std::string& s)
  1346. {
  1347. if (s.empty()) return;
  1348. const std::size_t removal_count = remove_leading(multiple_char_delimiter_predicate(
  1349. rem_chars,
  1350. rem_chars + details::strnlength(rem_chars,256)),
  1351. const_cast<char*>(s.data()),
  1352. const_cast<char*>(s.data() + s.size()));
  1353. if (removal_count > 0)
  1354. {
  1355. s.resize(s.size() - removal_count);
  1356. }
  1357. }
  1358. inline void remove_leading_trailing(const std::string& rem_chars, std::string& s)
  1359. {
  1360. remove_leading(rem_chars,s);
  1361. remove_trailing(rem_chars,s);
  1362. }
  1363. template <typename Predicate>
  1364. inline void remove_leading(Predicate predicate, std::string& s)
  1365. {
  1366. if (s.empty()) return;
  1367. const std::size_t removal_count = remove_leading(predicate,
  1368. const_cast<char*>(s.data()),
  1369. const_cast<char*>(s.data() + s.size()));
  1370. if (removal_count > 0)
  1371. {
  1372. s.resize(s.size() - removal_count);
  1373. }
  1374. }
  1375. template <typename Allocator,
  1376. template <typename,typename> class Sequence>
  1377. void remove_empty_strings(Sequence<std::string,Allocator>& seq)
  1378. {
  1379. struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
  1380. seq.erase(std::remove_if(seq.begin(),seq.end(),is_empty::check),seq.end());
  1381. }
  1382. template <typename Allocator>
  1383. void remove_empty_strings(std::list<std::string,Allocator>& l)
  1384. {
  1385. struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
  1386. l.remove_if(is_empty::check);
  1387. }
  1388. template <typename Comparator, typename Allocator>
  1389. void remove_empty_strings(std::set<std::string,C

Large files files are truncated, but you can click here to view the full file