PageRenderTime 129ms CodeModel.GetById 19ms RepoModel.GetById 1ms 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
  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,Comparator,Allocator>& set)
  1390. {
  1391. struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
  1392. typename std::set<std::string,Comparator,Allocator>::iterator itr = set.begin();
  1393. while (set.end() != itr)
  1394. {
  1395. if ((*itr).empty())
  1396. set.erase(itr++);
  1397. else
  1398. ++itr;
  1399. }
  1400. }
  1401. template <typename Comparator, typename Allocator>
  1402. void remove_empty_strings(std::multiset<std::string,Comparator,Allocator>& set)
  1403. {
  1404. struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
  1405. typename std::multiset<std::string,Comparator,Allocator>::iterator itr = set.begin();
  1406. while (set.end() != itr)
  1407. {
  1408. if ((*itr).empty())
  1409. set.erase(itr++);
  1410. else
  1411. ++itr;
  1412. }
  1413. }
  1414. template <typename Iterator>
  1415. inline void replace(const typename std::iterator_traits<Iterator>::value_type& c1,
  1416. const typename std::iterator_traits<Iterator>::value_type& c2,
  1417. const Iterator begin,
  1418. const Iterator end)
  1419. {
  1420. for (Iterator itr = begin; end != itr; ++itr)
  1421. {
  1422. if (c1 == (*itr))
  1423. {
  1424. (*itr) = c2;
  1425. }
  1426. }
  1427. }
  1428. inline void replace(const std::string::value_type& c0,
  1429. const std::string::value_type& c1,
  1430. std::string& s)
  1431. {
  1432. replace(c0,c1,const_cast<char*>(s.data()),const_cast<char*>(s.data() + s.size()));
  1433. }
  1434. template <typename T>
  1435. inline void replace(const T& c1, const T& c2, const range::adapter<T>& r)
  1436. {
  1437. replace(c1,c2,r.begin(),r.end());
  1438. }
  1439. inline void replace_pattern(const std::string& s, // input
  1440. const std::string& p, // pattern
  1441. const std::string& r, // replacement
  1442. std::string& n)
  1443. {
  1444. if (p.empty() || (p == r))
  1445. {
  1446. n.assign(s);
  1447. return;
  1448. }
  1449. const std::size_t p_size = p.size();
  1450. const std::size_t r_size = r.size();
  1451. int inc = static_cast<int>(r_size) - static_cast<int>(p_size);
  1452. std::size_t pos = 0;
  1453. std::vector<std::size_t> delta_list;
  1454. delta_list.reserve(std::min<std::size_t>(32,(s.size() / p_size) + 1));
  1455. while (std::string::npos != (pos = s.find(p,pos)))
  1456. {
  1457. delta_list.push_back(pos);
  1458. pos += p_size;
  1459. }
  1460. if (delta_list.empty())
  1461. {
  1462. n.assign(s);
  1463. return;
  1464. }
  1465. n.resize(delta_list.size() * inc + s.size(), 0x00);
  1466. char* n_itr = const_cast<char*>(n.data());
  1467. const char* s_end = s.data() + s.size();
  1468. const char* s_itr = s.data();
  1469. const char* r_begin = r.data();
  1470. const char* r_end = r.data() + r_size;
  1471. const std::size_t delta_list_size = delta_list.size();
  1472. std::size_t i = 0;
  1473. std::size_t delta = delta_list[0];
  1474. for ( ; ; )
  1475. {
  1476. std::copy(s_itr, s_itr + delta, n_itr);
  1477. s_itr += p_size + delta;
  1478. n_itr += delta;
  1479. std::copy(r_begin, r_end, n_itr);
  1480. n_itr += r_size;
  1481. if (++i >= delta_list_size)
  1482. break;
  1483. delta = delta_list[i] - (delta_list[i - 1] + p_size);
  1484. }
  1485. if (s_end != s_itr)
  1486. {
  1487. std::copy(s_itr, s_end, n_itr);
  1488. }
  1489. }
  1490. template <typename InputIterator, typename OutputIterator>
  1491. inline std::size_t replace_pattern(const InputIterator s_begin, const InputIterator s_end, // input
  1492. const InputIterator p_begin, const InputIterator p_end, // pattern
  1493. const InputIterator r_begin, const InputIterator r_end, // replacement
  1494. OutputIterator out)
  1495. {
  1496. InputIterator s_itr = s_begin;
  1497. InputIterator r_itr = r_begin;
  1498. InputIterator p_itr = p_begin;
  1499. const std::size_t p_size = std::distance(p_begin,p_end);
  1500. const std::size_t r_size = std::distance(r_begin,r_end);
  1501. if (
  1502. (0 == p_size) ||
  1503. (
  1504. (p_size == r_size) &&
  1505. std::equal(p_begin,p_end,r_begin)
  1506. )
  1507. )
  1508. {
  1509. std::copy(s_begin,s_end,out);
  1510. return std::distance(s_begin,s_end);
  1511. }
  1512. std::size_t pos = 0;
  1513. std::size_t prev_pos = 0;
  1514. std::size_t count = 0;
  1515. std::size_t new_size = std::distance(s_begin,s_end);
  1516. int inc = r_size - p_size;
  1517. InputIterator temp_s_itr = s_itr;
  1518. while (s_end != s_itr)
  1519. {
  1520. /*
  1521. Need to replace the following search code with
  1522. Knuth-Pratt-Morris or Boyer-Moore string search
  1523. algorithms.
  1524. */
  1525. bool found = true;
  1526. p_itr = p_begin;
  1527. temp_s_itr = s_itr;
  1528. while ((p_end != p_itr) && (s_end != temp_s_itr))
  1529. {
  1530. if (*(temp_s_itr++) != *(p_itr++))
  1531. {
  1532. found = false;
  1533. break;
  1534. }
  1535. }
  1536. if (found && (p_itr == p_end))
  1537. {
  1538. ++count;
  1539. new_size += inc;
  1540. s_itr = temp_s_itr;
  1541. }
  1542. else
  1543. ++s_itr;
  1544. }
  1545. s_itr = s_begin;
  1546. p_itr = p_begin;
  1547. pos = 0;
  1548. prev_pos = 0;
  1549. temp_s_itr = s_itr;
  1550. while (0 < count)
  1551. {
  1552. p_itr = p_begin;
  1553. bool found = true;
  1554. InputIterator pattern_start = temp_s_itr;
  1555. while ((p_end != p_itr) && (s_end != temp_s_itr))
  1556. {
  1557. if (*(temp_s_itr++) != *(p_itr++))
  1558. {
  1559. found = false;
  1560. temp_s_itr = pattern_start;
  1561. ++temp_s_itr;
  1562. break;
  1563. }
  1564. }
  1565. if (!found || (p_itr != p_end)) continue;
  1566. pos = std::distance(s_begin,temp_s_itr) - p_size;
  1567. int diff = pos - prev_pos;
  1568. std::copy(s_itr,s_itr + diff, out);
  1569. s_itr = temp_s_itr;
  1570. std::copy(r_itr,r_end, out);
  1571. pos += p_size;
  1572. prev_pos = pos;
  1573. --count;
  1574. }
  1575. std::copy(s_itr,s_end,out);
  1576. return new_size;
  1577. }
  1578. inline void remove_pattern(const std::string& s,
  1579. const std::string& p,
  1580. std::string& n)
  1581. {
  1582. static const std::string r("");
  1583. replace_pattern(s,p,r,n);
  1584. }
  1585. inline void sort(std::string& s)
  1586. {
  1587. std::sort(s.begin(),s.end());
  1588. }
  1589. template <typename Iterator>
  1590. inline bool match(const Iterator pattern_begin,
  1591. const Iterator pattern_end,
  1592. const Iterator data_begin,
  1593. const Iterator data_end,
  1594. const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
  1595. const typename std::iterator_traits<Iterator>::value_type& zero_or_one)
  1596. {
  1597. /*
  1598. Credits: Adapted from code by Jack Handy (2001)
  1599. */
  1600. if (0 == std::distance(data_begin,data_end)) return false;
  1601. Iterator d_itr = data_begin;
  1602. Iterator p_itr = pattern_begin;
  1603. Iterator c_itr = data_begin;
  1604. Iterator m_itr = data_begin;
  1605. while ((data_end != d_itr) && (zero_or_more != (*p_itr)))
  1606. {
  1607. if (((*p_itr) != (*d_itr)) && (zero_or_one != (*p_itr)))
  1608. {
  1609. return false;
  1610. }
  1611. ++p_itr;
  1612. ++d_itr;
  1613. }
  1614. while (data_end != d_itr)
  1615. {
  1616. if (zero_or_more == (*p_itr))
  1617. {
  1618. if (pattern_end == (++p_itr))
  1619. {
  1620. return true;
  1621. }
  1622. m_itr = p_itr;
  1623. c_itr = d_itr;
  1624. ++c_itr;
  1625. }
  1626. else if (((*p_itr) == (*d_itr)) || (zero_or_one == (*p_itr)))
  1627. {
  1628. ++p_itr;
  1629. ++d_itr;
  1630. }
  1631. else
  1632. {
  1633. p_itr = m_itr;
  1634. d_itr = c_itr++;
  1635. }
  1636. }
  1637. while ((p_itr != pattern_end) && (zero_or_more == (*p_itr))) ++p_itr;
  1638. return (p_itr == pattern_end);
  1639. }
  1640. inline bool match(const std::string& wild_card,
  1641. const std::string& str)
  1642. {
  1643. /*
  1644. * : Zero or more match
  1645. ? : Zero or one match
  1646. */
  1647. return match(wild_card.data(),
  1648. wild_card.data() + wild_card.size(),
  1649. str.data(),
  1650. str.data() + str.size(),
  1651. '*',
  1652. '?');
  1653. }
  1654. inline bool imatch_char(const char c1, const char c2)
  1655. {
  1656. return std::toupper(c1) == std::toupper(c2);
  1657. }
  1658. template <typename InputIterator>
  1659. inline bool imatch(const InputIterator begin1, const InputIterator end1,
  1660. const InputIterator begin2, const InputIterator end2)
  1661. {
  1662. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1663. details::convert_type_assert<itr_type>();
  1664. if (std::distance(begin1,end1) != std::distance(begin2,end2))
  1665. {
  1666. return false;
  1667. }
  1668. InputIterator itr1 = begin1;
  1669. InputIterator itr2 = begin2;
  1670. while (end1 != itr1)
  1671. {
  1672. //if (std::toupper(*itr1, std::locale::classic()) != std::toupper(*it2, std::locale::classic()))
  1673. if (std::toupper(*itr1) != std::toupper(*itr2))
  1674. {
  1675. return false;
  1676. }
  1677. ++itr1;
  1678. ++itr2;
  1679. }
  1680. return true;
  1681. }
  1682. template <typename T>
  1683. inline bool imatch(const range::adapter<T>& r1, const range::adapter<T>& r2)
  1684. {
  1685. return imatch(r1.begin(),r1.end(),r2.begin(),r2.end());
  1686. }
  1687. inline bool imatch(const std::string& s1, const std::string& s2)
  1688. {
  1689. return imatch(s1.data(),
  1690. s1.data() + s1.size(),
  1691. s2.data(),
  1692. s2.data() + s2.size());
  1693. }
  1694. template <typename Iterator>
  1695. inline Iterator imatch(const std::string& s, const Iterator begin, const Iterator end)
  1696. {
  1697. for (const std::string* itr = begin; end != itr; ++itr)
  1698. {
  1699. if (imatch(s,*itr))
  1700. {
  1701. return itr;
  1702. }
  1703. }
  1704. return end;
  1705. }
  1706. template <typename Allocator,
  1707. template <typename,typename> class Sequence>
  1708. inline bool imatch(const std::string& s, const Sequence<std::string,Allocator>& sequence)
  1709. {
  1710. return (sequence.end() != imatch(s,sequence.begin(),sequence.end()));
  1711. }
  1712. template <typename Comparator, typename Allocator>
  1713. inline bool imatch(const std::string& s, const std::set<std::string,Comparator,Allocator>& set)
  1714. {
  1715. return imatch(s,set.begin(),set.end());
  1716. }
  1717. template <typename Comparator, typename Allocator>
  1718. inline bool imatch(const std::string& s, const std::multiset<std::string,Comparator,Allocator>& multiset)
  1719. {
  1720. return imatch(s,multiset.begin(),multiset.end());
  1721. }
  1722. template <typename Iterator, typename OutputIterator>
  1723. inline std::size_t find_all(const Iterator pattern_begin,
  1724. const Iterator pattern_end,
  1725. const Iterator begin,
  1726. const Iterator end,
  1727. OutputIterator out)
  1728. {
  1729. Iterator itr = begin;
  1730. const std::size_t pattern_length = std::distance(pattern_begin,pattern_end);
  1731. std::size_t match_count = 0;
  1732. while (end != (itr = std::search(itr, end, pattern_begin, pattern_end)))
  1733. {
  1734. (*out) = std::make_pair(itr,itr + pattern_length);
  1735. itr += pattern_length;
  1736. ++out;
  1737. ++match_count;
  1738. }
  1739. return match_count;
  1740. }
  1741. template <typename Iterator,
  1742. typename Range,
  1743. typename Allocator,
  1744. template <typename,typename> class Sequence>
  1745. inline std::size_t find_all(const Iterator pattern_begin,
  1746. const Iterator pattern_end,
  1747. const Iterator begin,
  1748. const Iterator end,
  1749. Sequence<Range,Allocator>& seq)
  1750. {
  1751. return find_all(pattern_begin,pattern_end,begin,end,std::back_inserter(seq));
  1752. }
  1753. inline std::size_t ifind(const std::string& pattern, const std::string& data)
  1754. {
  1755. if (pattern.size() > data.size())
  1756. return std::string::npos;
  1757. const char* result_itr = std::search(data.data(),data.data() + data.size(),
  1758. pattern.data(), pattern.data() + pattern.size(),
  1759. imatch_char);
  1760. if ((data.data() + data.size()) == result_itr)
  1761. return std::string::npos;
  1762. else
  1763. return std::distance(data.data(),result_itr);
  1764. }
  1765. template <typename Iterator, typename OutputIterator>
  1766. inline std::size_t ifind_all(const Iterator pattern_begin,
  1767. const Iterator pattern_end,
  1768. const Iterator begin,
  1769. const Iterator end,
  1770. OutputIterator out)
  1771. {
  1772. Iterator itr = begin;
  1773. const std::size_t pattern_length = std::distance(pattern_begin,pattern_end);
  1774. std::size_t match_count = 0;
  1775. while (end != (itr = std::search(itr, end, pattern_begin, pattern_end, imatch_char)))
  1776. {
  1777. (*out) = std::make_pair(itr,itr + pattern_length);
  1778. itr += pattern_length;
  1779. ++out;
  1780. ++match_count;
  1781. }
  1782. return match_count;
  1783. }
  1784. template <typename OutputIterator>
  1785. inline std::size_t find_all(const std::string& pattern,
  1786. const std::string& data,
  1787. OutputIterator out)
  1788. {
  1789. return find_all(pattern.data(), pattern.data() + pattern.size(),
  1790. data.data(), data.data() + data.size(),
  1791. out);
  1792. }
  1793. template <typename Range,
  1794. typename Allocator,
  1795. template <typename,typename> class Sequence>
  1796. inline std::size_t find_all(const std::string& pattern,
  1797. const std::string& data,
  1798. Sequence<Range,Allocator>& seq)
  1799. {
  1800. return find_all(pattern,data,std::back_inserter(seq));
  1801. }
  1802. template <typename OutputIterator>
  1803. inline std::size_t ifind_all(const std::string& pattern,
  1804. const std::string& data,
  1805. OutputIterator out)
  1806. {
  1807. return ifind_all(pattern.data(), pattern.data() + pattern.size(),
  1808. data.data(), data.data() + data.size(),
  1809. out);
  1810. }
  1811. template <typename Range,
  1812. typename Allocator,
  1813. template <typename,typename> class Sequence>
  1814. inline std::size_t ifind_all(const std::string& pattern,
  1815. const std::string& data,
  1816. Sequence<Range,Allocator>& seq)
  1817. {
  1818. return ifind_all(pattern,data,std::back_inserter(seq));
  1819. }
  1820. template <typename InputIterator>
  1821. inline bool begins_with(const InputIterator pattern_begin,
  1822. const InputIterator pattern_end,
  1823. const InputIterator begin,
  1824. const InputIterator end)
  1825. {
  1826. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1827. details::convert_type_assert<itr_type>();
  1828. if (std::distance(pattern_begin,pattern_end) <= std::distance(begin,end))
  1829. {
  1830. return std::equal(pattern_begin,pattern_end,begin);
  1831. }
  1832. else
  1833. return false;
  1834. }
  1835. inline bool begins_with(const std::string& pattern, const std::string& data)
  1836. {
  1837. if (pattern.size() <= data.size())
  1838. {
  1839. return begins_with(pattern.data(),
  1840. pattern.data() + pattern.size(),
  1841. data.data(),
  1842. data.data() + data.size());
  1843. }
  1844. else
  1845. return false;
  1846. }
  1847. template <typename InputIterator>
  1848. inline bool ibegins_with(const InputIterator pattern_begin,
  1849. const InputIterator pattern_end,
  1850. const InputIterator begin,
  1851. const InputIterator end)
  1852. {
  1853. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1854. details::convert_type_assert<itr_type>();
  1855. if (std::distance(pattern_begin,pattern_end) <= std::distance(begin,end))
  1856. {
  1857. return std::equal(pattern_begin,pattern_end,begin,imatch_char);
  1858. }
  1859. else
  1860. return false;
  1861. }
  1862. inline bool ibegins_with(const std::string& pattern, const std::string& data)
  1863. {
  1864. if (pattern.size() <= data.size())
  1865. {
  1866. return ibegins_with(pattern.data(),
  1867. pattern.data() + pattern.size(),
  1868. data.data(),
  1869. data.data() + data.size());
  1870. }
  1871. else
  1872. return false;
  1873. }
  1874. template <typename InputIterator>
  1875. inline bool ends_with(const InputIterator pattern_begin,
  1876. const InputIterator pattern_end,
  1877. const InputIterator begin,
  1878. const InputIterator end)
  1879. {
  1880. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1881. details::convert_type_assert<itr_type>();
  1882. const std::size_t pattern_length = std::distance(pattern_begin,pattern_end);
  1883. const std::size_t data_length = std::distance(begin,end);
  1884. if (pattern_length <= data_length)
  1885. {
  1886. return std::equal(pattern_begin,
  1887. pattern_end,
  1888. begin + (data_length - pattern_length));
  1889. }
  1890. else
  1891. return false;
  1892. }
  1893. inline bool ends_with(const std::string& pattern, const std::string& data)
  1894. {
  1895. if (pattern.size() <= data.size())
  1896. {
  1897. return ends_with(pattern.data(),
  1898. pattern.data() + pattern.size(),
  1899. data.data(),
  1900. data.data() + data.size());
  1901. }
  1902. else
  1903. return false;
  1904. }
  1905. template <typename InputIterator>
  1906. inline bool iends_with(const InputIterator pattern_begin,
  1907. const InputIterator pattern_end,
  1908. const InputIterator begin,
  1909. const InputIterator end)
  1910. {
  1911. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1912. details::convert_type_assert<itr_type>();
  1913. const std::size_t pattern_length = std::distance(pattern_begin,pattern_end);
  1914. const std::size_t data_length = std::distance(begin,end);
  1915. if (pattern_length <= data_length)
  1916. {
  1917. return std::equal(pattern_begin,
  1918. pattern_end,
  1919. begin + (data_length - pattern_length),
  1920. imatch_char);
  1921. }
  1922. else
  1923. return false;
  1924. }
  1925. inline bool iends_with(const std::string& pattern, const std::string& data)
  1926. {
  1927. if (pattern.size() <= data.size())
  1928. {
  1929. return iends_with(pattern.data(),
  1930. pattern.data() + pattern.size(),
  1931. data.data(),
  1932. data.data() + data.size());
  1933. }
  1934. else
  1935. return false;
  1936. }
  1937. inline std::size_t index_of(const std::string& pattern, const std::string& data)
  1938. {
  1939. if (pattern.empty())
  1940. return std::string::npos;
  1941. else if (data.empty())
  1942. return std::string::npos;
  1943. else if (pattern.size() > data.size())
  1944. return std::string::npos;
  1945. const char* itr = std::search(data.data(),
  1946. data.data() + data.size(),
  1947. pattern.data(),
  1948. pattern.data() + pattern.size());
  1949. return ((data.data() + data.size()) == itr) ? std::string::npos : std::distance(data.data(),itr);
  1950. }
  1951. namespace tokenize_options
  1952. {
  1953. typedef std::size_t type;
  1954. enum
  1955. {
  1956. default_mode = 0,
  1957. compress_delimiters = 1,
  1958. include_1st_delimiter = 2,
  1959. include_all_delimiters = 4
  1960. };
  1961. static inline bool perform_compress_delimiters(const type& split_opt)
  1962. {
  1963. return compress_delimiters == (split_opt & compress_delimiters);
  1964. }
  1965. static inline bool perform_include_1st_delimiter(const type& split_opt)
  1966. {
  1967. return include_1st_delimiter == (split_opt & include_1st_delimiter);
  1968. }
  1969. static inline bool perform_include_all_delimiters(const type& split_opt)
  1970. {
  1971. return include_all_delimiters == (split_opt & include_all_delimiters);
  1972. }
  1973. } // namespace tokenize_options
  1974. template <typename Iterator, typename DelimiterPredicate>
  1975. class tokenizer
  1976. {
  1977. private:
  1978. template <typename Iterartor,
  1979. typename Predicate,
  1980. typename T = std::pair<Iterator,Iterator> >
  1981. class tokenizer_iterator : public std::iterator<std::forward_iterator_tag,T>
  1982. {
  1983. protected:
  1984. typedef Iterator iterator;
  1985. typedef const iterator const_iterator;
  1986. typedef typename std::pair<iterator,iterator> range_type;
  1987. public:
  1988. explicit inline tokenizer_iterator(const iterator begin,
  1989. const iterator end,
  1990. const Predicate& predicate,
  1991. const tokenize_options::type tokenize_option = tokenize_options::default_mode)
  1992. : predicate_(predicate),
  1993. end_(end),
  1994. range_(begin,begin),
  1995. current_token_(end,end),
  1996. compress_delimiters_(tokenize_options::perform_compress_delimiters(tokenize_option)),
  1997. include_1st_delimiter_(tokenize_options::perform_include_1st_delimiter(tokenize_option)),
  1998. include_all_delimiters_(tokenize_options::perform_include_all_delimiters(tokenize_option)),
  1999. include_delimiters_(include_1st_delimiter_ || include_all_delimiters_),
  2000. last_token_done_(false)
  2001. {
  2002. if (end != begin)
  2003. {
  2004. this->operator++();
  2005. }
  2006. }
  2007. inline tokenizer_iterator& operator++()
  2008. {
  2009. if (last_token_done_)
  2010. {
  2011. range_.first = range_.second;
  2012. return (*this);
  2013. }
  2014. else if (end_ != range_.second)
  2015. {
  2016. range_.first = range_.second;
  2017. }
  2018. while (end_ != range_.second)
  2019. {
  2020. if (predicate_(*(range_.second)))
  2021. {
  2022. if (include_delimiters_)
  2023. {
  2024. if (include_1st_delimiter_)
  2025. ++range_.second;
  2026. else if (include_all_delimiters_)
  2027. while ((end_ != range_.second) && predicate_(*(range_.second))) ++range_.second;
  2028. current_token_ = range_;
  2029. if ((!include_all_delimiters_) && compress_delimiters_)
  2030. while ((end_ != range_.second) && predicate_(*(range_.second))) ++range_.second;
  2031. }
  2032. else
  2033. {
  2034. current_token_ = range_;
  2035. if (compress_delimiters_)
  2036. while ((end_ != (++range_.second)) && predicate_(*(range_.second))) ;
  2037. else
  2038. ++range_.second;
  2039. }
  2040. return (*this);
  2041. }
  2042. else
  2043. ++range_.second;
  2044. }
  2045. if (range_.first != range_.second)
  2046. {
  2047. current_token_.second = range_.second;
  2048. if (!last_token_done_)
  2049. {
  2050. if (predicate_(*(range_.second - 1)))
  2051. current_token_.first = range_.second;
  2052. else
  2053. current_token_.first = range_.first;
  2054. last_token_done_ = true;
  2055. }
  2056. else
  2057. range_.first = range_.second;
  2058. }
  2059. return (*this);
  2060. }
  2061. inline tokenizer_iterator operator++(int)
  2062. {
  2063. tokenizer_iterator tmp = (*this);
  2064. this->operator++();
  2065. return tmp;
  2066. }
  2067. inline tokenizer_iterator& operator+=(const int inc)
  2068. {
  2069. if (inc > 0)
  2070. {
  2071. for (int i = 0; i < inc; ++i, ++(*this)) ;
  2072. }
  2073. return (*this);
  2074. }
  2075. inline T operator*() const
  2076. {
  2077. return current_token_;
  2078. }
  2079. inline std::string as_string() const
  2080. {
  2081. return std::string(current_token_.first,current_token_.second);
  2082. }
  2083. inline bool operator==(const tokenizer_iterator& itr) const
  2084. {
  2085. return (range_ == itr.range_) && (end_ == itr.end_);
  2086. }
  2087. inline bool operator!=(const tokenizer_iterator& itr) const
  2088. {
  2089. return (range_ != itr.range_) || (end_ != itr.end_);
  2090. }
  2091. inline tokenizer_iterator& operator=(const tokenizer_iterator& itr)
  2092. {
  2093. if (this != &itr)
  2094. {
  2095. range_ = itr.range_;
  2096. current_token_ = itr.current_token_;
  2097. end_ = itr.end_;
  2098. compress_delimiters_ = itr.compress_delimiters_;
  2099. include_1st_delimiter_ = itr.include_1st_delimiter_;
  2100. include_all_delimiters_ = itr.include_all_delimiters_;
  2101. include_delimiters_ = itr.include_delimiters_;
  2102. last_token_done_ = itr.last_token_done_;
  2103. }
  2104. return (*this);
  2105. }
  2106. inline std::string remaining() const
  2107. {
  2108. return std::string(current_token_.first,end_);
  2109. }
  2110. protected:
  2111. const Predicate& predicate_;
  2112. iterator end_;
  2113. range_type range_;
  2114. range_type current_token_;
  2115. bool compress_delimiters_;
  2116. bool include_1st_delimiter_;
  2117. bool include_all_delimiters_;
  2118. bool include_delimiters_;
  2119. bool last_token_done_;
  2120. };
  2121. public:
  2122. typedef typename std::iterator_traits<Iterator>::value_type value_type;
  2123. typedef DelimiterPredicate predicate;
  2124. typedef tokenizer_iterator<Iterator,DelimiterPredicate> iterator;
  2125. typedef const iterator const_iterator;
  2126. typedef iterator& iterator_ref;
  2127. typedef const_iterator& const_iterator_ref;
  2128. inline tokenizer(const Iterator begin,
  2129. const Iterator end,
  2130. const DelimiterPredicate& predicate,
  2131. const tokenize_options::type tokenize_options = tokenize_options::default_mode)
  2132. : tokenize_options_(tokenize_options),
  2133. predicate_(predicate),
  2134. begin_(begin),
  2135. end_(end),
  2136. begin_itr_(begin_,end_,predicate_,tokenize_options_),
  2137. end_itr_(end_,end_,predicate_,tokenize_options_)
  2138. {}
  2139. inline tokenizer(const std::string& s,
  2140. const DelimiterPredicate& predicate,
  2141. const tokenize_options::type tokenize_options = tokenize_options::default_mode)
  2142. : tokenize_options_(tokenize_options),
  2143. predicate_(predicate),
  2144. begin_(s.data()),
  2145. end_(s.data() + s.size()),
  2146. begin_itr_(begin_,end_,predicate_,tokenize_options_),
  2147. end_itr_(end_,end_,predicate_,tokenize_options_)
  2148. {}
  2149. inline tokenizer& operator=(const tokenizer& t)
  2150. {
  2151. if (this != &t)
  2152. {
  2153. begin_ = t.begin_;
  2154. end_ = t.end_;
  2155. end_itr_ = t.end_itr_;
  2156. begin_itr_ = t.begin_itr_;
  2157. tokenize_options_ = t.tokenize_options_;
  2158. }
  2159. return (*this);
  2160. }
  2161. inline void assign(const std::string& s) const
  2162. {
  2163. assign(s.data(),s.data() + s.size());
  2164. }
  2165. inline void assign(const std::string& s)
  2166. {
  2167. assign(s.data(),s.data() + s.size());
  2168. }
  2169. inline void assign(const Iterator begin, const Iterator end)
  2170. {
  2171. begin_ = begin;
  2172. end_ = end;
  2173. begin_itr_ = iterator(begin_,end_,predicate_,tokenize_options_);
  2174. end_itr_ = iterator(end_,end_,predicate_,tokenize_options_);
  2175. }
  2176. inline const_iterator_ref begin() const
  2177. {
  2178. return begin_itr_;
  2179. }
  2180. inline const_iterator_ref end() const
  2181. {
  2182. return end_itr_;
  2183. }
  2184. private:
  2185. tokenize_options::type tokenize_options_;
  2186. const DelimiterPredicate& predicate_;
  2187. Iterator begin_;
  2188. Iterator end_;
  2189. iterator begin_itr_;
  2190. iterator end_itr_;
  2191. };
  2192. namespace std_string
  2193. {
  2194. template <typename DelimiterPredicate = single_delimiter_predicate<std::string::value_type> >
  2195. struct tokenizer
  2196. {
  2197. typedef DelimiterPredicate predicate_type;
  2198. typedef const std::string::value_type* string_iterator_type;
  2199. typedef strtk::tokenizer<string_iterator_type,DelimiterPredicate> type;
  2200. typedef strtk::tokenizer<string_iterator_type,multiple_char_delimiter_predicate> md_type;
  2201. typedef std::pair<string_iterator_type,string_iterator_type> iterator_type;
  2202. };
  2203. typedef tokenizer<>::iterator_type iterator_type;
  2204. typedef tokenizer<>::iterator_type range_t;
  2205. typedef std::vector<iterator_type> token_vector_type;
  2206. typedef std::deque<iterator_type> token_deque_type;
  2207. typedef std::list<iterator_type> token_list_type;
  2208. } // namespace std_string
  2209. template <typename Sequence>
  2210. class range_to_type_back_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2211. void,
  2212. void,
  2213. void,
  2214. void>
  2215. {
  2216. public:
  2217. typedef typename Sequence::value_type value_type;
  2218. explicit inline range_to_type_back_inserter_iterator(Sequence& sequence)
  2219. : sequence_(sequence)
  2220. {}
  2221. range_to_type_back_inserter_iterator(const range_to_type_back_inserter_iterator& itr)
  2222. : sequence_(itr.sequence_)
  2223. {}
  2224. inline range_to_type_back_inserter_iterator& operator=(const range_to_type_back_inserter_iterator& itr)
  2225. {
  2226. if (this != &itr)
  2227. {
  2228. this->sequence_ = itr.sequence_;
  2229. }
  2230. return (*this);
  2231. }
  2232. template <typename Iterator>
  2233. inline range_to_type_back_inserter_iterator& operator=(const std::pair<Iterator,Iterator>& r)
  2234. {
  2235. value_type t;
  2236. if (string_to_type_converter(r.first,r.second,t))
  2237. sequence_.push_back(t);
  2238. return (*this);
  2239. }
  2240. inline range_to_type_back_inserter_iterator& operator=(const std::string& s)
  2241. {
  2242. value_type t;
  2243. if (string_to_type_converter(s.data(),s.data() + s.size(),t))
  2244. sequence_.push_back(t);
  2245. return (*this);
  2246. }
  2247. template <typename Iterator>
  2248. inline void operator()(const std::pair<Iterator,Iterator>& r) const
  2249. {
  2250. value_type t;
  2251. if (string_to_type_converter(r.first,r.second,t))
  2252. sequence_.push_back(t);
  2253. }
  2254. template <typename Iterator>
  2255. inline void operator()(const Iterator begin, const Iterator end)
  2256. {
  2257. sequence_.push_back(string_to_type_converter<value_type>(begin,end));
  2258. }
  2259. inline range_to_type_back_inserter_iterator& operator*()
  2260. {
  2261. return (*this);
  2262. }
  2263. inline range_to_type_back_inserter_iterator& operator++()
  2264. {
  2265. return (*this);
  2266. }
  2267. inline range_to_type_back_inserter_iterator operator++(int)
  2268. {
  2269. return (*this);
  2270. }
  2271. private:
  2272. Sequence& sequence_;
  2273. };
  2274. template <typename Sequence>
  2275. inline range_to_type_back_inserter_iterator<Sequence> range_to_type_back_inserter(Sequence& sequence)
  2276. {
  2277. return (range_to_type_back_inserter_iterator<Sequence>(sequence));
  2278. }
  2279. template <typename Set>
  2280. class range_to_type_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2281. void,
  2282. void,
  2283. void,
  2284. void>
  2285. {
  2286. public:
  2287. typedef typename Set::value_type value_type;
  2288. explicit inline range_to_type_inserter_iterator(Set& set)
  2289. : set_(set)
  2290. {}
  2291. range_to_type_inserter_iterator(const range_to_type_inserter_iterator& itr)
  2292. : set_(itr.set_)
  2293. {}
  2294. inline range_to_type_inserter_iterator& operator=(const range_to_type_inserter_iterator& itr)
  2295. {
  2296. if (this != &itr)
  2297. {
  2298. this->set_ = itr.set_;
  2299. }
  2300. return (*this);
  2301. }
  2302. template <typename Iterator>
  2303. inline range_to_type_inserter_iterator& operator=(const std::pair<Iterator,Iterator>& r)
  2304. {
  2305. value_type t;
  2306. if (string_to_type_converter(r.first,r.second,t))
  2307. set_.insert(t);
  2308. return (*this);
  2309. }
  2310. template <typename Iterator>
  2311. inline void operator()(const std::pair<Iterator,Iterator>& r)
  2312. {
  2313. value_type t;
  2314. if (string_to_type_converter(r.first,r.second,t))
  2315. set_.insert(t);
  2316. }
  2317. inline range_to_type_inserter_iterator& operator*()
  2318. {
  2319. return (*this);
  2320. }
  2321. inline range_to_type_inserter_iterator& operator++()
  2322. {
  2323. return (*this);
  2324. }
  2325. inline range_to_type_inserter_iterator operator++(int)
  2326. {
  2327. return (*this);
  2328. }
  2329. private:
  2330. Set& set_;
  2331. };
  2332. template <typename Set>
  2333. inline range_to_type_inserter_iterator<Set> range_to_type_inserter(Set& set)
  2334. {
  2335. return (range_to_type_inserter_iterator<Set>(set));
  2336. }
  2337. template <typename Container>
  2338. class range_to_type_push_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2339. void,
  2340. void,
  2341. void,
  2342. void>
  2343. {
  2344. public:
  2345. typedef typename Container::value_type value_type;
  2346. explicit inline range_to_type_push_inserter_iterator(Container& container)
  2347. : container_(container)
  2348. {}
  2349. range_to_type_push_inserter_iterator(const range_to_type_push_inserter_iterator& itr)
  2350. : container_(itr.container_)
  2351. {}
  2352. inline range_to_type_push_inserter_iterator& operator=(const range_to_type_push_inserter_iterator& itr)
  2353. {
  2354. if (this != &itr)
  2355. {
  2356. this->container_ = itr.container_;
  2357. }
  2358. return (*this);
  2359. }
  2360. template <typename Iterator>
  2361. inline range_to_type_push_inserter_iterator& operator=(const std::pair<Iterator,Iterator>& r)
  2362. {
  2363. value_type t;
  2364. if (string_to_type_converter(r.first,r.second,t))
  2365. container_.push(t);
  2366. return (*this);
  2367. }
  2368. template <typename Iterator>
  2369. inline void operator()(const std::pair<Iterator,Iterator>& r)
  2370. {
  2371. value_type t;
  2372. if (string_to_type_converter(r.first,r.second,t))
  2373. container_.push(t);
  2374. }
  2375. inline range_to_type_push_inserter_iterator& operator*()
  2376. {
  2377. return (*this);
  2378. }
  2379. inline range_to_type_push_inserter_iterator& operator++()
  2380. {
  2381. return (*this);
  2382. }
  2383. inline range_to_type_push_inserter_iterator operator++(int)
  2384. {
  2385. return (*this);
  2386. }
  2387. private:
  2388. Container& container_;
  2389. };
  2390. template <typename Container>
  2391. inline range_to_type_push_inserter_iterator<Container> range_to_type_push_inserter(Container& container)
  2392. {
  2393. return (range_to_type_push_inserter_iterator<Container>(container));
  2394. }
  2395. template <typename Sequence>
  2396. class back_inserter_with_valuetype_iterator : public std::iterator<std::output_iterator_tag,
  2397. typename Sequence::value_type,
  2398. void,
  2399. void,
  2400. void>
  2401. {
  2402. public:
  2403. explicit inline back_inserter_with_valuetype_iterator(Sequence& sequence)
  2404. : sequence_(sequence)
  2405. {}
  2406. back_inserter_with_valuetype_iterator(const back_inserter_with_valuetype_iterator& itr)
  2407. : sequence_(itr.sequence_)
  2408. {}
  2409. inline back_inserter_with_valuetype_iterator& operator=(const back_inserter_with_valuetype_iterator& itr)
  2410. {
  2411. if (this != &itr)
  2412. {
  2413. this->sequence_ = itr.sequence_;
  2414. }
  2415. return (*this);
  2416. }
  2417. inline back_inserter_with_valuetype_iterator& operator=(const typename Sequence::value_type& v)
  2418. {
  2419. sequence_.push_back(v);
  2420. return (*this);
  2421. }
  2422. inline void operator()(const typename Sequence::value_type& v)
  2423. {
  2424. sequence_.push_back(v);
  2425. }
  2426. inline back_inserter_with_valuetype_iterator& operator*()
  2427. {
  2428. return (*this);
  2429. }
  2430. inline back_inserter_with_valuetype_iterator& operator++()
  2431. {
  2432. return (*this);
  2433. }
  2434. inline back_inserter_with_valuetype_iterator operator++(int)
  2435. {
  2436. return (*this);
  2437. }
  2438. private:
  2439. Sequence& sequence_;
  2440. };
  2441. template <typename Sequence>
  2442. inline back_inserter_with_valuetype_iterator<Sequence> back_inserter_with_valuetype(Sequence& sequence_)
  2443. {
  2444. return (back_inserter_with_valuetype_iterator<Sequence>(sequence_));
  2445. }
  2446. template <typename Set>
  2447. class inserter_with_valuetype_iterator : public std::iterator<std::output_iterator_tag,
  2448. typename Set::value_type,
  2449. void,
  2450. void,
  2451. void>
  2452. {
  2453. public:
  2454. explicit inline inserter_with_valuetype_iterator(Set& set)
  2455. : set_(set)
  2456. {}
  2457. inserter_with_valuetype_iterator(const inserter_with_valuetype_iterator& itr)
  2458. : set_(itr.set_)
  2459. {}
  2460. inline inserter_with_valuetype_iterator& operator=(const inserter_with_valuetype_iterator& itr)
  2461. {
  2462. if (this != &itr)
  2463. {
  2464. this->set_ = itr.set_;
  2465. }
  2466. return (*this);
  2467. }
  2468. inline inserter_with_valuetype_iterator& operator=(const typename Set::value_type& v)
  2469. {
  2470. set_.insert(v);
  2471. return (*this);
  2472. }
  2473. inline void operator()(const typename Set::value_type& v)
  2474. {
  2475. set_.insert(v);
  2476. }
  2477. inline inserter_with_valuetype_iterator& operator*()
  2478. {
  2479. return (*this);
  2480. }
  2481. inline inserter_with_valuetype_iterator& operator++()
  2482. {
  2483. return (*this);
  2484. }
  2485. inline inserter_with_valuetype_iterator operator++(int)
  2486. {
  2487. return (*this);
  2488. }
  2489. private:
  2490. Set& set_;
  2491. };
  2492. template <typename Set>
  2493. inline inserter_with_valuetype_iterator<Set> inserter_with_valuetype(Set& set_)
  2494. {
  2495. return (inserter_with_valuetype_iterator<Set>(set_));
  2496. }
  2497. template <typename Container>
  2498. class push_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2499. void,
  2500. void,
  2501. void,
  2502. void>
  2503. {
  2504. public:
  2505. explicit inline push_inserter_iterator(Container& container)
  2506. : container_(container)
  2507. {}
  2508. inline push_inserter_iterator& operator=(const push_inserter_iterator& itr)
  2509. {
  2510. if (this != &itr)
  2511. {
  2512. this->container_ = itr.container_;
  2513. }
  2514. return (*this);
  2515. }
  2516. inline push_inserter_iterator<Container>& operator=(typename Container::const_reference v)
  2517. {
  2518. container_.push(v);
  2519. return (*this);
  2520. }
  2521. inline push_inserter_iterator<Container>& operator*()
  2522. {
  2523. return (*this);
  2524. }
  2525. inline push_inserter_iterator<Container>& operator++()
  2526. {
  2527. return (*this);
  2528. }
  2529. inline push_inserter_iterator<Container> operator++(int)
  2530. {
  2531. return (*this);
  2532. }
  2533. private:
  2534. Container& container_;
  2535. };
  2536. template <typename Container>
  2537. inline push_inserter_iterator<Container> push_inserter(Container& c)
  2538. {
  2539. return push_inserter_iterator<Container>(c);
  2540. }
  2541. template <typename T>
  2542. class range_to_ptr_type_iterator : public std::iterator<std::output_iterator_tag,
  2543. void,
  2544. void,
  2545. void,
  2546. void>
  2547. {
  2548. public:
  2549. typedef T value_type;
  2550. explicit inline range_to_ptr_type_iterator(T* pointer, std::size_t& insert_count)
  2551. : pointer_(pointer),
  2552. insert_count_(insert_count)
  2553. {}
  2554. range_to_ptr_type_iterator(const range_to_ptr_type_iterator& itr)
  2555. : pointer_(itr.pointer_)
  2556. {}
  2557. inline range_to_ptr_type_iterator& operator=(const range_to_ptr_type_iterator& itr)
  2558. {
  2559. if (this != &itr)
  2560. {
  2561. this->pointer_ = itr.pointer_;
  2562. }
  2563. return (*this);
  2564. }
  2565. template <typename Iterator>
  2566. inline range_to_ptr_type_iterator& operator=(const std::pair<Iterator,Iterator>& r)
  2567. {
  2568. value_type t = value_type();
  2569. if (string_to_type_converter(r.first,r.second,t))
  2570. {
  2571. (*pointer_) = t;
  2572. ++pointer_;
  2573. ++insert_count_;
  2574. }
  2575. return (*this);
  2576. }
  2577. inline range_to_ptr_type_iterator& operator=(const std::string& s)
  2578. {
  2579. value_type t = value_type();
  2580. if (string_to_type_converter(s.data(),s.data() + s.size(),t))
  2581. {
  2582. (*pointer_) = t;
  2583. ++pointer_;
  2584. ++insert_count_;
  2585. }
  2586. return (*this);
  2587. }
  2588. template <typename Iterator>
  2589. inline void operator()(const std::pair<Iterator,Iterator>& r) const
  2590. {
  2591. value_type t;
  2592. if (string_to_type_converter(r.first,r.second,t))
  2593. {
  2594. (*pointer_) = t;
  2595. ++pointer_;
  2596. ++insert_count_;
  2597. }
  2598. }
  2599. template <typename Iterator>
  2600. inline void operator()(const Iterator begin, const Iterator end)
  2601. {
  2602. (*pointer_) = string_to_type_converter<T>(begin,end);
  2603. ++pointer_;
  2604. ++insert_count_;
  2605. }
  2606. inline range_to_ptr_type_iterator& operator*()
  2607. {
  2608. return (*this);
  2609. }
  2610. inline range_to_ptr_type_iterator& operator++()
  2611. {
  2612. return (*this);
  2613. }
  2614. inline range_to_ptr_type_iterator operator++(int)
  2615. {
  2616. return (*this);
  2617. }
  2618. private:
  2619. T* pointer_;
  2620. std::size_t& insert_count_;
  2621. };
  2622. template <typename T>
  2623. inline range_to_ptr_type_iterator<T> range_to_ptr_type(T* pointer, std::size_t& insert_count)
  2624. {
  2625. return (range_to_ptr_type_iterator<T>(pointer,insert_count));
  2626. }
  2627. template <typename T>
  2628. inline range_to_ptr_type_iterator<T> range_to_ptr_type(T* pointer)
  2629. {
  2630. static std::size_t insert_count = 0;
  2631. return (range_to_ptr_type_iterator<T>(pointer,insert_count));
  2632. }
  2633. template <typename T>
  2634. class counting_back_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2635. T,
  2636. void,
  2637. void,
  2638. void>
  2639. {
  2640. public:
  2641. explicit inline counting_back_inserter_iterator(std::size_t& counter)
  2642. : counter_(counter)
  2643. {}
  2644. counting_back_inserter_iterator(const counting_back_inserter_iterator& itr)
  2645. : counter_(itr.counter_)
  2646. {}
  2647. inline counting_back_inserter_iterator& operator=(const counting_back_inserter_iterator& itr)
  2648. {
  2649. if (this != &itr)
  2650. {
  2651. this->counter_ = itr.counter_;
  2652. }
  2653. return (*this);
  2654. }
  2655. inline counting_back_inserter_iterator& operator=(const T&)
  2656. {
  2657. ++counter_;
  2658. return (*this);
  2659. }
  2660. inline void operator()(const T&)
  2661. {
  2662. ++counter_;
  2663. }
  2664. inline counting_back_inserter_iterator& operator*()
  2665. {
  2666. return (*this);
  2667. }
  2668. inline counting_back_inserter_iterator& operator++()
  2669. {
  2670. return (*this);
  2671. }
  2672. inline counting_back_inserter_iterator operator++(int)
  2673. {
  2674. return (*this);
  2675. }
  2676. private:
  2677. std::size_t& counter_;
  2678. };
  2679. template <typename T>
  2680. inline counting_back_inserter_iterator<T> counting_back_inserter(std::size_t& counter_)
  2681. {
  2682. return (counting_back_inserter_iterator<T>(counter_));
  2683. }
  2684. template <typename Function>
  2685. class functional_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2686. void,
  2687. void,
  2688. void,
  2689. void>
  2690. {
  2691. public:
  2692. explicit inline functional_inserter_iterator(Function function)
  2693. : function_(function)
  2694. {}
  2695. functional_inserter_iterator(const functional_inserter_iterator& itr)
  2696. : function_(itr.function_)
  2697. {}
  2698. inline functional_inserter_iterator& operator=(const functional_inserter_iterator& itr)
  2699. {
  2700. if (this != &itr)
  2701. {
  2702. this->function_ = itr.function_;
  2703. }
  2704. return (*this);
  2705. }
  2706. template <typename T>
  2707. inline functional_inserter_iterator& operator=(const T& t)
  2708. {
  2709. function_(t);
  2710. return (*this);
  2711. }
  2712. template <typename T>
  2713. inline void operator()(const T& t)
  2714. {
  2715. function_(t);
  2716. }
  2717. inline functional_inserter_iterator& operator*()
  2718. {
  2719. return (*this);
  2720. }
  2721. inline functional_inserter_iterator& operator++()
  2722. {
  2723. return (*this);
  2724. }
  2725. inline functional_inserter_iterator operator++(int)
  2726. {
  2727. return (*this);
  2728. }
  2729. private:
  2730. Function function_;
  2731. };
  2732. template <typename Function>
  2733. inline functional_inserter_iterator<Function> functional_inserter(Function function)
  2734. {
  2735. return (functional_inserter_iterator<Function>(function));
  2736. }
  2737. namespace split_options
  2738. {
  2739. typedef std::size_t type;
  2740. enum
  2741. {
  2742. default_mode = 0,
  2743. compress_delimiters = 1,
  2744. include_1st_delimiter = 2,
  2745. include_all_delimiters = 4
  2746. };
  2747. static inline bool perform_compress_delimiters(const type& split_opt)
  2748. {
  2749. return compress_delimiters == (split_opt & compress_delimiters);
  2750. }
  2751. static inline bool perform_include_1st_delimiter(const type& split_opt)
  2752. {
  2753. return include_1st_delimiter == (split_opt & include_1st_delimiter);
  2754. }
  2755. static inline bool perform_include_all_delimiters(const type& split_opt)
  2756. {
  2757. return include_all_delimiters == (split_opt & include_all_delimiters);
  2758. }
  2759. } // namespace split_options
  2760. namespace details
  2761. {
  2762. template <typename DelimiterPredicate,
  2763. typename Iterator,
  2764. typename OutputIterator>
  2765. inline std::size_t split_compress_delimiters(const DelimiterPredicate& delimiter,
  2766. const Iterator begin,
  2767. const Iterator end,
  2768. OutputIterator out)
  2769. {
  2770. std::size_t token_count = 0;
  2771. std::pair<Iterator,Iterator> range(begin,begin);
  2772. while (end != range.second)
  2773. {
  2774. if (delimiter(*range.second))
  2775. {
  2776. (*out) = range;
  2777. ++out;
  2778. while ((end != ++range.second) && delimiter(*range.second));
  2779. range.first = range.second;
  2780. if (end != range.second)
  2781. ++range.second;
  2782. ++token_count;
  2783. }
  2784. else
  2785. ++range.second;
  2786. }
  2787. if ((range.first != range.second) || delimiter(*(range.second - 1)))
  2788. {
  2789. (*out) = range;
  2790. ++out;
  2791. ++token_count;
  2792. }
  2793. return token_count;
  2794. }
  2795. }
  2796. template <typename DelimiterPredicate,
  2797. typename Iterator,
  2798. typename OutputIterator>
  2799. inline std::size_t split(const DelimiterPredicate& delimiter,
  2800. const Iterator begin,
  2801. const Iterator end,
  2802. OutputIterator out,
  2803. const split_options::type split_option = split_options::default_mode)
  2804. {
  2805. if (begin == end) return 0;
  2806. const bool compress_delimiters = split_options::perform_compress_delimiters(split_option);
  2807. const bool include_1st_delimiter = split_options::perform_include_1st_delimiter(split_option);
  2808. const bool include_all_delimiters = (!include_1st_delimiter) && split_options::perform_include_all_delimiters(split_option);
  2809. const bool include_delimiters = include_1st_delimiter || include_all_delimiters;
  2810. if (compress_delimiters && (!include_delimiters))
  2811. {
  2812. return details::split_compress_delimiters(delimiter,begin,end,out);
  2813. }
  2814. std::size_t token_count = 0;
  2815. std::pair<Iterator,Iterator> range(begin,begin);
  2816. while (end != range.second)
  2817. {
  2818. if (delimiter(*range.second))
  2819. {
  2820. if (include_delimiters)
  2821. {
  2822. if (include_1st_delimiter)
  2823. ++range.second;
  2824. else if (include_all_delimiters)
  2825. while ((end != range.second) && delimiter(*range.second)) ++range.second;
  2826. (*out) = range;
  2827. ++out;
  2828. if ((!include_all_delimiters) && compress_delimiters)
  2829. while ((end != range.second) && delimiter(*range.second)) ++range.second;
  2830. }
  2831. else
  2832. {
  2833. (*out) = range;
  2834. ++out;
  2835. ++range.second;
  2836. }
  2837. ++token_count;
  2838. range.first = range.second;
  2839. }
  2840. else
  2841. ++range.second;
  2842. }
  2843. if ((range.first != range.second) || delimiter(*(range.second - 1)))
  2844. {
  2845. (*out) = range;
  2846. ++out;
  2847. ++token_count;
  2848. }
  2849. return token_count;
  2850. }
  2851. template <typename DelimiterPredicate,
  2852. typename Iterator,
  2853. typename OutputIterator>
  2854. inline std::size_t split(const DelimiterPredicate& delimiter,
  2855. const std::pair<Iterator,Iterator>& range,
  2856. OutputIterator out,
  2857. const split_options::type split_option = split_options::default_mode)
  2858. {
  2859. return split(delimiter,
  2860. range.first,range.second,
  2861. out,
  2862. split_option);
  2863. }
  2864. template <typename DelimiterPredicate,
  2865. typename Iterator,
  2866. typename OutputIterator>
  2867. inline std::size_t split(const char* delimiters,
  2868. const std::pair<Iterator,Iterator>& range,
  2869. OutputIterator out,
  2870. const split_options::type split_option = split_options::default_mode)
  2871. {
  2872. if (1 == details::strnlength(delimiters,256))
  2873. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2874. range.first,range.second,
  2875. out,
  2876. split_option);
  2877. else
  2878. return split(multiple_char_delimiter_predicate(delimiters),
  2879. range.first,range.second,
  2880. out,
  2881. split_option);
  2882. }
  2883. template <typename DelimiterPredicate,
  2884. typename Iterator,
  2885. typename OutputIterator>
  2886. inline std::size_t split(const std::string& delimiters,
  2887. const std::pair<Iterator,Iterator>& range,
  2888. OutputIterator out,
  2889. const split_options::type split_option = split_options::default_mode)
  2890. {
  2891. if (1 == delimiters.size())
  2892. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2893. range.first,range.second,
  2894. out,
  2895. split_option);
  2896. else
  2897. return split(multiple_char_delimiter_predicate(delimiters),
  2898. range.first,range.second,
  2899. out,
  2900. split_option);
  2901. }
  2902. template <typename OutputIterator>
  2903. inline std::size_t split(const char* delimiters,
  2904. const std::string& str,
  2905. OutputIterator out,
  2906. const split_options::type& split_option = split_options::default_mode)
  2907. {
  2908. if (1 == details::strnlength(delimiters,256))
  2909. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2910. str.data(), str.data() + str.size(),
  2911. out,
  2912. split_option);
  2913. else
  2914. return split(multiple_char_delimiter_predicate(delimiters),
  2915. str.data(), str.data() + str.size(),
  2916. out,
  2917. split_option);
  2918. }
  2919. template <typename OutputIterator>
  2920. inline std::size_t split(const std::string& delimiters,
  2921. const std::string& str,
  2922. OutputIterator out,
  2923. const split_options::type& split_option = split_options::default_mode)
  2924. {
  2925. if (1 == delimiters.size())
  2926. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2927. str.data(), str.data() + str.size(),
  2928. out,
  2929. split_option);
  2930. else
  2931. return split(multiple_char_delimiter_predicate(delimiters),
  2932. str.data(), str.data() + str.size(),
  2933. out,
  2934. split_option);
  2935. }
  2936. template <typename OutputIterator>
  2937. inline std::size_t split(const std::string::value_type delimiter,
  2938. const std::string& str,
  2939. OutputIterator out,
  2940. const split_options::type& split_option = split_options::default_mode)
  2941. {
  2942. return split(single_delimiter_predicate<std::string::value_type>(delimiter),
  2943. str.data(), str.data() + str.size(),
  2944. out,
  2945. split_option);
  2946. }
  2947. template <typename Allocator,
  2948. template <typename,typename> class Sequence>
  2949. inline std::size_t split(const char* delimiters,
  2950. const std::string& str,
  2951. Sequence<std::pair<const char*, const char*>,Allocator>& sequence,
  2952. const split_options::type& split_option = split_options::default_mode)
  2953. {
  2954. if (1 == details::strnlength(delimiters,256))
  2955. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2956. str.data(), str.data() + str.size(),
  2957. std::back_inserter(sequence),
  2958. split_option);
  2959. else
  2960. return split(multiple_char_delimiter_predicate(delimiters),
  2961. str.data(), str.data() + str.size(),
  2962. std::back_inserter(sequence),
  2963. split_option);
  2964. }
  2965. template <typename Allocator,
  2966. template <typename,typename> class Sequence>
  2967. inline std::size_t split(const std::string& delimiters,
  2968. const std::string& str,
  2969. Sequence<std::pair<const char*, const char*>,Allocator>& sequence,
  2970. const split_options::type& split_option = split_options::default_mode)
  2971. {
  2972. if (1 == delimiters.size())
  2973. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2974. str.data(), str.data() + str.size(),
  2975. std::back_inserter(sequence),
  2976. split_option);
  2977. else
  2978. return split(multiple_char_delimiter_predicate(delimiters),
  2979. str.data(), str.data() + str.size(),
  2980. std::back_inserter(sequence),
  2981. split_option);
  2982. }
  2983. template <typename DelimiterPredicate,
  2984. typename OutputIterator>
  2985. inline std::size_t split(const DelimiterPredicate& delimiter,
  2986. const std::string& str,
  2987. OutputIterator out,
  2988. const split_options::type& split_option = split_options::default_mode)
  2989. {
  2990. return split(delimiter,
  2991. str.data(), str.data() + str.size(),
  2992. out,
  2993. split_option);
  2994. }
  2995. template <typename DelimiterPredicate,
  2996. typename Iterator,
  2997. typename OutputIterator>
  2998. inline std::size_t split_n(const DelimiterPredicate& delimiter,
  2999. const Iterator begin,
  3000. const Iterator end,
  3001. const std::size_t& token_count,
  3002. OutputIterator out,
  3003. const split_options::type& split_option = split_options::default_mode)
  3004. {
  3005. if (0 == token_count) return 0;
  3006. if (begin == end) return 0;
  3007. std::size_t match_count = 0;
  3008. std::pair<Iterator,Iterator> range(begin,begin);
  3009. const bool compress_delimiters = split_options::perform_compress_delimiters(split_option);
  3010. const bool include_1st_delimiter = split_options::perform_include_1st_delimiter(split_option);
  3011. const bool include_all_delimiters = (!include_1st_delimiter) && split_options::perform_include_all_delimiters(split_option);
  3012. const bool include_delimiters = include_1st_delimiter || include_all_delimiters;
  3013. while (end != range.second)
  3014. {
  3015. if (delimiter(*range.second))
  3016. {
  3017. if (include_delimiters)
  3018. {
  3019. ++range.second;
  3020. (*out) = range;
  3021. ++out;
  3022. if (++match_count >= token_count)
  3023. return match_count;
  3024. if (compress_delimiters)
  3025. while ((end != range.second) && delimiter(*range.second)) ++range.second;
  3026. }
  3027. else
  3028. {
  3029. (*out) = range;
  3030. ++out;
  3031. if (++match_count >= token_count)
  3032. return match_count;
  3033. if (compress_delimiters)
  3034. while ((end != (++range.second)) && delimiter(*range.second)) ;
  3035. else
  3036. ++range.second;
  3037. }
  3038. range.first = range.second;
  3039. }
  3040. else
  3041. ++range.second;
  3042. }
  3043. if ((range.first != range.second) || delimiter(*(range.second - 1)))
  3044. {
  3045. (*out) = range;
  3046. ++out;
  3047. ++match_count;
  3048. }
  3049. return match_count;
  3050. }
  3051. template <typename OutputIterator>
  3052. inline std::size_t split_n(const char* delimiters,
  3053. const std::string& str,
  3054. const std::size_t& token_count,
  3055. OutputIterator out,
  3056. const split_options::type& split_option = split_options::default_mode)
  3057. {
  3058. return split_n(multiple_char_delimiter_predicate(delimiters),
  3059. str.data(), str.data() + str.size(),
  3060. token_count,
  3061. out,
  3062. split_option);
  3063. }
  3064. template <typename OutputIterator>
  3065. inline std::size_t split_n(const std::string& delimiters,
  3066. const std::string& str,
  3067. const std::size_t& token_count,
  3068. OutputIterator out,
  3069. const split_options::type& split_option = split_options::default_mode)
  3070. {
  3071. if (1 == delimiters.size())
  3072. return split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  3073. str.data(), str.data() + str.size(),
  3074. token_count,
  3075. out,
  3076. split_option);
  3077. else
  3078. return split_n(multiple_char_delimiter_predicate(delimiters),
  3079. str.data(), str.data() + str.size(),
  3080. token_count,
  3081. out,
  3082. split_option);
  3083. }
  3084. template <typename InputIterator, typename OutputIterator>
  3085. inline std::size_t split_n(const std::string& delimiters,
  3086. const InputIterator begin,
  3087. const InputIterator end,
  3088. const std::size_t& token_count,
  3089. OutputIterator out,
  3090. const split_options::type& split_option = split_options::default_mode)
  3091. {
  3092. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  3093. details::convert_type_assert<itr_type>();
  3094. if (1 == delimiters.size())
  3095. return split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  3096. begin,end,
  3097. token_count,
  3098. out,
  3099. split_option);
  3100. else
  3101. return split_n(multiple_char_delimiter_predicate(delimiters),
  3102. begin,end,
  3103. token_count,
  3104. out,
  3105. split_option);
  3106. }
  3107. template <typename OutputIterator>
  3108. inline std::size_t split_n(const std::string::value_type delimiter,
  3109. const std::string& str,
  3110. const std::size_t& token_count,
  3111. OutputIterator out,
  3112. const split_options::type& split_option = split_options::default_mode)
  3113. {
  3114. return split_n(single_delimiter_predicate<std::string::value_type>(delimiter),
  3115. str.data(),str.data() + str.size(),
  3116. token_count,
  3117. out,
  3118. split_option);
  3119. }
  3120. template <typename DelimiterPredicate,
  3121. typename OutputIterator>
  3122. inline std::size_t split_n(const DelimiterPredicate& delimiter,
  3123. const std::string& str,
  3124. const std::size_t& token_count,
  3125. OutputIterator out,
  3126. const split_options::type& split_option = split_options::default_mode)
  3127. {
  3128. return split_n(delimiter,
  3129. str.data(),str.data() + str.size(),
  3130. token_count,
  3131. out,
  3132. split_option);
  3133. }
  3134. #ifdef strtk_enable_regex
  3135. static const std::string uri_expression ("((https?|ftp)\\://((\\[?(\\d{1,3}\\.){3}\\d{1,3}\\]?)|(([-a-zA-Z0-9]+\\.)+[a-zA-Z]{2,4}))(\\:\\d+)?(/[-a-zA-Z0-9._?,+&amp;%$#=~\\\\]+)*/?)");
  3136. static const std::string email_expression ("([\\w\\-\\.]+)@((\\[([0-9]{1,3}\\.){3}[0-9]{1,3}\\])|(([\\w\\-]+\\.)+)([a-zA-Z]{2,4}))");
  3137. static const std::string ip_expression ("(([0-2]*[0-9]+[0-9]+)\\.([0-2]*[0-9]+[0-9]+)\\.([0-2]*[0-9]+[0-9]+)\\.([0-2]*[0-9]+[0-9]+))");
  3138. static const std::string ieee754_expression ("([-+]?((\\.[0-9]+|[0-9]+\\.[0-9]+)([eE][-+][0-9]+)?|[0-9]+))");
  3139. namespace regex_match_mode
  3140. {
  3141. enum type
  3142. {
  3143. match_all = 0,
  3144. match_1 = 1,
  3145. match_2 = 2,
  3146. match_3 = 3,
  3147. match_4 = 4,
  3148. match_5 = 5,
  3149. match_6 = 6,
  3150. match_7 = 7,
  3151. match_8 = 8,
  3152. match_9 = 9
  3153. };
  3154. }
  3155. template <typename InputIterator, typename OutputIterator>
  3156. inline std::size_t split_regex(const boost::regex& delimiter_expression,
  3157. const InputIterator begin,
  3158. const InputIterator end,
  3159. OutputIterator out,
  3160. const regex_match_mode::type mode = regex_match_mode::match_all)
  3161. {
  3162. boost::regex_iterator<InputIterator> itr(begin,end,delimiter_expression);
  3163. boost::regex_iterator<InputIterator> itr_end;
  3164. std::pair<InputIterator,InputIterator> range(begin,begin);
  3165. std::size_t match_count = 0;
  3166. while (itr_end != itr)
  3167. {
  3168. range.first = (*itr)[mode].first;
  3169. range.second = (*itr)[mode].second;
  3170. (*out) = range;
  3171. ++out;
  3172. ++itr;
  3173. ++match_count;
  3174. }
  3175. return match_count;
  3176. }
  3177. template <typename InputIterator, typename OutputIterator>
  3178. inline std::size_t split_regex(const std::string& delimiter_expression,
  3179. const InputIterator begin,
  3180. const InputIterator end,
  3181. OutputIterator out,
  3182. const regex_match_mode::type mode = regex_match_mode::match_all)
  3183. {
  3184. const boost::regex regex_expression(delimiter_expression);
  3185. return split_regex(regex_expression,
  3186. begin,end,
  3187. out,
  3188. mode);
  3189. }
  3190. template <typename OutputIterator>
  3191. inline std::size_t split_regex(const std::string& delimiter_expression,
  3192. const std::string& text,
  3193. OutputIterator out,
  3194. const regex_match_mode::type mode = regex_match_mode::match_all)
  3195. {
  3196. return split_regex(delimiter_expression,
  3197. text.begin(),text.end(),
  3198. out,
  3199. mode);
  3200. }
  3201. template <typename OutputIterator>
  3202. inline std::size_t split_regex(const boost::regex& delimiter_expression,
  3203. const std::string& text,
  3204. OutputIterator out,
  3205. const regex_match_mode::type mode = regex_match_mode::match_all)
  3206. {
  3207. return split_regex(delimiter_expression,
  3208. text.begin(),text.end(),
  3209. out,
  3210. mode);
  3211. }
  3212. template <typename InputIterator, typename OutputIterator>
  3213. inline std::size_t split_regex_n(const boost::regex& delimiter_expression,
  3214. const InputIterator begin,
  3215. const InputIterator end,
  3216. const std::size_t& token_count,
  3217. OutputIterator out,
  3218. const regex_match_mode::type mode = regex_match_mode::match_all)
  3219. {
  3220. boost::sregex_iterator itr(begin,end,delimiter_expression);
  3221. const boost::sregex_iterator itr_end;
  3222. std::pair<InputIterator,InputIterator> range(begin,begin);
  3223. std::size_t match_count = 0;
  3224. while (itr_end != itr)
  3225. {
  3226. range.first = (*itr)[mode].first;
  3227. range.second = (*itr)[mode].second;
  3228. (*out) = range;
  3229. ++out;
  3230. ++itr;
  3231. if (++match_count >= token_count)
  3232. return match_count;
  3233. }
  3234. return match_count;
  3235. }
  3236. template <typename InputIterator, typename OutputIterator>
  3237. inline std::size_t split_regex_n(const std::string& delimiter_expression,
  3238. const InputIterator begin,
  3239. const InputIterator end,
  3240. const std::size_t& token_count,
  3241. OutputIterator out,
  3242. const regex_match_mode::type mode = regex_match_mode::match_all)
  3243. {
  3244. const boost::regex regex_expression(delimiter_expression);
  3245. return split_regex_n(regex_expression,
  3246. begin,end,
  3247. token_count,
  3248. out,
  3249. mode);
  3250. }
  3251. template <typename OutputIterator>
  3252. inline std::size_t split_regex_n(const std::string& delimiter_expression,
  3253. const std::string& text,
  3254. const std::size_t& token_count,
  3255. OutputIterator out,
  3256. const regex_match_mode::type mode = regex_match_mode::match_all)
  3257. {
  3258. return split_regex_n(delimiter_expression,
  3259. text.begin(),text.end(),
  3260. token_count,
  3261. out,
  3262. mode);
  3263. }
  3264. template <typename OutputIterator>
  3265. inline std::size_t split_regex_n(const boost::regex& delimiter_expression,
  3266. const std::string& text,
  3267. const std::size_t& token_count,
  3268. OutputIterator out,
  3269. const regex_match_mode::type mode = regex_match_mode::match_all)
  3270. {
  3271. return split_regex_n(delimiter_expression,
  3272. text.begin(),text.end(),
  3273. token_count,
  3274. out,
  3275. mode);
  3276. }
  3277. #endif // strtk_enable_regex
  3278. template <const std::size_t offset_list_size>
  3279. class offset_predicate
  3280. {
  3281. public:
  3282. offset_predicate(const int offset_list[], const bool rotate = false)
  3283. : rotate_(rotate),
  3284. current_index_(0)
  3285. {
  3286. std::copy(offset_list, offset_list + offset_list_size, offset_list_);
  3287. offset_list_[offset_list_size] = 0;
  3288. }
  3289. inline bool operator!() const
  3290. {
  3291. return (0 == offset_list_size);
  3292. }
  3293. inline void reset() const
  3294. {
  3295. current_index_ = 0;
  3296. }
  3297. inline std::size_t size() const
  3298. {
  3299. return offset_list_size;
  3300. }
  3301. inline int next() const
  3302. {
  3303. int result = offset_list_[current_index_++];
  3304. if (rotate_ && (current_index_ >= offset_list_size))
  3305. {
  3306. current_index_ = 0;
  3307. }
  3308. return result;
  3309. }
  3310. private:
  3311. bool rotate_;
  3312. mutable std::size_t current_index_;
  3313. int offset_list_[offset_list_size + 1];
  3314. };
  3315. inline offset_predicate<12> offsets(const int& v1, const int& v2, const int& v3,
  3316. const int& v4, const int& v5, const int& v6,
  3317. const int& v7, const int& v8, const int& v9,
  3318. const int& v10, const int& v11, const int& v12,
  3319. const bool& rotate = false)
  3320. {
  3321. const int offset_list[12] = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 };
  3322. return offset_predicate<12>(offset_list,rotate);
  3323. }
  3324. inline offset_predicate<11> offsets(const int& v1, const int& v2, const int& v3,
  3325. const int& v4, const int& v5, const int& v6,
  3326. const int& v7, const int& v8, const int& v9,
  3327. const int& v10, const int& v11,
  3328. const bool& rotate = false)
  3329. {
  3330. const int offset_list[11] = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 };
  3331. return offset_predicate<11>(offset_list,rotate);
  3332. }
  3333. inline offset_predicate<10> offsets(const int& v1, const int& v2, const int& v3,
  3334. const int& v4, const int& v5, const int& v6,
  3335. const int& v7, const int& v8, const int& v9,
  3336. const int& v10, const bool& rotate = false)
  3337. {
  3338. const int offset_list[10] = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 };
  3339. return offset_predicate<10>(offset_list,rotate);
  3340. }
  3341. inline offset_predicate<9> offsets(const int& v1, const int& v2, const int& v3,
  3342. const int& v4, const int& v5, const int& v6,
  3343. const int& v7, const int& v8, const int& v9,
  3344. const bool& rotate = false)
  3345. {
  3346. const int offset_list[9] = { v1, v2, v3, v4, v5, v6, v7, v8, v9 };
  3347. return offset_predicate<9>(offset_list,rotate);
  3348. }
  3349. inline offset_predicate<8> offsets(const int& v1, const int& v2, const int& v3,
  3350. const int& v4, const int& v5, const int& v6,
  3351. const int& v7, const int& v8, const bool& rotate = false)
  3352. {
  3353. const int offset_list[8] = { v1, v2, v3, v4, v5, v6, v7, v8 };
  3354. return offset_predicate<8>(offset_list,rotate);
  3355. }
  3356. inline offset_predicate<7> offsets(const int& v1, const int& v2, const int& v3,
  3357. const int& v4, const int& v5, const int& v6,
  3358. const int& v7, const bool& rotate = false)
  3359. {
  3360. const int offset_list[7] = { v1, v2, v3, v4, v5, v6, v7 };
  3361. return offset_predicate<7>(offset_list,rotate);
  3362. }
  3363. inline offset_predicate<6> offsets(const int& v1, const int& v2, const int& v3,
  3364. const int& v4, const int& v5, const int& v6,
  3365. const bool& rotate = false)
  3366. {
  3367. const int offset_list[6] = { v1, v2, v3, v4, v5, v6 };
  3368. return offset_predicate<6>(offset_list,rotate);
  3369. }
  3370. inline offset_predicate<5> offsets(const int& v1, const int& v2, const int& v3,
  3371. const int& v4, const int& v5, const bool& rotate = false)
  3372. {
  3373. const int offset_list[5] = { v1, v2, v3, v4, v5 };
  3374. return offset_predicate<5>(offset_list,rotate);
  3375. }
  3376. inline offset_predicate<4> offsets(const int& v1, const int& v2, const int& v3,
  3377. const int& v4, const bool& rotate = false)
  3378. {
  3379. const int offset_list[4] = { v1, v2, v3, v4 };
  3380. return offset_predicate<4>(offset_list,rotate);
  3381. }
  3382. inline offset_predicate<3> offsets(const int& v1, const int& v2, const int& v3,
  3383. const bool& rotate = false)
  3384. {
  3385. const int offset_list[3] = { v1, v2, v3 };
  3386. return offset_predicate<3>(offset_list,rotate);
  3387. }
  3388. inline offset_predicate<2> offsets(const int& v1, const int& v2, const bool& rotate = false)
  3389. {
  3390. const int offset_list[2] = { v1, v2 };
  3391. return offset_predicate<2>(offset_list,rotate);
  3392. }
  3393. inline offset_predicate<1> offsets(const int& v1,
  3394. const bool& rotate = false)
  3395. {
  3396. const int offset_list[1] = { v1 };
  3397. return offset_predicate<1>(offset_list,rotate);
  3398. }
  3399. template <typename OffsetPredicate,
  3400. typename InputIterator,
  3401. typename OutputIterator>
  3402. inline std::size_t offset_splitter(const InputIterator begin,
  3403. const InputIterator end,
  3404. const OffsetPredicate& offset,
  3405. OutputIterator out)
  3406. {
  3407. std::size_t length = 0;
  3408. if (0 == (length = std::distance(begin,end))) return 0;
  3409. std::pair<InputIterator,InputIterator> range(begin,begin);
  3410. std::size_t match_count = 0;
  3411. int offset_length = 0;
  3412. std::size_t increment_amount = 0;
  3413. while ((end != range.second) && (0 < (offset_length = offset.next())))
  3414. {
  3415. increment_amount = std::min<std::size_t>(length,offset_length);
  3416. range.first = range.second;
  3417. range.second += increment_amount;
  3418. length -= increment_amount;
  3419. (*out) = range;
  3420. ++out;
  3421. ++match_count;
  3422. }
  3423. return match_count;
  3424. }
  3425. template <typename OffsetPredicate,
  3426. typename OutputIterator>
  3427. inline std::size_t offset_splitter(const std::string& str,
  3428. const OffsetPredicate& offset,
  3429. OutputIterator out)
  3430. {
  3431. return offset_splitter(str.data(),str.data() + str.size(),offset,out);
  3432. }
  3433. template <typename InputIterator,
  3434. typename Predicate,
  3435. typename OutputPair>
  3436. inline bool split_pair(const InputIterator begin,
  3437. const InputIterator end,
  3438. const Predicate& delimiter,
  3439. OutputPair& v1,
  3440. OutputPair& v2)
  3441. {
  3442. if (0 == std::distance(begin,end)) return false;
  3443. InputIterator itr = begin;
  3444. while (end != itr)
  3445. {
  3446. if (delimiter(*itr))
  3447. {
  3448. v1 = std::make_pair(begin,itr);
  3449. ++itr;
  3450. if (0 != std::distance(itr,end))
  3451. {
  3452. v2 = std::make_pair(itr,end);
  3453. return true;
  3454. }
  3455. else
  3456. return false;
  3457. }
  3458. else
  3459. ++itr;
  3460. }
  3461. return false;
  3462. }
  3463. inline bool split_pair(const std::string::value_type delimiter,
  3464. const std::string& str,
  3465. std::pair<const char*,const char*>& v1,
  3466. std::pair<const char*,const char*>& v2)
  3467. {
  3468. return split_pair(str.data(),
  3469. str.data() + str.size(),
  3470. single_delimiter_predicate<std::string::value_type>(delimiter),
  3471. v1,
  3472. v2);
  3473. }
  3474. template <typename DelimiterPredicate>
  3475. inline bool split_pair(const DelimiterPredicate& delimiter,
  3476. const std::string& str,
  3477. std::pair<const char*,const char*>& v1,
  3478. std::pair<const char*,const char*>& v2)
  3479. {
  3480. return split_pair(str.data(),
  3481. str.data() + str.size(),
  3482. delimiter,
  3483. v1,
  3484. v2);
  3485. }
  3486. template <typename Function>
  3487. inline std::size_t for_each_token(const std::string& buffer,
  3488. const std::string& delimiters,
  3489. Function function)
  3490. {
  3491. return split(delimiters,
  3492. buffer,
  3493. strtk::functional_inserter<Function>(function));
  3494. }
  3495. template <typename Function>
  3496. inline std::size_t for_each_token(const std::string& buffer,
  3497. const char* delimiters,
  3498. Function function)
  3499. {
  3500. return split(delimiters,
  3501. buffer,
  3502. strtk::functional_inserter<Function>(function));
  3503. }
  3504. template <typename InputIterator>
  3505. inline std::size_t count_consecutive_duplicates(const InputIterator begin, const InputIterator end)
  3506. {
  3507. if (std::distance(begin,end) < 2) return 0;
  3508. InputIterator prev = begin;
  3509. InputIterator itr = begin;
  3510. std::size_t count = 0;
  3511. while (end != ++itr)
  3512. {
  3513. if ((*prev) == (*itr))
  3514. ++count;
  3515. else
  3516. prev = itr;
  3517. }
  3518. return count;
  3519. }
  3520. template <typename T,
  3521. typename Allocator,
  3522. template <typename,typename> class Sequence>
  3523. inline T min_of_cont(const Sequence<T,Allocator>& sequence)
  3524. {
  3525. return (*std::min_element(sequence.begin(),sequence.end()));
  3526. }
  3527. template <typename T,
  3528. typename Comparator,
  3529. typename Allocator>
  3530. inline T min_of_cont(const std::set<T,Comparator,Allocator>& set)
  3531. {
  3532. return (*set.begin());
  3533. }
  3534. template <typename T,
  3535. typename Comparator,
  3536. typename Allocator>
  3537. inline T min_of_cont(const std::multiset<T,Comparator,Allocator>& multiset)
  3538. {
  3539. return (*multiset.begin());
  3540. }
  3541. template <typename T,
  3542. typename Allocator,
  3543. template <typename,typename> class Sequence>
  3544. inline T max_of_cont(const Sequence<T,Allocator>& sequence)
  3545. {
  3546. return (*std::max_element(sequence.begin(),sequence.end()));
  3547. }
  3548. template <typename T,
  3549. typename Comparator,
  3550. typename Allocator>
  3551. inline T max_of_cont(const std::set<T,Comparator,Allocator>& set)
  3552. {
  3553. return (*set.rbegin());
  3554. }
  3555. template <typename T,
  3556. typename Comparator,
  3557. typename Allocator>
  3558. inline T max_of_cont(const std::multiset<T,Comparator,Allocator>& multiset)
  3559. {
  3560. return (*multiset.rbegin());
  3561. }
  3562. template <typename InputIterator>
  3563. inline void min_max_of_range(const InputIterator begin, const InputIterator end,
  3564. typename std::iterator_traits<InputIterator>::value_type& min_value,
  3565. typename std::iterator_traits<InputIterator>::value_type& max_value)
  3566. {
  3567. min_value = *begin;
  3568. max_value = *begin;
  3569. InputIterator itr = begin;
  3570. while (end != ++itr)
  3571. {
  3572. if (*itr < min_value)
  3573. min_value = (*itr);
  3574. else if (*itr > max_value)
  3575. max_value = (*itr);
  3576. }
  3577. }
  3578. template <typename T,
  3579. typename Allocator,
  3580. template <typename,typename> class Sequence>
  3581. inline void min_max_of_cont(const Sequence<T,Allocator>& sequence,
  3582. T& min_value,
  3583. T& max_value)
  3584. {
  3585. min_max_of_range(sequence.begin(),sequence.end(),
  3586. min_value,
  3587. max_value);
  3588. }
  3589. template <typename T,
  3590. typename Comparator,
  3591. typename Allocator>
  3592. inline void min_max_of_cont(const std::set<T,Comparator,Allocator>& set,
  3593. T& min_value,
  3594. T& max_value)
  3595. {
  3596. min_value = (*set.begin());
  3597. max_value = (*set.rbegin());
  3598. }
  3599. template <typename T,
  3600. typename Comparator,
  3601. typename Allocator>
  3602. inline void min_max_of_cont(const std::multiset<T,Comparator,Allocator>& multiset,
  3603. T& min_value,
  3604. T& max_value)
  3605. {
  3606. min_value = (*multiset.begin());
  3607. max_value = (*multiset.rbegin());
  3608. }
  3609. template <typename Iterator>
  3610. inline void lexicographically_canonicalize(Iterator begin, Iterator end)
  3611. {
  3612. typedef typename std::iterator_traits<Iterator>::value_type type;
  3613. typedef typename std::pair<Iterator,Iterator> iter_type;
  3614. typedef typename std::list<iter_type> itr_list_type;
  3615. itr_list_type itr_list;
  3616. type smallest = (*std::min_element(begin,end));
  3617. for (Iterator itr = begin; itr != end; ++itr)
  3618. {
  3619. if (*itr == smallest) itr_list.push_back(std::make_pair(itr,itr));
  3620. }
  3621. while (itr_list.size() > 1)
  3622. {
  3623. typename itr_list_type::iterator itr = itr_list.begin();
  3624. while (itr_list.end() != itr)
  3625. {
  3626. ++(*itr).first;
  3627. if (end == (*itr).first)
  3628. itr = itr_list.erase(itr);
  3629. else
  3630. ++itr;
  3631. }
  3632. smallest = *(*itr_list.begin()).first;
  3633. for (itr = (++itr_list.begin()); itr != itr_list.end(); ++itr)
  3634. {
  3635. if (*(*itr).first < smallest)
  3636. {
  3637. smallest = *(*itr).first;
  3638. }
  3639. }
  3640. itr = itr_list.begin();
  3641. while (itr_list.end() != itr)
  3642. {
  3643. if (*(*itr).first != smallest)
  3644. itr = itr_list.erase(itr);
  3645. else
  3646. ++itr;
  3647. }
  3648. itr = itr_list.begin();
  3649. while (itr_list.end() != itr)
  3650. {
  3651. if (end == (*itr).first)
  3652. itr = itr_list.erase(itr);
  3653. else
  3654. ++itr;
  3655. }
  3656. }
  3657. std::rotate(begin,(*itr_list.begin()).second,end);
  3658. }
  3659. inline void lexicographically_canonicalize(std::string& str)
  3660. {
  3661. lexicographically_canonicalize(const_cast<char*>(str.data()),
  3662. const_cast<char*>(str.data() + str.size()));
  3663. }
  3664. template <typename T,
  3665. typename Allocator,
  3666. template <typename,typename> class Sequence>
  3667. inline void lexicographically_canonicalize(Sequence<T,Allocator>& sequence)
  3668. {
  3669. lexicographically_canonicalize(sequence.begin(),sequence.end());
  3670. }
  3671. inline const char* first_non_repeated_char(const char* begin, const char* end)
  3672. {
  3673. static const std::size_t lut_size = 256;
  3674. unsigned long long int lut[lut_size];
  3675. std::fill_n(lut,lut_size,std::numeric_limits<unsigned long long int>::max());
  3676. static const unsigned long long int not_yet_encountered = std::numeric_limits<unsigned long long int>::max();
  3677. static const unsigned long long int repeated = not_yet_encountered - 1;
  3678. const char* itr = begin;
  3679. unsigned long long int position = 0;
  3680. while (end != itr)
  3681. {
  3682. unsigned long long int& element = lut[static_cast<unsigned int>(*itr)];
  3683. if (not_yet_encountered == element)
  3684. {
  3685. element = position;
  3686. }
  3687. else if (element < repeated)
  3688. {
  3689. element = repeated;
  3690. }
  3691. ++itr;
  3692. ++position;
  3693. }
  3694. position = repeated;
  3695. for (std::size_t i = 0; i < lut_size; ++i)
  3696. {
  3697. if (lut[i] < position)
  3698. position = lut[i];
  3699. }
  3700. return (repeated != position) ? (begin + position) : end;
  3701. }
  3702. inline const unsigned char* first_non_repeated_char(const unsigned char* begin, const unsigned char* end)
  3703. {
  3704. char * b = reinterpret_cast<char*>(const_cast<unsigned char*>(begin));
  3705. char * e = reinterpret_cast<char*>(const_cast<unsigned char*>(end));
  3706. return const_cast<const unsigned char*>(reinterpret_cast<unsigned char*>(const_cast<char*>(first_non_repeated_char(b,e))));
  3707. }
  3708. inline std::size_t first_non_repeated_char(const std::string& str)
  3709. {
  3710. if (str.empty())
  3711. return static_cast<std::size_t>(std::string::npos);
  3712. const char* itr = first_non_repeated_char(str.data(),str.data() + str.size());
  3713. if ((str.data() + str.size()) != itr)
  3714. return static_cast<std::size_t>(itr - str.data());
  3715. else
  3716. return static_cast<std::size_t>(std::string::npos);
  3717. }
  3718. inline void convert_bin_to_hex(const unsigned char* begin, const unsigned char* end, unsigned char* out)
  3719. {
  3720. static const unsigned short hex_lut[] =
  3721. {
  3722. 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730,
  3723. 0x3830, 0x3930, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530, 0x4630,
  3724. 0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731,
  3725. 0x3831, 0x3931, 0x4131, 0x4231, 0x4331, 0x4431, 0x4531, 0x4631,
  3726. 0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732,
  3727. 0x3832, 0x3932, 0x4132, 0x4232, 0x4332, 0x4432, 0x4532, 0x4632,
  3728. 0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733,
  3729. 0x3833, 0x3933, 0x4133, 0x4233, 0x4333, 0x4433, 0x4533, 0x4633,
  3730. 0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734,
  3731. 0x3834, 0x3934, 0x4134, 0x4234, 0x4334, 0x4434, 0x4534, 0x4634,
  3732. 0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735,
  3733. 0x3835, 0x3935, 0x4135, 0x4235, 0x4335, 0x4435, 0x4535, 0x4635,
  3734. 0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736,
  3735. 0x3836, 0x3936, 0x4136, 0x4236, 0x4336, 0x4436, 0x4536, 0x4636,
  3736. 0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737,
  3737. 0x3837, 0x3937, 0x4137, 0x4237, 0x4337, 0x4437, 0x4537, 0x4637,
  3738. 0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738,
  3739. 0x3838, 0x3938, 0x4138, 0x4238, 0x4338, 0x4438, 0x4538, 0x4638,
  3740. 0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739,
  3741. 0x3839, 0x3939, 0x4139, 0x4239, 0x4339, 0x4439, 0x4539, 0x4639,
  3742. 0x3041, 0x3141, 0x3241, 0x3341, 0x3441, 0x3541, 0x3641, 0x3741,
  3743. 0x3841, 0x3941, 0x4141, 0x4241, 0x4341, 0x4441, 0x4541, 0x4641,
  3744. 0x3042, 0x3142, 0x3242, 0x3342, 0x3442, 0x3542, 0x3642, 0x3742,
  3745. 0x3842, 0x3942, 0x4142, 0x4242, 0x4342, 0x4442, 0x4542, 0x4642,
  3746. 0x3043, 0x3143, 0x3243, 0x3343, 0x3443, 0x3543, 0x3643, 0x3743,
  3747. 0x3843, 0x3943, 0x4143, 0x4243, 0x4343, 0x4443, 0x4543, 0x4643,
  3748. 0x3044, 0x3144, 0x3244, 0x3344, 0x3444, 0x3544, 0x3644, 0x3744,
  3749. 0x3844, 0x3944, 0x4144, 0x4244, 0x4344, 0x4444, 0x4544, 0x4644,
  3750. 0x3045, 0x3145, 0x3245, 0x3345, 0x3445, 0x3545, 0x3645, 0x3745,
  3751. 0x3845, 0x3945, 0x4145, 0x4245, 0x4345, 0x4445, 0x4545, 0x4645,
  3752. 0x3046, 0x3146, 0x3246, 0x3346, 0x3446, 0x3546, 0x3646, 0x3746,
  3753. 0x3846, 0x3946, 0x4146, 0x4246, 0x4346, 0x4446, 0x4546, 0x4646
  3754. };
  3755. for (const unsigned char* itr = begin; end != itr; ++itr)
  3756. {
  3757. *reinterpret_cast<unsigned short*>(out) = hex_lut[(*itr)];
  3758. out += sizeof(unsigned short);
  3759. }
  3760. }
  3761. inline void convert_bin_to_hex(const char* begin, const char* end, char* out)
  3762. {
  3763. convert_bin_to_hex(reinterpret_cast<const unsigned char*>(begin),
  3764. reinterpret_cast<const unsigned char*>(end),
  3765. reinterpret_cast<unsigned char*>(out));
  3766. }
  3767. inline void convert_bin_to_hex(const std::pair<unsigned char*,unsigned char*>& r, unsigned char* out)
  3768. {
  3769. convert_bin_to_hex(r.first,r.second,out);
  3770. }
  3771. inline void convert_bin_to_hex(const std::pair<const unsigned char*,const unsigned char*>& r, unsigned char* out)
  3772. {
  3773. convert_bin_to_hex(r.first,r.second,out);
  3774. }
  3775. inline void convert_bin_to_hex(const std::pair<const char*,const char*>& r, char* out)
  3776. {
  3777. convert_bin_to_hex(r.first,r.second,out);
  3778. }
  3779. inline void convert_bin_to_hex(const std::string& binary_data, std::string& output)
  3780. {
  3781. output.resize(binary_data.size() * 2);
  3782. convert_bin_to_hex(binary_data.data(),
  3783. binary_data.data() + binary_data.size(),
  3784. const_cast<char*>(output.data()));
  3785. }
  3786. inline std::string convert_bin_to_hex(const std::string& binary_data)
  3787. {
  3788. std::string output;
  3789. convert_bin_to_hex(binary_data,output);
  3790. return output;
  3791. }
  3792. inline bool convert_hex_to_bin(const unsigned char* begin, const unsigned char* end, unsigned char* out)
  3793. {
  3794. const std::size_t length = std::distance(begin,end);
  3795. if (0 == length)
  3796. return false;
  3797. else if (1 == (length % 2))
  3798. return false;
  3799. static const unsigned char hex_to_bin[] =
  3800. {
  3801. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 - 0x07
  3802. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 - 0x0F
  3803. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 - 0x17
  3804. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 - 0x1F
  3805. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 - 0x27
  3806. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 - 0x2F
  3807. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 0x30 - 0x37
  3808. 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 - 0x3F
  3809. 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, // 0x40 - 0x47
  3810. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 - 0x4F
  3811. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 - 0x57
  3812. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 - 0x5F
  3813. 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, // 0x60 - 0x67
  3814. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 - 0x6F
  3815. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 - 0x77
  3816. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 - 0x7F
  3817. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 - 0x87
  3818. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 - 0x8F
  3819. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 - 0x97
  3820. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 - 0x9F
  3821. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 - 0xA7
  3822. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 - 0xAF
  3823. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 - 0xB7
  3824. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 - 0xBF
  3825. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 - 0xC7
  3826. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 - 0xCF
  3827. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 - 0xD7
  3828. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 - 0xDF
  3829. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 - 0xE7
  3830. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 - 0xEF
  3831. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 - 0xF7
  3832. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 0xF8 - 0xFF
  3833. };
  3834. const unsigned char* itr = begin;
  3835. while (end != itr)
  3836. {
  3837. *reinterpret_cast<unsigned char*>(out) = static_cast<unsigned char>(hex_to_bin[itr[0]] << 4 | hex_to_bin[itr[1]]);
  3838. ++out;
  3839. itr += 2;
  3840. }
  3841. return true;
  3842. }
  3843. inline bool convert_hex_to_bin(const char* begin, const char* end, char* out)
  3844. {
  3845. return convert_hex_to_bin(reinterpret_cast<const unsigned char*>(begin),
  3846. reinterpret_cast<const unsigned char*>(end),
  3847. reinterpret_cast<unsigned char*>(out));
  3848. }
  3849. inline bool convert_hex_to_bin(const std::pair<unsigned char*,unsigned char*>& r, unsigned char* out)
  3850. {
  3851. return convert_hex_to_bin(r.first,r.second,out);
  3852. }
  3853. inline bool convert_hex_to_bin(const std::pair<const unsigned char*,const unsigned char*>& r, unsigned char* out)
  3854. {
  3855. return convert_hex_to_bin(r.first,r.second,out);
  3856. }
  3857. inline bool convert_hex_to_bin(const std::pair<char*,char*>& r, char* out)
  3858. {
  3859. return convert_hex_to_bin(r.first,r.second,out);
  3860. }
  3861. inline bool convert_hex_to_bin(const std::pair<const char*,const char*>& r, char* out)
  3862. {
  3863. return convert_hex_to_bin(r.first,r.second,out);
  3864. }
  3865. inline bool convert_hex_to_bin(const std::string& hex_data, std::string& output)
  3866. {
  3867. if (hex_data.empty() || (1 == (hex_data.size() % 2)))
  3868. return false;
  3869. output.resize(hex_data.size() >> 1);
  3870. return convert_hex_to_bin(hex_data.data(),
  3871. hex_data.data() + hex_data.size(),
  3872. const_cast<char*>(output.data()));
  3873. }
  3874. inline std::size_t convert_bin_to_base64(const unsigned char* begin, const unsigned char* end, unsigned char* out)
  3875. {
  3876. static const unsigned char bin_to_base64 [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  3877. const std::size_t length = std::distance(begin,end);
  3878. std::size_t rounds = length / 3;
  3879. const unsigned char* itr = begin;
  3880. for (std::size_t i = 0; i < rounds; ++i)
  3881. {
  3882. unsigned int block = *(itr++) << 16;
  3883. block |= *(itr++) << 8;
  3884. block |= *(itr++) ;
  3885. *(out++) = bin_to_base64[( block >> 18 ) & 0x3F];
  3886. *(out++) = bin_to_base64[( block >> 12 ) & 0x3F];
  3887. *(out++) = bin_to_base64[( block >> 6 ) & 0x3F];
  3888. *(out++) = bin_to_base64[( block ) & 0x3F];
  3889. }
  3890. if ((rounds = (length % 3)) > 0)
  3891. {
  3892. switch (rounds)
  3893. {
  3894. case 1 : {
  3895. unsigned int block = (unsigned char) (*itr) << 16;
  3896. *(out++) = bin_to_base64[( block >> 18 ) & 0x3F];
  3897. *(out++) = bin_to_base64[( block >> 12 ) & 0x3F];
  3898. *(out++) = '=';
  3899. *(out++) = '=';
  3900. }
  3901. break;
  3902. case 2 : {
  3903. unsigned int block = *(itr++) << 16;
  3904. block |= *(itr++) << 8;
  3905. *(out++) = bin_to_base64[( block >> 18 ) & 0x3F];
  3906. *(out++) = bin_to_base64[( block >> 12 ) & 0x3F];
  3907. *(out++) = bin_to_base64[( block >> 6 ) & 0x3F];
  3908. *(out++) = '=';
  3909. }
  3910. break;
  3911. }
  3912. }
  3913. return static_cast<std::size_t>((length / 3) * 4) + ((length % 3) > 0 ? 4 : 0);
  3914. }
  3915. inline std::size_t convert_bin_to_base64(const char* begin, const char* end, char* out)
  3916. {
  3917. return convert_bin_to_base64(reinterpret_cast<const unsigned char*>(begin),
  3918. reinterpret_cast<const unsigned char*>(end),
  3919. reinterpret_cast<unsigned char*>(out));
  3920. }
  3921. inline void convert_bin_to_base64(const std::string& binary_data, std::string& output)
  3922. {
  3923. output.resize(std::max<std::size_t>(4,binary_data.size() << 1));
  3924. std::size_t resize = convert_bin_to_base64(binary_data.data(),
  3925. binary_data.data() + binary_data.size(),
  3926. const_cast<char*>(output.data()));
  3927. output.resize(resize);
  3928. }
  3929. inline std::size_t convert_base64_to_bin(const unsigned char* begin, const unsigned char* end, unsigned char* out)
  3930. {
  3931. static const unsigned char base64_to_bin[] =
  3932. {
  3933. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x00 - 0x07
  3934. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x08 - 0x0F
  3935. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x10 - 0x17
  3936. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x18 - 0x1F
  3937. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x20 - 0x27
  3938. 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, // 0x28 - 0x2F
  3939. 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 - 0x37
  3940. 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x38 - 0x3F
  3941. 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 - 0x47
  3942. 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 - 0x4F
  3943. 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 - 0x57
  3944. 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x58 - 0x5F
  3945. 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 - 0x67
  3946. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 - 0x6F
  3947. 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 - 0x77
  3948. 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x78 - 0x7F
  3949. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x80 - 0x87
  3950. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x88 - 0x8F
  3951. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x90 - 0x97
  3952. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x98 - 0x9F
  3953. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA0 - 0xA7
  3954. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA8 - 0xAF
  3955. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB0 - 0xB7
  3956. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB8 - 0xBF
  3957. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC0 - 0xC7
  3958. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC8 - 0xCF
  3959. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD0 - 0xD7
  3960. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD8 - 0xDF
  3961. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE0 - 0xE7
  3962. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE8 - 0xEF
  3963. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xF0 - 0xF7
  3964. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 0xF8 - 0xFF
  3965. };
  3966. const unsigned char* end_itr = end;
  3967. if ('=' == *(end - 2))
  3968. end_itr = end - 2;
  3969. else if ('=' == *(end - 1))
  3970. end_itr = end - 1;
  3971. const std::size_t length = std::distance(begin,end_itr);
  3972. const std::size_t rounds = length / 4;
  3973. const unsigned char* itr = begin;
  3974. for (std::size_t i = 0; i < rounds; ++i)
  3975. {
  3976. unsigned int block = base64_to_bin[*(itr++)] << 18;
  3977. block |= base64_to_bin[*(itr++)] << 12;
  3978. block |= base64_to_bin[*(itr++)] << 6;
  3979. block |= base64_to_bin[*(itr++)];
  3980. *(out++) = static_cast<unsigned char>(( block >> 16 ) & 0xFF);
  3981. *(out++) = static_cast<unsigned char>(( block >> 8 ) & 0xFF);
  3982. *(out++) = static_cast<unsigned char>(( block ) & 0xFF);
  3983. }
  3984. const std::size_t remainder = (length % 4);
  3985. if (remainder > 0)
  3986. {
  3987. switch (remainder)
  3988. {
  3989. case 2 : {
  3990. unsigned int block = base64_to_bin[*(itr++)] << 18;
  3991. block |= base64_to_bin[*(itr++)] << 12;
  3992. (*out) = static_cast<unsigned char>(( block >> 16 ) & 0xFF);
  3993. }
  3994. break;
  3995. case 3 : {
  3996. unsigned int block = base64_to_bin[*(itr++)] << 18;
  3997. block |= base64_to_bin[*(itr++)] << 12;
  3998. block |= base64_to_bin[*(itr++)] << 6;
  3999. *(out++) = static_cast<unsigned char>(( block >> 16 ) & 0xFF);
  4000. *(out ) = static_cast<unsigned char>(( block >> 8 ) & 0xFF);
  4001. }
  4002. break;
  4003. }
  4004. }
  4005. return static_cast<std::size_t>((3 * length) / 4);
  4006. }
  4007. inline std::size_t convert_base64_to_bin(const char* begin, const char* end, char* out)
  4008. {
  4009. return convert_base64_to_bin(reinterpret_cast<const unsigned char*>(begin),
  4010. reinterpret_cast<const unsigned char*>(end),
  4011. reinterpret_cast<unsigned char*>(out));
  4012. }
  4013. inline void convert_base64_to_bin(const std::string& binary_data, std::string& output)
  4014. {
  4015. output.resize(binary_data.size());
  4016. std::size_t resize = convert_base64_to_bin(binary_data.data(),
  4017. binary_data.data() + binary_data.size(),
  4018. const_cast<char*>(output.data()));
  4019. output.resize(resize);
  4020. }
  4021. inline void convert_to_printable_chars(unsigned char* begin, unsigned char* end)
  4022. {
  4023. static const unsigned char printable_char_table[] =
  4024. {
  4025. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x00 - 0x07
  4026. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x08 - 0x0F
  4027. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x10 - 0x17
  4028. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x18 - 0x1F
  4029. 0x2E, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, // 0x20 - 0x27
  4030. 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, // 0x28 - 0x2F
  4031. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // 0x30 - 0x37
  4032. 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // 0x38 - 0x3F
  4033. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, // 0x40 - 0x47
  4034. 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, // 0x48 - 0x4F
  4035. 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, // 0x50 - 0x57
  4036. 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, // 0x58 - 0x5F
  4037. 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, // 0x60 - 0x67
  4038. 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, // 0x68 - 0x6F
  4039. 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // 0x70 - 0x77
  4040. 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x2E, // 0x78 - 0x7F
  4041. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x80 - 0x87
  4042. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x88 - 0x8F
  4043. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x90 - 0x97
  4044. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x98 - 0x9F
  4045. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xA0 - 0xA7
  4046. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xA8 - 0xAF
  4047. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xB0 - 0xB7
  4048. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xB8 - 0xBF
  4049. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xC0 - 0xC7
  4050. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xC8 - 0xCF
  4051. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xD0 - 0xD7
  4052. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xD8 - 0xDF
  4053. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xE0 - 0xE7
  4054. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xE8 - 0xEF
  4055. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xF0 - 0xF7
  4056. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E // 0xF8 - 0xFF
  4057. };
  4058. unsigned char* itr = begin;
  4059. while (end != itr)
  4060. {
  4061. (*itr) = printable_char_table[static_cast<unsigned int>((*itr))];
  4062. ++itr;
  4063. }
  4064. }
  4065. inline void convert_to_printable_chars(char* begin, char* end)
  4066. {
  4067. convert_to_printable_chars(reinterpret_cast<unsigned char*>(begin),
  4068. reinterpret_cast<unsigned char*>(end));
  4069. }
  4070. inline void convert_to_printable_chars(std::string& str)
  4071. {
  4072. convert_to_printable_chars(reinterpret_cast<unsigned char*>(const_cast<char*>(str.data())),
  4073. reinterpret_cast<unsigned char*>(const_cast<char*>(str.data() + str.size())));
  4074. }
  4075. inline void convert_to_uppercase(unsigned char* begin, unsigned char* end)
  4076. {
  4077. std::transform(begin,end,begin,::toupper);
  4078. /*
  4079. unsigned char* itr = begin;
  4080. while (end != itr)
  4081. {
  4082. //(*itr) = std::toupper((*itr), std::locale::classic());
  4083. (*itr) = static_cast<unsigned char>(::toupper(static_cast<int>(*itr)));
  4084. ++itr;
  4085. }
  4086. */
  4087. }
  4088. inline void convert_to_uppercase(char* begin, char* end)
  4089. {
  4090. convert_to_uppercase(reinterpret_cast<unsigned char*>(begin),
  4091. reinterpret_cast<unsigned char*>(end));
  4092. }
  4093. inline void convert_to_uppercase(std::string& str)
  4094. {
  4095. convert_to_uppercase(reinterpret_cast<unsigned char*>(const_cast<char*>(str.data())),
  4096. reinterpret_cast<unsigned char*>(const_cast<char*>(str.data() + str.size())));
  4097. }
  4098. inline void convert_to_lowercase(unsigned char* begin, unsigned char* end)
  4099. {
  4100. std::transform(begin,end,begin,::tolower);
  4101. /*
  4102. unsigned char* itr = begin;
  4103. while (end != itr)
  4104. {
  4105. //(*itr) = std::tolower((*itr), std::locale::classic());
  4106. (*itr) = static_cast<unsigned char>(::tolower(static_cast<int>(*itr)));
  4107. ++itr;
  4108. }
  4109. */
  4110. }
  4111. inline void convert_to_lowercase(char* begin, char* end)
  4112. {
  4113. convert_to_lowercase(reinterpret_cast<unsigned char*>(begin),
  4114. reinterpret_cast<unsigned char*>(end));
  4115. }
  4116. inline void convert_to_lowercase(const char* begin, const char* end)
  4117. {
  4118. convert_to_lowercase(const_cast<char*>(begin),const_cast<char*>(end));
  4119. }
  4120. inline void convert_to_lowercase(std::string& str)
  4121. {
  4122. convert_to_lowercase(reinterpret_cast<unsigned char*>(const_cast<char*>(str.data())),
  4123. reinterpret_cast<unsigned char*>(const_cast<char*>(str.data() + str.size())));
  4124. }
  4125. inline std::string as_lowercase(const std::string& str)
  4126. {
  4127. std::string result = str;
  4128. convert_to_lowercase(result);
  4129. return result;
  4130. }
  4131. inline std::string as_uppercase(const std::string& str)
  4132. {
  4133. std::string result = str;
  4134. convert_to_uppercase(result);
  4135. return result;
  4136. }
  4137. inline bool twoway_bitwise_interleave(const unsigned char* begin1, const unsigned char* end1,
  4138. const unsigned char* begin2, const unsigned char* end2,
  4139. unsigned char* out)
  4140. {
  4141. if (std::distance(begin1,end1) != std::distance(begin2,end2))
  4142. {
  4143. return false;
  4144. }
  4145. static const std::size_t interleave_table_size = 256;
  4146. static const unsigned short interleave_table[interleave_table_size] =
  4147. {
  4148. 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, // 0x00 - 0x07
  4149. 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, // 0x08 - 0x0F
  4150. 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, // 0x10 - 0x17
  4151. 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, // 0x18 - 0x1F
  4152. 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, // 0x20 - 0x27
  4153. 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, // 0x28 - 0x2F
  4154. 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, // 0x30 - 0x37
  4155. 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, // 0x38 - 0x3F
  4156. 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, // 0x40 - 0x47
  4157. 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, // 0x48 - 0x4F
  4158. 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, // 0x50 - 0x57
  4159. 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, // 0x58 - 0x5F
  4160. 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, // 0x60 - 0x67
  4161. 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, // 0x68 - 0x6F
  4162. 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, // 0x70 - 0x77
  4163. 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, // 0x78 - 0x7F
  4164. 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, // 0x80 - 0x87
  4165. 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, // 0x88 - 0x8F
  4166. 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, // 0x90 - 0x97
  4167. 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, // 0x98 - 0x9F
  4168. 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, // 0xA0 - 0xA7
  4169. 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, // 0xA8 - 0xAF
  4170. 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, // 0xB0 - 0xB7
  4171. 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, // 0xB8 - 0xBF
  4172. 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, // 0xC0 - 0xC7
  4173. 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, // 0xC8 - 0xCF
  4174. 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, // 0xD0 - 0xD7
  4175. 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, // 0xD8 - 0xDF
  4176. 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, // 0xE0 - 0xE7
  4177. 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, // 0xE8 - 0xEF
  4178. 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, // 0xF0 - 0xF7
  4179. 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 // 0xF8 - 0xFF
  4180. };
  4181. const unsigned char* itr1 = begin1;
  4182. const unsigned char* itr2 = begin2;
  4183. while (end1 != itr1)
  4184. {
  4185. *(reinterpret_cast<unsigned short*>(out)) = (interleave_table[*(itr2++)] << 1);
  4186. *(reinterpret_cast<unsigned short*>(out)) |= interleave_table[*(itr1++)];
  4187. out += 2;
  4188. }
  4189. return true;
  4190. }
  4191. inline bool twoway_bitwise_interleave(const char* begin1, const char* end1,
  4192. const char* begin2, const char* end2,
  4193. char* out)
  4194. {
  4195. return twoway_bitwise_interleave(reinterpret_cast<const unsigned char*>(begin1),
  4196. reinterpret_cast<const unsigned char*>(end1),
  4197. reinterpret_cast<const unsigned char*>(begin2),
  4198. reinterpret_cast<const unsigned char*>(end2),
  4199. reinterpret_cast<unsigned char*>(out));
  4200. }
  4201. inline bool twoway_bitwise_interleave(const std::string& str1,
  4202. const std::string& str2,
  4203. std::string& out)
  4204. {
  4205. if (str1.size() != str2.size())
  4206. {
  4207. return false;
  4208. }
  4209. out.resize(str1.size());
  4210. return twoway_bitwise_interleave(str1.data(),str1.data() + str1.size(),
  4211. str2.data(),str2.data() + str2.size(),
  4212. const_cast<char*>(out.data()));
  4213. }
  4214. template <std::size_t n>
  4215. struct interleave_ary;
  4216. template<> struct interleave_ary<sizeof(unsigned short)> { typedef unsigned short type; };
  4217. template<> struct interleave_ary<sizeof(unsigned int )> { typedef unsigned int type; };
  4218. template<> struct interleave_ary<sizeof(unsigned long long int)> { typedef unsigned long long int type; };
  4219. template <std::size_t n>
  4220. inline void create_nway_interleave_table(typename interleave_ary<n>::type table[256])
  4221. {
  4222. typedef typename interleave_ary<n>::type type;
  4223. const type diff = static_cast<type>(n - 1);
  4224. for (type i = static_cast<type>(0); i < static_cast<type>(256); ++i)
  4225. {
  4226. table[i] = 0x00;
  4227. for (type j = static_cast<type>(0); j < static_cast<type>(8); ++j)
  4228. {
  4229. table[i] |= (i & (1 << j)) << (j * diff);
  4230. }
  4231. }
  4232. }
  4233. namespace bitwise_operation { enum type { eAND, eOR, eXOR }; }
  4234. inline void bitwise_transform(const bitwise_operation::type& operation,
  4235. const unsigned char* begin1, const unsigned char* end1,
  4236. const unsigned char* begin2,
  4237. unsigned char* out)
  4238. {
  4239. const unsigned char* itr1 = begin1;
  4240. const unsigned char* itr2 = begin2;
  4241. switch (operation)
  4242. {
  4243. case bitwise_operation::eAND : while (itr1 != end1) { *(out++) = *(itr1++) & *(itr2++); } return;
  4244. case bitwise_operation::eOR : while (itr1 != end1) { *(out++) = *(itr1++) | *(itr2++); } return;
  4245. case bitwise_operation::eXOR : while (itr1 != end1) { *(out++) = *(itr1++) ^ *(itr2++); } return;
  4246. }
  4247. }
  4248. inline void bitwise_transform(const bitwise_operation::type& operation,
  4249. const char* begin1, const char* end1,
  4250. const char* begin2,
  4251. char* out)
  4252. {
  4253. bitwise_transform(operation,
  4254. reinterpret_cast<const unsigned char*>(begin1),
  4255. reinterpret_cast<const unsigned char*>(end1),
  4256. reinterpret_cast<const unsigned char*>(begin2),
  4257. reinterpret_cast<unsigned char*>(out));
  4258. }
  4259. inline void bitwise_transform(const bitwise_operation::type& operation,
  4260. const std::string& str1,
  4261. const std::string& str2,
  4262. std::string& out)
  4263. {
  4264. if (str1.size() != str2.size()) return;
  4265. out.resize(str1.size());
  4266. bitwise_transform(operation,
  4267. str1.data(),str1.data() + str1.size(),
  4268. str2.data(),
  4269. const_cast<char*>(out.data()));
  4270. }
  4271. inline std::size_t high_bit_count(const unsigned char c)
  4272. {
  4273. static const std::size_t high_bits_in_char[256] =
  4274. {
  4275. 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
  4276. 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  4277. 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  4278. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4279. 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  4280. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4281. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4282. 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  4283. 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  4284. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4285. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4286. 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  4287. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4288. 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  4289. 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  4290. 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
  4291. };
  4292. return high_bits_in_char[c];
  4293. }
  4294. inline std::size_t high_bit_count(const unsigned short& s)
  4295. {
  4296. const unsigned char* ptr = reinterpret_cast<const unsigned char*>(&s);
  4297. return high_bit_count(*(ptr + 0)) + high_bit_count(*(ptr + 1));
  4298. }
  4299. inline std::size_t high_bit_count(const unsigned int& i)
  4300. {
  4301. const unsigned char* ptr = reinterpret_cast<const unsigned char*>(&i);
  4302. return high_bit_count(*(ptr + 0)) + high_bit_count(*(ptr + 1)) +
  4303. high_bit_count(*(ptr + 2)) + high_bit_count(*(ptr + 3));
  4304. }
  4305. inline std::size_t high_bit_count(const long long int& ll)
  4306. {
  4307. const unsigned char* ptr = reinterpret_cast<const unsigned char*>(&ll);
  4308. return high_bit_count(*(ptr + 0)) + high_bit_count(*(ptr + 1)) +
  4309. high_bit_count(*(ptr + 2)) + high_bit_count(*(ptr + 3)) +
  4310. high_bit_count(*(ptr + 4)) + high_bit_count(*(ptr + 5)) +
  4311. high_bit_count(*(ptr + 6)) + high_bit_count(*(ptr + 7));
  4312. }
  4313. inline std::size_t high_bit_count(const unsigned char* begin, const unsigned char* end)
  4314. {
  4315. std::size_t count = 0;
  4316. const unsigned char* itr = begin;
  4317. while (end != itr)
  4318. {
  4319. count += high_bit_count(*itr++);
  4320. }
  4321. return count;
  4322. }
  4323. inline std::size_t high_bit_count(const char* begin, const char* end)
  4324. {
  4325. return high_bit_count(reinterpret_cast<const unsigned char*>(begin),
  4326. reinterpret_cast<const unsigned char*>(end));
  4327. }
  4328. inline std::size_t high_bit_count(const std::string& str)
  4329. {
  4330. return high_bit_count(str.data(),str.data() + str.size());
  4331. }
  4332. inline bool bit_state(const std::size_t& index, const unsigned char* ptr)
  4333. {
  4334. static const unsigned char bit_mask[] =
  4335. {
  4336. 0x01, //00000001
  4337. 0x02, //00000010
  4338. 0x04, //00000100
  4339. 0x08, //00001000
  4340. 0x10, //00010000
  4341. 0x20, //00100000
  4342. 0x40, //01000000
  4343. 0x80 //10000000
  4344. };
  4345. return (0 != (ptr[(index >> 3)] & bit_mask[index & 7]));
  4346. }
  4347. inline void set_bit_high(const std::size_t& index, unsigned char* const ptr)
  4348. {
  4349. static const unsigned char bit_mask[] =
  4350. {
  4351. 0x01, //00000001
  4352. 0x02, //00000010
  4353. 0x04, //00000100
  4354. 0x08, //00001000
  4355. 0x10, //00010000
  4356. 0x20, //00100000
  4357. 0x40, //01000000
  4358. 0x80 //10000000
  4359. };
  4360. ptr[(index >> 3)] |= bit_mask[index & 7];
  4361. }
  4362. inline void set_bit_low(const std::size_t& index, unsigned char* const ptr)
  4363. {
  4364. static const unsigned char bit_mask[] =
  4365. {
  4366. 0xFE, //11111110
  4367. 0xFD, //11111101
  4368. 0xFB, //11111011
  4369. 0xF7, //11110111
  4370. 0xEF, //11101111
  4371. 0xDF, //11011111
  4372. 0xBF, //10111111
  4373. 0x7F //01111111
  4374. };
  4375. ptr[(index >> 3)] &= bit_mask[index & 7];
  4376. }
  4377. inline std::size_t hamming_distance(const unsigned char* begin1, const unsigned char* end1,
  4378. const unsigned char* begin2, const unsigned char* end2)
  4379. {
  4380. if (std::distance(begin1,end1) != std::distance(begin2,end2))
  4381. {
  4382. return std::numeric_limits<std::size_t>::max();
  4383. }
  4384. std::size_t distance = 0;
  4385. const unsigned char* itr1 = begin1;
  4386. const unsigned char* itr2 = begin2;
  4387. while (end1 != itr1)
  4388. {
  4389. distance += high_bit_count(static_cast<unsigned char>(((*itr1++) ^ (*itr2++)) & 0xFF));
  4390. }
  4391. return distance;
  4392. }
  4393. inline std::size_t hamming_distance(const char* begin1, const char* end1,
  4394. const char* begin2, const char* end2)
  4395. {
  4396. return hamming_distance(reinterpret_cast<const unsigned char*>(begin1),
  4397. reinterpret_cast<const unsigned char*>(end1),
  4398. reinterpret_cast<const unsigned char*>(begin2),
  4399. reinterpret_cast<const unsigned char*>(end2));
  4400. }
  4401. inline std::size_t hamming_distance(const std::string& str1, const std::string& str2)
  4402. {
  4403. return hamming_distance(str1.data(), str1.data() + str1.size(),
  4404. str2.data(), str2.data() + str2.size());
  4405. }
  4406. template <typename Iterator>
  4407. inline std::size_t hamming_distance_elementwise(const Iterator begin1, const Iterator end1,
  4408. const Iterator begin2, const Iterator end2)
  4409. {
  4410. if (std::distance(begin1,end1) != std::distance(begin2,end2))
  4411. {
  4412. return std::numeric_limits<std::size_t>::max();
  4413. }
  4414. std::size_t distance = 0;
  4415. Iterator itr1 = begin1;
  4416. Iterator itr2 = begin2;
  4417. while (end1 != itr1)
  4418. {
  4419. if ((*itr1) != (*itr2))
  4420. ++distance;
  4421. }
  4422. return distance;
  4423. }
  4424. inline std::size_t hamming_distance_elementwise(const std::string& str1, const std::string& str2)
  4425. {
  4426. return hamming_distance_elementwise(str1.data(), str1.data() + str1.size(),
  4427. str2.data(), str2.data() + str2.size());
  4428. }
  4429. class token_grid
  4430. {
  4431. public:
  4432. typedef const unsigned char* iterator_t;
  4433. typedef unsigned int index_t;
  4434. typedef std::pair<iterator_t,iterator_t> range_t;
  4435. typedef std::deque<range_t> token_list_t;
  4436. typedef std::pair<index_t,index_t> row_index_range_t;
  4437. typedef std::deque<row_index_range_t> row_index_t;
  4438. typedef std::pair<index_t,index_t> row_range_t;
  4439. typedef std::pair<index_t,index_t> col_range_t;
  4440. private:
  4441. struct store
  4442. {
  4443. store()
  4444. : max_column(0)
  4445. {}
  4446. token_list_t token_list;
  4447. row_index_t row_index;
  4448. std::size_t max_column;
  4449. inline void clear()
  4450. {
  4451. token_list.clear();
  4452. row_index.clear();
  4453. }
  4454. inline range_t operator()(const std::size_t& col, const std::size_t& row) const
  4455. {
  4456. if (row < row_index.size())
  4457. {
  4458. const row_index_range_t& r = row_index[row];
  4459. if (col < (r.second - r.first + 1))
  4460. return *(token_list.begin() + (r.first + col));
  4461. else
  4462. return null_range();
  4463. }
  4464. else
  4465. return null_range();
  4466. }
  4467. inline bool remove_row(const std::size_t& row)
  4468. {
  4469. if (row >= row_index.size()) return false;
  4470. row_index_range_t& r = row_index[row];
  4471. std::size_t number_of_tokens = r.second - r.first + 1;
  4472. token_list_t::iterator remove_begin = token_list.begin() + r.first;
  4473. token_list_t::iterator remove_end = token_list.begin() + r.first + number_of_tokens;
  4474. token_list.erase(remove_begin,remove_end);
  4475. row_index.erase(row_index.begin() + row);
  4476. for (std::size_t i = row; i < row_index.size(); ++i)
  4477. {
  4478. row_index_range_t& r = row_index[i];
  4479. r.first -= static_cast<unsigned int>(number_of_tokens);
  4480. r.second -= static_cast<unsigned int>(number_of_tokens);
  4481. }
  4482. return true;
  4483. }
  4484. inline std::size_t token_count(const row_index_range_t& r) const
  4485. {
  4486. return (r.second - r.first + 1);
  4487. }
  4488. inline std::size_t token_count(const std::size_t& index) const
  4489. {
  4490. return token_count(row_index[index]);
  4491. }
  4492. inline bool remove_row_range(const std::size_t& r0, const std::size_t& r1)
  4493. {
  4494. if (r0 > r1)
  4495. return false;
  4496. else if (r0 >= row_index.size())
  4497. return false;
  4498. else if (r1 >= row_index.size())
  4499. return false;
  4500. std::size_t number_of_tokens = 0;
  4501. for (std::size_t i = r0; i <= r1; ++i)
  4502. {
  4503. row_index_range_t& r = row_index[i];
  4504. number_of_tokens += token_count(r);
  4505. }
  4506. row_index_range_t rr0 = row_index[r0];
  4507. token_list_t::iterator remove_begin = token_list.begin() + rr0.first;
  4508. token_list_t::iterator remove_end = token_list.begin() + rr0.first + number_of_tokens;
  4509. token_list.erase(remove_begin,remove_end);
  4510. row_index.erase(row_index.begin() + r0,row_index.begin() + r0 + (r1 - r0 + 1));
  4511. for (std::size_t i = r0; i < row_index.size(); ++i)
  4512. {
  4513. row_index_range_t& r = row_index[i];
  4514. r.first -= static_cast<unsigned int>(number_of_tokens);
  4515. r.second -= static_cast<unsigned int>(number_of_tokens);
  4516. }
  4517. return true;
  4518. }
  4519. struct remove_column_impl
  4520. {
  4521. std::size_t column;
  4522. std::size_t counter;
  4523. std::size_t remainder;
  4524. std::size_t current_row;
  4525. inline void update(store& idx)
  4526. {
  4527. current_row++;
  4528. while (current_row < idx.row_index.size())
  4529. {
  4530. std::size_t number_of_tokens = idx.token_count(current_row);
  4531. if (number_of_tokens > column)
  4532. break;
  4533. counter += number_of_tokens;
  4534. ++current_row;
  4535. }
  4536. if (current_row < idx.row_index.size())
  4537. {
  4538. counter += column + remainder;
  4539. row_index_range_t& r = idx.row_index[current_row];
  4540. remainder = (r.second - r.first) - column;
  4541. }
  4542. else
  4543. counter = std::numeric_limits<std::size_t>::max();
  4544. }
  4545. inline void process(store& idx)
  4546. {
  4547. token_list_t::iterator itr1 = idx.token_list.begin();
  4548. token_list_t::iterator itr2 = idx.token_list.begin();
  4549. token_list_t::iterator end = idx.token_list.end();
  4550. counter = 0;
  4551. remainder = 0;
  4552. current_row = static_cast<std::size_t>(-1);
  4553. update(idx);
  4554. while (end != itr1)
  4555. {
  4556. while ((end != itr1) && (0 != counter))
  4557. {
  4558. if (itr1 != itr2)
  4559. {
  4560. (*itr2) = (*itr1);
  4561. }
  4562. ++itr1;
  4563. ++itr2;
  4564. --counter;
  4565. }
  4566. if (0 == counter)
  4567. {
  4568. update(idx);
  4569. ++itr1;
  4570. }
  4571. }
  4572. std::size_t remove_count = 0;
  4573. idx.max_column = std::numeric_limits<std::size_t>::min();
  4574. for (std::size_t i = 0; i < idx.row_index.size(); ++i)
  4575. {
  4576. row_index_range_t& r = idx.row_index[i];
  4577. std::size_t token_count = (r.second - r.first + 1);
  4578. r.first -= static_cast<unsigned int>(remove_count);
  4579. if (token_count > column)
  4580. {
  4581. ++remove_count;
  4582. }
  4583. r.second -= static_cast<unsigned int>(remove_count);
  4584. token_count = (r.second - r.first + 1);
  4585. if (token_count > idx.max_column)
  4586. idx.max_column = token_count;
  4587. }
  4588. idx.token_list.resize(idx.token_list.size() - remove_count);
  4589. }
  4590. };
  4591. inline bool remove_column(const std::size_t& column)
  4592. {
  4593. if (column >= max_column) return false;
  4594. remove_column_impl rc;
  4595. rc.column = column;
  4596. rc.process(*this);
  4597. return true;
  4598. }
  4599. inline static range_t null_range()
  4600. {
  4601. static const range_t null_range_ = range_t(reinterpret_cast<const unsigned char*>(0),
  4602. reinterpret_cast<const unsigned char*>(0));
  4603. return null_range_;
  4604. }
  4605. };
  4606. template <typename DelimiterPredicate = multiple_char_delimiter_predicate>
  4607. struct row_processor
  4608. {
  4609. row_processor(store& idx,
  4610. DelimiterPredicate& tp,
  4611. const split_options::type split_mode = split_options::compress_delimiters)
  4612. : idx_(idx),
  4613. row_start_index_(0),
  4614. row_end_index_(0),
  4615. token_predicate_(tp),
  4616. split_mode_(split_mode)
  4617. {
  4618. idx_.max_column = std::numeric_limits<std::size_t>::min();
  4619. }
  4620. inline void operator()(const range_t& range)
  4621. {
  4622. if (0 == std::distance(range.first,range.second))
  4623. return;
  4624. row_start_index_ = static_cast<index_t>(idx_.token_list.size());
  4625. std::size_t token_count = split(token_predicate_,
  4626. range.first,range.second,
  4627. std::back_inserter(idx_.token_list),
  4628. split_mode_);
  4629. row_end_index_ = row_start_index_ + token_count - 1;
  4630. idx_.row_index.push_back(std::make_pair(row_start_index_,row_end_index_));
  4631. if (token_count > idx_.max_column)
  4632. idx_.max_column = token_count;
  4633. }
  4634. row_processor<DelimiterPredicate> operator=(const row_processor<DelimiterPredicate>&);
  4635. store& idx_;
  4636. index_t row_start_index_;
  4637. index_t row_end_index_;
  4638. DelimiterPredicate& token_predicate_;
  4639. split_options::type split_mode_;
  4640. };
  4641. public:
  4642. inline row_range_t range(std::size_t lower_bound,
  4643. std::size_t upper_bound = std::numeric_limits<std::size_t>::max()) const
  4644. {
  4645. if (upper_bound == std::numeric_limits<std::size_t>::max())
  4646. {
  4647. upper_bound = dsv_index_.token_list.size();
  4648. }
  4649. else if (upper_bound > dsv_index_.token_list.size())
  4650. {
  4651. return row_range_t(std::numeric_limits<std::size_t>::max(),std::numeric_limits<std::size_t>::max());
  4652. }
  4653. else if (lower_bound > upper_bound)
  4654. {
  4655. return row_range_t(std::numeric_limits<std::size_t>::max(),std::numeric_limits<std::size_t>::max());
  4656. }
  4657. return row_range_t(lower_bound,upper_bound);
  4658. }
  4659. struct options
  4660. {
  4661. options()
  4662. : row_split_option(split_options::compress_delimiters),
  4663. column_split_option(split_options::compress_delimiters),
  4664. row_delimiters("\n\r"),
  4665. column_delimiters(",|;\t "),
  4666. support_dquotes(false),
  4667. trim_dquotes(false)
  4668. {}
  4669. options(split_options::type sro,
  4670. split_options::type sco,
  4671. const std::string& rd,
  4672. const std::string& cd,
  4673. const bool support_dq = false,
  4674. const bool trim_dq = false)
  4675. : row_split_option(sro),
  4676. column_split_option(sco),
  4677. row_delimiters(rd),
  4678. column_delimiters(cd),
  4679. support_dquotes(support_dq),
  4680. trim_dquotes(trim_dq)
  4681. {}
  4682. inline options& set_column_split_option(const split_options::type& option)
  4683. {
  4684. column_split_option = option;
  4685. return *this;
  4686. }
  4687. inline options& set_row_split_option(const split_options::type& option)
  4688. {
  4689. row_split_option = option;
  4690. return *this;
  4691. }
  4692. inline options& set_column_delimiters(const std::string& delimiters)
  4693. {
  4694. column_delimiters = delimiters;
  4695. return *this;
  4696. }
  4697. inline options& set_row_delimiters(const std::string& delimiters)
  4698. {
  4699. row_delimiters = delimiters;
  4700. return *this;
  4701. }
  4702. split_options::type row_split_option;
  4703. split_options::type column_split_option;
  4704. std::string row_delimiters;
  4705. std::string column_delimiters;
  4706. bool support_dquotes;
  4707. bool trim_dquotes;
  4708. };
  4709. class row_type
  4710. {
  4711. private:
  4712. typedef std::pair<bool,row_type*> row_pair_type;
  4713. public:
  4714. row_type()
  4715. : index_(std::numeric_limits<std::size_t>::max()),
  4716. size_(0)
  4717. {}
  4718. row_type(const std::size_t& index,
  4719. const store& dsv_index)
  4720. : index_(index),
  4721. size_ (dsv_index.token_count(index)),
  4722. begin_(dsv_index.token_list.begin() + dsv_index.row_index[index].first)
  4723. {}
  4724. inline bool is_null(const std::size_t& index) const
  4725. {
  4726. const range_t& range = *(begin_ + index);
  4727. return (0 == std::distance(range.first,range.second));
  4728. }
  4729. template <typename T>
  4730. inline T operator[](const std::size_t& index) const
  4731. {
  4732. const range_t& range = *(begin_ + index);
  4733. return string_to_type_converter<T>(range.first,range.second);
  4734. }
  4735. template <typename T>
  4736. inline T get(const std::size_t& index) const
  4737. {
  4738. return operator[]<T>(index);
  4739. }
  4740. inline col_range_t all_columns() const
  4741. {
  4742. return col_range_t(0,static_cast<index_t>(size()));
  4743. }
  4744. inline range_t range() const
  4745. {
  4746. return range_t((*begin_).first,(*(begin_ + (size_ - 1))).second);
  4747. }
  4748. inline range_t token(const std::size_t& index) const
  4749. {
  4750. return *(begin_ + index);
  4751. }
  4752. inline std::size_t index() const
  4753. {
  4754. return index_;
  4755. }
  4756. inline std::size_t size() const
  4757. {
  4758. return size_;
  4759. }
  4760. inline std::size_t raw_length() const
  4761. {
  4762. std::size_t result = 0;
  4763. token_list_t::const_iterator itr = begin_;
  4764. for (std::size_t i = 0; i < size_; ++i, ++itr)
  4765. {
  4766. const range_t& range = (*itr);
  4767. result += std::distance(range.first,range.second);
  4768. }
  4769. return result;
  4770. }
  4771. inline std::size_t raw_length(const std::size_t& column_index) const
  4772. {
  4773. const range_t& range = *(begin_ + column_index);
  4774. return std::distance(range.first,range.second);
  4775. }
  4776. inline std::string as_string() const
  4777. {
  4778. std::string result;
  4779. result.reserve(std::distance(begin_->first,(begin_ + (size_ - 1))->second));
  4780. token_list_t::const_iterator itr = begin_;
  4781. for (std::size_t i = 0; i < size_; ++i, ++itr)
  4782. {
  4783. const range_t& range = (*itr);
  4784. result.append(range.first,range.second);
  4785. }
  4786. return result;
  4787. }
  4788. inline void as_string(std::string& out) const
  4789. {
  4790. out = as_string();
  4791. }
  4792. template <typename T0, typename T1, typename T2, typename T3,
  4793. typename T4, typename T5, typename T6, typename T7,
  4794. typename T8, typename T9>
  4795. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4796. const std::size_t& col2, const std::size_t& col3,
  4797. const std::size_t& col4, const std::size_t& col5,
  4798. const std::size_t& col6, const std::size_t& col7,
  4799. const std::size_t& col8, const std::size_t& col9,
  4800. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  4801. T6& t6, T7& t7, T8& t8, T9& t9) const
  4802. {
  4803. if (!process(*(begin_ + col0),t0)) return false;
  4804. if (!process(*(begin_ + col1),t1)) return false;
  4805. if (!process(*(begin_ + col2),t2)) return false;
  4806. if (!process(*(begin_ + col3),t3)) return false;
  4807. if (!process(*(begin_ + col4),t4)) return false;
  4808. if (!process(*(begin_ + col5),t5)) return false;
  4809. if (!process(*(begin_ + col6),t6)) return false;
  4810. if (!process(*(begin_ + col7),t7)) return false;
  4811. if (!process(*(begin_ + col8),t8)) return false;
  4812. if (!process(*(begin_ + col9),t9)) return false;
  4813. return true;
  4814. }
  4815. template <typename T0, typename T1, typename T2, typename T3,
  4816. typename T4, typename T5, typename T6, typename T7,
  4817. typename T8>
  4818. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4819. const std::size_t& col2, const std::size_t& col3,
  4820. const std::size_t& col4, const std::size_t& col5,
  4821. const std::size_t& col6, const std::size_t& col7,
  4822. const std::size_t& col8,
  4823. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  4824. T6& t6, T7& t7, T8& t8) const
  4825. {
  4826. if (!process(*(begin_ + col0),t0)) return false;
  4827. if (!process(*(begin_ + col1),t1)) return false;
  4828. if (!process(*(begin_ + col2),t2)) return false;
  4829. if (!process(*(begin_ + col3),t3)) return false;
  4830. if (!process(*(begin_ + col4),t4)) return false;
  4831. if (!process(*(begin_ + col5),t5)) return false;
  4832. if (!process(*(begin_ + col6),t6)) return false;
  4833. if (!process(*(begin_ + col7),t7)) return false;
  4834. if (!process(*(begin_ + col8),t8)) return false;
  4835. return true;
  4836. }
  4837. template <typename T0, typename T1, typename T2, typename T3,
  4838. typename T4, typename T5, typename T6, typename T7>
  4839. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4840. const std::size_t& col2, const std::size_t& col3,
  4841. const std::size_t& col4, const std::size_t& col5,
  4842. const std::size_t& col6, const std::size_t& col7,
  4843. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  4844. T6& t6, T7& t7) const
  4845. {
  4846. if (!process(*(begin_ + col0),t0)) return false;
  4847. if (!process(*(begin_ + col1),t1)) return false;
  4848. if (!process(*(begin_ + col2),t2)) return false;
  4849. if (!process(*(begin_ + col3),t3)) return false;
  4850. if (!process(*(begin_ + col4),t4)) return false;
  4851. if (!process(*(begin_ + col5),t5)) return false;
  4852. if (!process(*(begin_ + col6),t6)) return false;
  4853. if (!process(*(begin_ + col7),t7)) return false;
  4854. return true;
  4855. }
  4856. template <typename T0, typename T1, typename T2, typename T3,
  4857. typename T4, typename T5, typename T6>
  4858. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4859. const std::size_t& col2, const std::size_t& col3,
  4860. const std::size_t& col4, const std::size_t& col5,
  4861. const std::size_t& col6,
  4862. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  4863. T6& t6) const
  4864. {
  4865. if (!process(*(begin_ + col0),t0)) return false;
  4866. if (!process(*(begin_ + col1),t1)) return false;
  4867. if (!process(*(begin_ + col2),t2)) return false;
  4868. if (!process(*(begin_ + col3),t3)) return false;
  4869. if (!process(*(begin_ + col4),t4)) return false;
  4870. if (!process(*(begin_ + col5),t5)) return false;
  4871. if (!process(*(begin_ + col6),t6)) return false;
  4872. return true;
  4873. }
  4874. template <typename T0, typename T1, typename T2, typename T3,
  4875. typename T4, typename T5>
  4876. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4877. const std::size_t& col2, const std::size_t& col3,
  4878. const std::size_t& col4, const std::size_t& col5,
  4879. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const
  4880. {
  4881. if (!process(*(begin_ + col0),t0)) return false;
  4882. if (!process(*(begin_ + col1),t1)) return false;
  4883. if (!process(*(begin_ + col2),t2)) return false;
  4884. if (!process(*(begin_ + col3),t3)) return false;
  4885. if (!process(*(begin_ + col4),t4)) return false;
  4886. if (!process(*(begin_ + col5),t5)) return false;
  4887. return true;
  4888. }
  4889. template <typename T0, typename T1, typename T2, typename T3, typename T4>
  4890. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4891. const std::size_t& col2, const std::size_t& col3,
  4892. const std::size_t& col4,
  4893. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4) const
  4894. {
  4895. if (!process(*(begin_ + col0),t0)) return false;
  4896. if (!process(*(begin_ + col1),t1)) return false;
  4897. if (!process(*(begin_ + col2),t2)) return false;
  4898. if (!process(*(begin_ + col3),t3)) return false;
  4899. if (!process(*(begin_ + col4),t4)) return false;
  4900. return true;
  4901. }
  4902. template <typename T0, typename T1, typename T2, typename T3>
  4903. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4904. const std::size_t& col2, const std::size_t& col3,
  4905. T0& t0, T1& t1, T2& t2, T3& t3) const
  4906. {
  4907. if (!process(*(begin_ + col0),t0)) return false;
  4908. if (!process(*(begin_ + col1),t1)) return false;
  4909. if (!process(*(begin_ + col2),t2)) return false;
  4910. if (!process(*(begin_ + col3),t3)) return false;
  4911. return true;
  4912. }
  4913. template <typename T0, typename T1, typename T2>
  4914. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4915. const std::size_t& col2,
  4916. T0& t0, T1& t1, T2& t2) const
  4917. {
  4918. if (!process(*(begin_ + col0),t0)) return false;
  4919. if (!process(*(begin_ + col1),t1)) return false;
  4920. if (!process(*(begin_ + col2),t2)) return false;
  4921. return true;
  4922. }
  4923. template <typename T0, typename T1>
  4924. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4925. T0& t0, T1& t1) const
  4926. {
  4927. if (!process(*(begin_ + col0),t0)) return false;
  4928. if (!process(*(begin_ + col1),t1)) return false;
  4929. return true;
  4930. }
  4931. template <typename T>
  4932. inline bool parse_with_index(const std::size_t& col, T& t) const
  4933. {
  4934. return process(*(begin_ + col),t);
  4935. }
  4936. template <typename T0, typename T1, typename T2, typename T3,
  4937. typename T4, typename T5, typename T6, typename T7,
  4938. typename T8, typename T9 >
  4939. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  4940. T4& t4, T5& t5, T6& t6, T7& t7,
  4941. T8& t8, T9& t9) const
  4942. {
  4943. if (!process(*(begin_ + 0),t0)) return false;
  4944. if (!process(*(begin_ + 1),t1)) return false;
  4945. if (!process(*(begin_ + 2),t2)) return false;
  4946. if (!process(*(begin_ + 3),t3)) return false;
  4947. if (!process(*(begin_ + 4),t4)) return false;
  4948. if (!process(*(begin_ + 5),t5)) return false;
  4949. if (!process(*(begin_ + 6),t6)) return false;
  4950. if (!process(*(begin_ + 7),t7)) return false;
  4951. if (!process(*(begin_ + 8),t8)) return false;
  4952. if (!process(*(begin_ + 9),t9)) return false;
  4953. return true;
  4954. }
  4955. template <typename T0, typename T1, typename T2, typename T3,
  4956. typename T4, typename T5, typename T6, typename T7,
  4957. typename T8>
  4958. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  4959. T4& t4, T5& t5, T6& t6, T7& t7,
  4960. T8& t8) const
  4961. {
  4962. if (!process(*(begin_ + 0),t0)) return false;
  4963. if (!process(*(begin_ + 1),t1)) return false;
  4964. if (!process(*(begin_ + 2),t2)) return false;
  4965. if (!process(*(begin_ + 3),t3)) return false;
  4966. if (!process(*(begin_ + 4),t4)) return false;
  4967. if (!process(*(begin_ + 5),t5)) return false;
  4968. if (!process(*(begin_ + 6),t6)) return false;
  4969. if (!process(*(begin_ + 7),t7)) return false;
  4970. if (!process(*(begin_ + 8),t8)) return false;
  4971. return true;
  4972. }
  4973. template <typename T0, typename T1, typename T2, typename T3,
  4974. typename T4, typename T5, typename T6, typename T7>
  4975. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  4976. T4& t4, T5& t5, T6& t6, T7& t7) const
  4977. {
  4978. if (!process(*(begin_ + 0),t0)) return false;
  4979. if (!process(*(begin_ + 1),t1)) return false;
  4980. if (!process(*(begin_ + 2),t2)) return false;
  4981. if (!process(*(begin_ + 3),t3)) return false;
  4982. if (!process(*(begin_ + 4),t4)) return false;
  4983. if (!process(*(begin_ + 5),t5)) return false;
  4984. if (!process(*(begin_ + 6),t6)) return false;
  4985. if (!process(*(begin_ + 7),t7)) return false;
  4986. return true;
  4987. }
  4988. template <typename T0, typename T1, typename T2, typename T3,
  4989. typename T4, typename T5, typename T6>
  4990. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  4991. T4& t4, T5& t5, T6& t6) const
  4992. {
  4993. if (!process(*(begin_ + 0),t0)) return false;
  4994. if (!process(*(begin_ + 1),t1)) return false;
  4995. if (!process(*(begin_ + 2),t2)) return false;
  4996. if (!process(*(begin_ + 3),t3)) return false;
  4997. if (!process(*(begin_ + 4),t4)) return false;
  4998. if (!process(*(begin_ + 5),t5)) return false;
  4999. if (!process(*(begin_ + 6),t6)) return false;
  5000. return true;
  5001. }
  5002. template <typename T0, typename T1, typename T2, typename T3,
  5003. typename T4, typename T5>
  5004. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  5005. T4& t4, T5& t5) const
  5006. {
  5007. if (!process(*(begin_ + 0),t0)) return false;
  5008. if (!process(*(begin_ + 1),t1)) return false;
  5009. if (!process(*(begin_ + 2),t2)) return false;
  5010. if (!process(*(begin_ + 3),t3)) return false;
  5011. if (!process(*(begin_ + 4),t4)) return false;
  5012. if (!process(*(begin_ + 5),t5)) return false;
  5013. return true;
  5014. }
  5015. template <typename T0, typename T1,
  5016. typename T2, typename T3,typename T4>
  5017. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3, T4& t4) const
  5018. {
  5019. if (!process(*(begin_ + 0),t0)) return false;
  5020. if (!process(*(begin_ + 1),t1)) return false;
  5021. if (!process(*(begin_ + 2),t2)) return false;
  5022. if (!process(*(begin_ + 3),t3)) return false;
  5023. if (!process(*(begin_ + 4),t4)) return false;
  5024. return true;
  5025. }
  5026. template <typename T0, typename T1,
  5027. typename T2, typename T3>
  5028. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3) const
  5029. {
  5030. if (!process(*(begin_ + 0),t0)) return false;
  5031. if (!process(*(begin_ + 1),t1)) return false;
  5032. if (!process(*(begin_ + 2),t2)) return false;
  5033. if (!process(*(begin_ + 3),t3)) return false;
  5034. return true;
  5035. }
  5036. template <typename T0, typename T1, typename T2>
  5037. inline bool parse(T0& t0, T1& t1, T2& t2) const
  5038. {
  5039. if (!process(*(begin_ + 0),t0)) return false;
  5040. if (!process(*(begin_ + 1),t1)) return false;
  5041. if (!process(*(begin_ + 2),t2)) return false;
  5042. return true;
  5043. }
  5044. template <typename T0, typename T1>
  5045. inline bool parse(T0& t0, T1& t1) const
  5046. {
  5047. if (!process(*(begin_ + 0),t0)) return false;
  5048. if (!process(*(begin_ + 1),t1)) return false;
  5049. return true;
  5050. }
  5051. template <typename T0>
  5052. inline bool parse(T0& t) const
  5053. {
  5054. return process(*begin_,t);
  5055. }
  5056. template <typename T, typename OutputIterator>
  5057. inline void parse(OutputIterator out) const
  5058. {
  5059. token_list_t::const_iterator itr = begin_;
  5060. const token_list_t::const_iterator end = begin_ + size_;
  5061. while (end != itr)
  5062. {
  5063. const range_t& range = (*itr);
  5064. *(out++) = string_to_type_converter<T>(range.first,range.second);
  5065. ++itr;
  5066. }
  5067. }
  5068. bool validate_column_range(const col_range_t& range) const
  5069. {
  5070. if ((range.first > size()) || (range.second > size()))
  5071. return false;
  5072. else if (range.first > range.second)
  5073. return false;
  5074. else
  5075. return true;
  5076. }
  5077. col_range_t range(const std::size_t& lower_bound,
  5078. const std::size_t& upper_bound = std::numeric_limits<std::size_t>::max()) const
  5079. {
  5080. if (std::numeric_limits<std::size_t>::max() != upper_bound)
  5081. return col_range_t(lower_bound,upper_bound);
  5082. else
  5083. return col_range_t(lower_bound,static_cast<index_t>(size()));
  5084. }
  5085. template <typename T,
  5086. typename Allocator,
  5087. template <typename,typename> class Sequence>
  5088. inline bool parse(const col_range_t& range,
  5089. Sequence<T,Allocator>& sequence) const
  5090. {
  5091. if (!validate_column_range(range))
  5092. return false;
  5093. token_list_t::const_iterator itr = (begin_ + range.first);
  5094. token_list_t::const_iterator end = (begin_ + range.second);
  5095. T t;
  5096. while (end != itr)
  5097. {
  5098. const range_t& range = (*itr);
  5099. if (string_to_type_converter(range.first,range.second,t))
  5100. sequence.push_back(t);
  5101. else
  5102. return false;
  5103. ++itr;
  5104. }
  5105. return true;
  5106. }
  5107. template <typename T,
  5108. typename Comparator,
  5109. typename Allocator>
  5110. inline bool parse(const col_range_t& range,
  5111. std::set<T,Comparator,Allocator>& set) const
  5112. {
  5113. if (!validate_column_range(range))
  5114. return false;
  5115. token_list_t::const_iterator itr = (begin_ + range.first);
  5116. token_list_t::const_iterator end = (begin_ + range.second);
  5117. T t;
  5118. while (end != itr)
  5119. {
  5120. const range_t& range = (*itr);
  5121. if (string_to_type_converter(range.first,range.second,t))
  5122. set.insert(t);
  5123. else
  5124. return false;
  5125. ++itr;
  5126. }
  5127. return true;
  5128. }
  5129. template <typename T,
  5130. typename Comparator,
  5131. typename Allocator>
  5132. inline bool parse(const col_range_t& range,
  5133. std::multiset<T,Comparator,Allocator>& multiset) const
  5134. {
  5135. if (!validate_column_range(range))
  5136. return false;
  5137. token_list_t::const_iterator itr = (begin_ + range.first);
  5138. token_list_t::const_iterator end = (begin_ + range.second);
  5139. T t;
  5140. while (end != itr)
  5141. {
  5142. const range_t& range = (*itr);
  5143. if (string_to_type_converter(range.first,range.second,t))
  5144. multiset.insert(t);
  5145. else
  5146. return false;
  5147. ++itr;
  5148. }
  5149. return true;
  5150. }
  5151. template <typename T, typename Container>
  5152. inline bool parse(const col_range_t& range,
  5153. std::queue<T,Container>& queue) const
  5154. {
  5155. if (!validate_column_range(range))
  5156. return false;
  5157. token_list_t::const_iterator itr = (begin_ + range.first);
  5158. token_list_t::const_iterator end = (begin_ + range.second);
  5159. T t;
  5160. while (end != itr)
  5161. {
  5162. const range_t& range = (*itr);
  5163. if (string_to_type_converter(range.first,range.second,t))
  5164. queue.push(t);
  5165. else
  5166. return false;
  5167. ++itr;
  5168. }
  5169. return true;
  5170. }
  5171. template <typename T, typename Container>
  5172. inline bool parse(const col_range_t& range,
  5173. std::stack<T,Container>& stack) const
  5174. {
  5175. if (!validate_column_range(range))
  5176. return false;
  5177. token_list_t::const_iterator itr = (begin_ + range.first);
  5178. token_list_t::const_iterator end = (begin_ + range.second);
  5179. T t;
  5180. while (end != itr)
  5181. {
  5182. const range_t& range = (*itr);
  5183. if (string_to_type_converter(range.first,range.second,t))
  5184. stack.push(t);
  5185. else
  5186. return false;
  5187. ++itr;
  5188. }
  5189. return true;
  5190. }
  5191. template <typename T,
  5192. typename Container,
  5193. typename Comparator>
  5194. inline bool parse(const col_range_t& range,
  5195. std::priority_queue<T,Container,Comparator>& priority_queue) const
  5196. {
  5197. if (!validate_column_range(range))
  5198. return false;
  5199. token_list_t::const_iterator itr = (begin_ + range.first);
  5200. token_list_t::const_iterator end = (begin_ + range.second);
  5201. T t;
  5202. while (end != itr)
  5203. {
  5204. const range_t& range = (*itr);
  5205. if (string_to_type_converter(range.first,range.second,t))
  5206. priority_queue.push(t);
  5207. else
  5208. return false;
  5209. ++itr;
  5210. }
  5211. return true;
  5212. }
  5213. template <typename T,
  5214. typename Allocator,
  5215. template <typename,typename> class Sequence>
  5216. inline bool parse(Sequence<T,Allocator>& sequence) const
  5217. {
  5218. return parse(range(0),sequence);
  5219. }
  5220. template <typename T,
  5221. typename Comparator,
  5222. typename Allocator>
  5223. inline bool parse(std::set<T,Comparator,Allocator>& set) const
  5224. {
  5225. return parse(range(0),set);
  5226. }
  5227. template <typename T,
  5228. typename Comparator,
  5229. typename Allocator>
  5230. inline bool parse(std::multiset<T,Comparator,Allocator>& multiset) const
  5231. {
  5232. return parse(range(0),multiset);
  5233. }
  5234. template <typename T, typename Container>
  5235. inline bool parse(std::queue<T,Container>& queue) const
  5236. {
  5237. return parse(range(0),queue);
  5238. }
  5239. template <typename T, typename Container>
  5240. inline bool parse(std::stack<T,Container>& stack) const
  5241. {
  5242. return parse(range(0),stack);
  5243. }
  5244. template <typename T,
  5245. typename Container,
  5246. typename Comparator>
  5247. inline bool parse(std::priority_queue<T,Container,Comparator>& priority_queue) const
  5248. {
  5249. return parse(range(0),priority_queue);
  5250. }
  5251. template <typename T,
  5252. typename Allocator,
  5253. template <typename,typename> class Sequence>
  5254. inline std::size_t parse_n(const std::size_t& n, Sequence<T,Allocator>& sequence) const
  5255. {
  5256. if (0 == n) return 0;
  5257. T t;
  5258. std::size_t count = 0;
  5259. token_list_t::const_iterator itr = begin_;
  5260. const token_list_t::const_iterator end = begin_ + size_;
  5261. while (end != itr)
  5262. {
  5263. const range_t& range = (*itr);
  5264. if (!string_to_type_converter(range.first,range.second,t))
  5265. return false;
  5266. else
  5267. sequence.push_back(t);
  5268. if (n == (++count))
  5269. break;
  5270. ++itr;
  5271. }
  5272. return count;
  5273. }
  5274. template <typename T, typename OutputIterator>
  5275. inline void parse_checked(OutputIterator out) const
  5276. {
  5277. T value;
  5278. token_list_t::const_iterator itr = begin_;
  5279. const token_list_t::const_iterator end = begin_ + size_;
  5280. while (end != itr)
  5281. {
  5282. const range_t& range = (*itr);
  5283. if (string_to_type_converter(range.first,range.second,value))
  5284. {
  5285. *(out++) = value;
  5286. }
  5287. ++itr;
  5288. }
  5289. }
  5290. template <typename T,
  5291. typename Allocator,
  5292. template <typename,typename> class Sequence>
  5293. inline void parse_checked(Sequence<T,Allocator>& sequence) const
  5294. {
  5295. parse_checked<T>(std::back_inserter(sequence));
  5296. }
  5297. template <typename T,
  5298. typename Comparator,
  5299. typename Allocator>
  5300. inline void parse_checked(std::set<T,Comparator,Allocator>& set) const
  5301. {
  5302. parse_checked<T>(std::inserter(set,set.end()));
  5303. }
  5304. template <typename T,
  5305. typename Comparator,
  5306. typename Allocator>
  5307. inline void parse_checked(std::multiset<T,Comparator,Allocator>& multiset) const
  5308. {
  5309. parse_checked<T>(std::inserter(multiset,multiset.end()));
  5310. }
  5311. template <typename T, typename Container>
  5312. inline void parse_checked(std::queue<T,Container>& queue) const
  5313. {
  5314. parse_checked<T>(push_inserter(queue));
  5315. }
  5316. template <typename T, typename Container>
  5317. inline void parse_checked(std::stack<T,Container>& stack) const
  5318. {
  5319. parse_checked<T>(push_inserter(stack));
  5320. }
  5321. template <typename T,
  5322. typename Container,
  5323. typename Comparator>
  5324. inline void parse_checked(std::priority_queue<T,Container,Comparator>& priority_queue) const
  5325. {
  5326. parse_checked<T>(push_inserter(priority_queue));
  5327. }
  5328. template <typename Function>
  5329. inline std::size_t for_each_column(const col_range_t& range, Function f) const
  5330. {
  5331. if (!validate_column_range(range))
  5332. return false;
  5333. token_list_t::const_iterator itr = begin_ + range.first;
  5334. token_list_t::const_iterator end = begin_ + range.second;
  5335. std::size_t col_count = 0;
  5336. while (end != itr)
  5337. {
  5338. const range_t& range = (*itr);
  5339. f(range);
  5340. ++itr;
  5341. ++col_count;
  5342. }
  5343. return col_count;
  5344. }
  5345. template <typename Function>
  5346. inline std::size_t for_each_column(Function f) const
  5347. {
  5348. return for_each_column(all_columns(),f);
  5349. }
  5350. private:
  5351. template <typename T>
  5352. inline bool process(const range_t& range, T& t) const
  5353. {
  5354. return string_to_type_converter(range.first,range.second,t);
  5355. }
  5356. private:
  5357. std::size_t index_;
  5358. std::size_t size_;
  5359. token_list_t::const_iterator begin_;
  5360. };
  5361. token_grid()
  5362. : file_name_(""),
  5363. buffer_(0),
  5364. buffer_size_(0),
  5365. min_column_count_(0),
  5366. max_column_count_(0),
  5367. load_from_file_(false),
  5368. state_(false)
  5369. {}
  5370. token_grid(const std::string& file_name,
  5371. const token_grid::options& options)
  5372. : file_name_(file_name),
  5373. buffer_(0),
  5374. buffer_size_(0),
  5375. min_column_count_(0),
  5376. max_column_count_(0),
  5377. options_(options),
  5378. load_from_file_(true),
  5379. state_(load())
  5380. {}
  5381. token_grid(const unsigned char* input_buffer,
  5382. const std::size_t& input_buffer_size,
  5383. const token_grid::options& options)
  5384. : file_name_(""),
  5385. buffer_(const_cast<unsigned char*>(input_buffer)),
  5386. buffer_size_(input_buffer_size),
  5387. min_column_count_(0),
  5388. max_column_count_(0),
  5389. options_(options),
  5390. load_from_file_(false),
  5391. state_(load())
  5392. {}
  5393. token_grid(const char* input_buffer,
  5394. const std::size_t& input_buffer_size,
  5395. const token_grid::options& options)
  5396. : file_name_(""),
  5397. buffer_(reinterpret_cast<unsigned char*>(const_cast<char*>(input_buffer))),
  5398. buffer_size_(input_buffer_size),
  5399. min_column_count_(0),
  5400. max_column_count_(0),
  5401. options_(options),
  5402. load_from_file_(false),
  5403. state_(load())
  5404. {}
  5405. token_grid(const std::string& input_buffer,
  5406. const std::size_t& input_buffer_size,
  5407. const token_grid::options& options)
  5408. : file_name_(""),
  5409. buffer_(reinterpret_cast<unsigned char*>(const_cast<char*>(input_buffer.data()))),
  5410. buffer_size_(input_buffer_size),
  5411. min_column_count_(0),
  5412. max_column_count_(0),
  5413. options_(options),
  5414. load_from_file_(false),
  5415. state_(load())
  5416. {}
  5417. token_grid(const std::string& file_name,
  5418. const std::string& column_delimiters = ",|;\t",
  5419. const std::string& row_delimiters = "\n\r")
  5420. : file_name_(file_name),
  5421. buffer_(0),
  5422. buffer_size_(0),
  5423. min_column_count_(0),
  5424. max_column_count_(0),
  5425. options_(split_options::compress_delimiters,
  5426. split_options::compress_delimiters,
  5427. row_delimiters,
  5428. column_delimiters),
  5429. load_from_file_(true),
  5430. state_(load())
  5431. {}
  5432. token_grid(const unsigned char* input_buffer,
  5433. const std::size_t& input_buffer_size,
  5434. const std::string& column_delimiters = ",|;\t",
  5435. const std::string& row_delimiters = "\n\r")
  5436. : file_name_(""),
  5437. buffer_(const_cast<unsigned char*>(input_buffer)),
  5438. buffer_size_(input_buffer_size),
  5439. min_column_count_(0),
  5440. max_column_count_(0),
  5441. options_(split_options::compress_delimiters,
  5442. split_options::compress_delimiters,
  5443. row_delimiters,
  5444. column_delimiters),
  5445. load_from_file_(false),
  5446. state_(load())
  5447. {}
  5448. token_grid(const char* input_buffer,
  5449. const std::size_t& input_buffer_size,
  5450. const std::string& column_delimiters = ",|;\t",
  5451. const std::string& row_delimiters = "\n\r")
  5452. : file_name_(""),
  5453. buffer_(reinterpret_cast<unsigned char*>(const_cast<char*>(input_buffer))),
  5454. buffer_size_(input_buffer_size),
  5455. min_column_count_(0),
  5456. max_column_count_(0),
  5457. options_(split_options::compress_delimiters,
  5458. split_options::compress_delimiters,
  5459. row_delimiters,
  5460. column_delimiters),
  5461. load_from_file_(false),
  5462. state_(load())
  5463. {}
  5464. token_grid(const std::string& input_buffer,
  5465. const std::size_t& input_buffer_size,
  5466. const std::string& column_delimiters = ",;|\t ",
  5467. const std::string& row_delimiters = "\n\r")
  5468. : file_name_(""),
  5469. buffer_(reinterpret_cast<unsigned char*>(const_cast<char*>(input_buffer.data()))),
  5470. buffer_size_(input_buffer_size),
  5471. min_column_count_(0),
  5472. max_column_count_(0),
  5473. options_(split_options::compress_delimiters,
  5474. split_options::compress_delimiters,
  5475. row_delimiters,
  5476. column_delimiters),
  5477. load_from_file_(false),
  5478. state_(load())
  5479. {}
  5480. ~token_grid()
  5481. {
  5482. if ((load_from_file_) && (0 != buffer_))
  5483. {
  5484. delete [] buffer_;
  5485. buffer_ = 0;
  5486. }
  5487. }
  5488. inline bool operator!() const
  5489. {
  5490. return !state_;
  5491. }
  5492. inline std::string source_file() const
  5493. {
  5494. return file_name_;
  5495. }
  5496. inline std::size_t row_count() const
  5497. {
  5498. return dsv_index_.row_index.size();
  5499. }
  5500. inline std::size_t min_column_count() const
  5501. {
  5502. return min_column_count_;
  5503. }
  5504. inline std::size_t max_column_count() const
  5505. {
  5506. return max_column_count_;
  5507. }
  5508. inline range_t token(const unsigned int& row, const std::size_t& col) const
  5509. {
  5510. return dsv_index_(col,row);
  5511. }
  5512. template <typename T>
  5513. inline T get(const unsigned int& row, const std::size_t& col)
  5514. {
  5515. range_t r = token(row,col);
  5516. return string_to_type_converter<T>(r.first,r.second);
  5517. }
  5518. inline row_type row(const unsigned int& row_index) const
  5519. {
  5520. return row_type(row_index,dsv_index_);
  5521. }
  5522. inline row_range_t all_rows() const
  5523. {
  5524. return row_range_t(0,static_cast<index_t>(dsv_index_.row_index.size()));
  5525. }
  5526. template <typename OutputIterator>
  5527. inline bool extract_column_checked(const row_range_t& row_range,
  5528. const std::size_t& index,
  5529. OutputIterator out) const
  5530. {
  5531. if (index > max_column_count_)
  5532. return false;
  5533. else if (row_range_invalid(row_range))
  5534. return false;
  5535. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5536. {
  5537. const row_index_range_t& row = dsv_index_.row_index[i];
  5538. if (index < dsv_index_.token_count(row))
  5539. {
  5540. dsv_index_.token_list.begin() + (row.first + index);
  5541. process_token_checked(*(dsv_index_.token_list.begin() + (row.first + index)),out);
  5542. }
  5543. }
  5544. return true;
  5545. }
  5546. template <typename OutputIterator>
  5547. inline bool extract_column_checked(const std::size_t& index,
  5548. OutputIterator out) const
  5549. {
  5550. return extract_column_checked(all_rows(),index,out);
  5551. }
  5552. template <typename T,
  5553. typename Allocator,
  5554. template <typename,typename> class Sequence>
  5555. inline void extract_column_checked(const std::size_t& index,
  5556. Sequence<T,Allocator>& sequence) const
  5557. {
  5558. extract_column_checked(index,back_inserter_with_valuetype(sequence));
  5559. }
  5560. template <typename T,
  5561. typename Comparator,
  5562. typename Allocator>
  5563. inline void extract_column_checked(const std::size_t& index,
  5564. std::set<T,Comparator,Allocator>& set) const
  5565. {
  5566. extract_column_checked(index,inserter_with_valuetype(set));
  5567. }
  5568. template <typename T,
  5569. typename Comparator,
  5570. typename Allocator>
  5571. inline void extract_column_checked(const std::size_t& index,
  5572. std::multiset<T,Comparator,Allocator>& multiset) const
  5573. {
  5574. extract_column_checked(index,inserter_with_valuetype(multiset));
  5575. }
  5576. template <typename OutputIterator>
  5577. inline bool extract_column(const row_range_t& row_range,
  5578. const std::size_t& index,
  5579. OutputIterator out) const
  5580. {
  5581. if (index > max_column_count_)
  5582. return false;
  5583. else if (row_range_invalid(row_range))
  5584. return false;
  5585. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5586. {
  5587. const row_index_range_t& row = dsv_index_.row_index[i];
  5588. if (index < dsv_index_.token_count(row))
  5589. {
  5590. process_token(*(dsv_index_.token_list.begin() + (row.first + index)),out);
  5591. }
  5592. }
  5593. return true;
  5594. }
  5595. template <typename OutputIterator>
  5596. inline bool extract_column(const std::size_t& index,
  5597. OutputIterator out) const
  5598. {
  5599. return extract_column(all_rows(),index,out);
  5600. }
  5601. template <typename OutputIterator0, typename OutputIterator1>
  5602. inline bool extract_column(const row_range_t& row_range,
  5603. const std::size_t& index0,
  5604. const std::size_t& index1,
  5605. OutputIterator0 out0,
  5606. OutputIterator1 out1) const
  5607. {
  5608. if ((index0 > max_column_count_) ||
  5609. (index1 > max_column_count_))
  5610. return false;
  5611. else if (row_range_invalid(row_range))
  5612. return false;
  5613. std::size_t max_index = std::max(index0,index1);
  5614. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5615. {
  5616. const row_index_range_t& row = dsv_index_.row_index[i];
  5617. if (max_index < dsv_index_.token_count(row))
  5618. {
  5619. process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0);
  5620. process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1);
  5621. }
  5622. }
  5623. return true;
  5624. }
  5625. template <typename OutputIterator0, typename OutputIterator1, typename OutputIterator2>
  5626. inline bool extract_column(const row_range_t& row_range,
  5627. const std::size_t& index0,
  5628. const std::size_t& index1,
  5629. const std::size_t& index2,
  5630. OutputIterator0 out0,
  5631. OutputIterator1 out1,
  5632. OutputIterator2 out2) const
  5633. {
  5634. if ((index0 > max_column_count_) ||
  5635. (index1 > max_column_count_) ||
  5636. (index2 > max_column_count_))
  5637. return false;
  5638. else if (row_range_invalid(row_range))
  5639. return false;
  5640. std::size_t max_index = std::max(index0,std::max(index1,index2));
  5641. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5642. {
  5643. const row_index_range_t& row = dsv_index_.row_index[i];
  5644. if (max_index < dsv_index_.token_count(row))
  5645. {
  5646. process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0);
  5647. process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1);
  5648. process_token(*(dsv_index_.token_list.begin() + (row.first + index2)),out2);
  5649. }
  5650. }
  5651. return true;
  5652. }
  5653. template <typename OutputIterator0, typename OutputIterator1,
  5654. typename OutputIterator2, typename OutputIterator3>
  5655. inline bool extract_column(const row_range_t& row_range,
  5656. const std::size_t& index0,
  5657. const std::size_t& index1,
  5658. const std::size_t& index2,
  5659. const std::size_t& index3,
  5660. OutputIterator0 out0,
  5661. OutputIterator1 out1,
  5662. OutputIterator2 out2,
  5663. OutputIterator3 out3) const
  5664. {
  5665. if ((index0 > max_column_count_) ||
  5666. (index1 > max_column_count_) ||
  5667. (index2 > max_column_count_) ||
  5668. (index3 > max_column_count_))
  5669. return false;
  5670. else if (row_range_invalid(row_range))
  5671. return false;
  5672. std::size_t max_index = std::max(std::max(index0,index1),std::max(index2,index3));
  5673. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5674. {
  5675. const row_index_range_t& row = dsv_index_.row_index[i];
  5676. if (max_index < dsv_index_.token_count(row))
  5677. {
  5678. process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0);
  5679. process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1);
  5680. process_token(*(dsv_index_.token_list.begin() + (row.first + index2)),out2);
  5681. process_token(*(dsv_index_.token_list.begin() + (row.first + index3)),out3);
  5682. }
  5683. }
  5684. return true;
  5685. }
  5686. template <typename OutputIterator0, typename OutputIterator1,
  5687. typename OutputIterator2, typename OutputIterator3,
  5688. typename OutputIterator4>
  5689. inline bool extract_column(const row_range_t& row_range,
  5690. const std::size_t& index0,
  5691. const std::size_t& index1,
  5692. const std::size_t& index2,
  5693. const std::size_t& index3,
  5694. const std::size_t& index4,
  5695. OutputIterator0 out0,
  5696. OutputIterator1 out1,
  5697. OutputIterator2 out2,
  5698. OutputIterator3 out3,
  5699. OutputIterator4 out4) const
  5700. {
  5701. if ((index0 > max_column_count_) ||
  5702. (index1 > max_column_count_) ||
  5703. (index2 > max_column_count_) ||
  5704. (index3 > max_column_count_) ||
  5705. (index4 > max_column_count_))
  5706. return false;
  5707. else if (row_range_invalid(row_range))
  5708. return false;
  5709. std::size_t max_index = std::max(index4,std::max(std::max(index0,index1),std::max(index2,index3)));
  5710. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5711. {
  5712. const row_index_range_t& row = dsv_index_.row_index[i];
  5713. if (max_index < dsv_index_.token_count(row))
  5714. {
  5715. process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0);
  5716. process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1);
  5717. process_token(*(dsv_index_.token_list.begin() + (row.first + index2)),out2);
  5718. process_token(*(dsv_index_.token_list.begin() + (row.first + index3)),out3);
  5719. process_token(*(dsv_index_.token_list.begin() + (row.first + index4)),out4);
  5720. }
  5721. }
  5722. return true;
  5723. }
  5724. inline void remove_row(const std::size_t& index)
  5725. {
  5726. if (index < dsv_index_.row_index.size())
  5727. {
  5728. dsv_index_.remove_row(index);
  5729. }
  5730. }
  5731. template <typename Predicate>
  5732. inline bool remove_row_if(const row_range_t& row_range, Predicate predicate)
  5733. {
  5734. if (row_range_invalid(row_range))
  5735. return false;
  5736. std::size_t removed_token_count = 0;
  5737. std::deque<std::size_t> remove_token_list;
  5738. std::deque<std::size_t> remove_row_list;
  5739. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5740. {
  5741. row_index_range_t& r = dsv_index_.row_index[i];
  5742. std::size_t temp_r_first = r.first - removed_token_count;
  5743. row_type row(i,dsv_index_);
  5744. if (predicate(row))
  5745. {
  5746. remove_row_list.push_back(i);
  5747. for (std::size_t j = r.first; j <= r.second; ++j)
  5748. {
  5749. remove_token_list.push_back(j);
  5750. }
  5751. removed_token_count += row.size();
  5752. }
  5753. r.first = static_cast<unsigned int>(temp_r_first);
  5754. r.second -= static_cast<unsigned int>(removed_token_count);
  5755. }
  5756. for (std::size_t i = row_range.second; i < dsv_index_.row_index.size(); ++i)
  5757. {
  5758. row_index_range_t& r = dsv_index_.row_index[i];
  5759. r.first -= static_cast<unsigned int>(removed_token_count);
  5760. r.second -= static_cast<unsigned int>(removed_token_count);
  5761. }
  5762. if (!remove_row_list.empty())
  5763. {
  5764. remove_inplace(index_remover(remove_row_list),dsv_index_.row_index);
  5765. }
  5766. if (!remove_token_list.empty())
  5767. {
  5768. remove_inplace(index_remover(remove_token_list),dsv_index_.token_list);
  5769. }
  5770. return true;
  5771. }
  5772. template <typename Predicate>
  5773. inline bool remove_row_if(Predicate predicate)
  5774. {
  5775. return remove_row_if(all_rows(),predicate);
  5776. }
  5777. template <typename Predicate>
  5778. inline std::size_t remove_token_if(const row_range_t& row_range, Predicate predicate)
  5779. {
  5780. if (row_range_invalid(row_range))
  5781. return 0;
  5782. std::size_t removed_token_count = 0;
  5783. std::deque<std::size_t> remove_token_list;
  5784. std::deque<std::size_t> remove_row_list;
  5785. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5786. {
  5787. row_index_range_t& r = dsv_index_.row_index[i];
  5788. std::size_t temp_r_first = r.first - removed_token_count;
  5789. row_type row(i,dsv_index_);
  5790. for (std::size_t j = 0; j < row.size(); ++j)
  5791. {
  5792. if (predicate(row.token(j)))
  5793. {
  5794. remove_token_list.push_back(r.first + j);
  5795. ++removed_token_count;
  5796. }
  5797. }
  5798. r.first = static_cast<unsigned int>(temp_r_first);
  5799. r.second -= static_cast<unsigned int>(removed_token_count);
  5800. if (0 == dsv_index_.token_count(r))
  5801. {
  5802. remove_row_list.push_back(i);
  5803. }
  5804. }
  5805. for (std::size_t i = row_range.second; i < dsv_index_.row_index.size(); ++i)
  5806. {
  5807. row_index_range_t& r = dsv_index_.row_index[i];
  5808. r.first -= static_cast<unsigned int>(removed_token_count);
  5809. r.second -= static_cast<unsigned int>(removed_token_count);
  5810. }
  5811. if (!remove_row_list.empty())
  5812. {
  5813. remove_inplace(index_remover(remove_row_list),dsv_index_.row_index);
  5814. }
  5815. if (!remove_token_list.empty())
  5816. {
  5817. remove_inplace(index_remover(remove_token_list),dsv_index_.token_list);
  5818. }
  5819. if (!remove_token_list.empty())
  5820. {
  5821. update_minmax_columns();
  5822. }
  5823. return remove_token_list.size();
  5824. }
  5825. inline std::size_t remove_empty_tokens(const row_range_t& range)
  5826. {
  5827. return remove_token_if(range,is_empty_token());
  5828. }
  5829. inline std::size_t remove_empty_tokens()
  5830. {
  5831. return remove_empty_tokens(all_rows());
  5832. }
  5833. inline void enforce_column_count(const row_range_t& row_range,
  5834. const std::size_t& column_count)
  5835. {
  5836. if (row_range_invalid(row_range))
  5837. return;
  5838. remove_row_if(insufficient_number_of_columns(column_count));
  5839. min_column_count_ = column_count;
  5840. max_column_count_ = column_count;
  5841. }
  5842. inline void enforce_column_count(const std::size_t& column_count)
  5843. {
  5844. enforce_column_count(all_rows(),column_count);
  5845. }
  5846. inline void enforce_min_max_column_count(const row_range_t& row_range,
  5847. const std::size_t& min_column_count,
  5848. const std::size_t& max_column_count)
  5849. {
  5850. if (row_range_invalid(row_range))
  5851. return;
  5852. remove_row_if(insufficient_number_of_minmax_columns(min_column_count,max_column_count));
  5853. min_column_count_ = min_column_count;
  5854. max_column_count_ = max_column_count;
  5855. }
  5856. inline void enforce_min_max_column_count(const std::size_t& min_column_count,
  5857. const std::size_t& max_column_count)
  5858. {
  5859. enforce_min_max_column_count(all_rows(),min_column_count,max_column_count);
  5860. }
  5861. inline void clear(const bool force_delete_buffer = false)
  5862. {
  5863. if (load_from_file_ || force_delete_buffer)
  5864. delete[] buffer_;
  5865. buffer_ = 0;
  5866. buffer_size_ = 0;
  5867. dsv_index_.clear();
  5868. min_column_count_ = 0;
  5869. max_column_count_ = 0;
  5870. state_ = false;
  5871. file_name_ = "";
  5872. }
  5873. inline std::size_t column_width(const std::size_t& col,
  5874. const row_range_t& row_range) const
  5875. {
  5876. if (col > max_column_count_)
  5877. return 0;
  5878. else if (row_range_invalid(row_range))
  5879. return 0;
  5880. std::size_t result = 0;
  5881. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5882. {
  5883. const row_index_range_t& r = dsv_index_.row_index[i];
  5884. if (col < dsv_index_.token_count(r))
  5885. {
  5886. const range_t& range = *(dsv_index_.token_list.begin() + r.first + col);
  5887. result = std::max<std::size_t>(std::distance(range.first,range.second),result);
  5888. }
  5889. }
  5890. return result;
  5891. }
  5892. inline std::size_t column_width(const std::size_t& col) const
  5893. {
  5894. return column_width(col,all_rows());
  5895. }
  5896. template <typename Allocator,
  5897. template <typename,typename> class Sequence>
  5898. inline void get_column_widths(Sequence<std::size_t,Allocator>& columns)
  5899. {
  5900. for (std::size_t c = 0; c < max_column_count(); ++c)
  5901. {
  5902. columns.push_back(column_width(c));
  5903. }
  5904. }
  5905. template <typename Allocator,
  5906. template <typename,typename> class Sequence>
  5907. inline void get_column_widths(Sequence<std::pair<std::size_t,std::size_t>,Allocator>& columns)
  5908. {
  5909. for (std::size_t c = 0; c < max_column_count(); ++c)
  5910. {
  5911. columns.push_back(std::make_pair(c,column_width(c)));
  5912. }
  5913. }
  5914. template <typename T>
  5915. inline std::size_t accumulate_row(const std::size_t& row, T& result) const
  5916. {
  5917. if (row >= dsv_index_.row_index.size())
  5918. return 0;
  5919. const row_index_range_t& r = dsv_index_.row_index[row];
  5920. token_list_t::const_iterator itr = dsv_index_.token_list.begin() + r.first;
  5921. token_list_t::const_iterator end = dsv_index_.token_list.begin() + r.second + 1;
  5922. std::size_t process_count = 0;
  5923. T current_value = T();
  5924. while (end != itr)
  5925. {
  5926. if (string_to_type_converter((*itr).first,(*itr).second,current_value))
  5927. {
  5928. result += current_value;
  5929. ++process_count;
  5930. }
  5931. else
  5932. return 0;
  5933. ++itr;
  5934. }
  5935. return process_count;
  5936. }
  5937. template <typename T>
  5938. inline std::size_t accumulate_column(const std::size_t& col,
  5939. const row_range_t& row_range,
  5940. T& result) const
  5941. {
  5942. if (col > max_column_count_)
  5943. return 0;
  5944. else if (row_range_invalid(row_range))
  5945. return 0;
  5946. std::size_t process_count = 0;
  5947. T current_value = T();
  5948. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5949. {
  5950. const row_index_range_t& r = dsv_index_.row_index[i];
  5951. if (col < dsv_index_.token_count(r))
  5952. {
  5953. const range_t& range = *(dsv_index_.token_list.begin() + r.first + col);
  5954. if (string_to_type_converter(range.first,range.second,current_value))
  5955. result += current_value;
  5956. else
  5957. return 0;
  5958. }
  5959. ++process_count;
  5960. }
  5961. return process_count;
  5962. }
  5963. template <typename T>
  5964. inline std::size_t accumulate_column(const std::size_t& col, T& result) const
  5965. {
  5966. return accumulate_column(col,all_rows(),result);
  5967. }
  5968. template <typename T, typename Predicate>
  5969. inline std::size_t accumulate_column(const std::size_t& col,
  5970. const row_range_t& row_range,
  5971. Predicate p,
  5972. T& result) const
  5973. {
  5974. if (col > max_column_count_)
  5975. return 0;
  5976. else if (row_range_invalid(row_range))
  5977. return 0;
  5978. std::size_t process_count = 0;
  5979. T current_value = T();
  5980. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5981. {
  5982. const row_index_range_t& r = dsv_index_.row_index[i];
  5983. if (col < dsv_index_.token_count(r))
  5984. {
  5985. row_type row = row_type(i,dsv_index_);
  5986. if (p(row))
  5987. {
  5988. const range_t& range = row.token(col);
  5989. if (string_to_type_converter(range.first,range.second,current_value))
  5990. {
  5991. result += current_value;
  5992. ++process_count;
  5993. }
  5994. else
  5995. return 0;
  5996. }
  5997. }
  5998. }
  5999. return process_count;
  6000. }
  6001. template <typename T, typename Predicate>
  6002. inline std::size_t accumulate_column(const std::size_t& col,
  6003. Predicate p,
  6004. T& result) const
  6005. {
  6006. return accumulate_column(col,all_rows(),p,result);
  6007. }
  6008. inline bool join_row(const std::size_t& row,
  6009. const std::string& delimiter,
  6010. std::string& result)
  6011. {
  6012. if (row >= dsv_index_.row_index.size())
  6013. return false;
  6014. const row_index_range_t& r = dsv_index_.row_index[row];
  6015. token_list_t::const_iterator itr = dsv_index_.token_list.begin() + r.first;
  6016. token_list_t::const_iterator end = dsv_index_.token_list.begin() + r.second + (row < (dsv_index_.row_index.size() - 1) ? 1 : 0);
  6017. result.reserve(delimiter.size() * dsv_index_.token_count(r) + std::distance(itr->first,end->second));
  6018. bool appended = false;
  6019. while (end != itr)
  6020. {
  6021. if (!delimiter.empty() && appended)
  6022. result.append(delimiter);
  6023. appended = false;
  6024. if ((*itr).first != (*itr).second)
  6025. {
  6026. result.append((*itr).first,(*itr).second);
  6027. appended = true;
  6028. }
  6029. ++itr;
  6030. }
  6031. return true;
  6032. }
  6033. template <typename Predicate>
  6034. inline bool join_row(const std::size_t& row,
  6035. Predicate predicate,
  6036. const std::string& delimiter,
  6037. std::string& result)
  6038. {
  6039. if (row >= dsv_index_.row_index.size())
  6040. return false;
  6041. const row_index_range_t& r = dsv_index_.row_index[row];
  6042. token_list_t::const_iterator itr = (dsv_index_.token_list.begin() + r.first);
  6043. token_list_t::const_iterator end = dsv_index_.token_list.begin() + r.second + (row < (dsv_index_.row_index.size() - 1) ? 1 : 0);
  6044. result.reserve(delimiter.size() * dsv_index_.token_count(r) + std::distance(itr->first,end->second));
  6045. bool appended = false;
  6046. while (end != itr)
  6047. {
  6048. if (!delimiter.empty() && appended)
  6049. result.append(delimiter);
  6050. appended = false;
  6051. if ((*itr).first != (*itr).second)
  6052. {
  6053. if (predicate(*itr))
  6054. {
  6055. result.append((*itr).first,(*itr).second);
  6056. appended = true;
  6057. }
  6058. }
  6059. ++itr;
  6060. }
  6061. return true;
  6062. }
  6063. template <typename Predicate>
  6064. inline bool join_row(const std::size_t& row,
  6065. Predicate predicate,
  6066. const char* delimiter,
  6067. std::string& result)
  6068. {
  6069. return join_row(row,predicate,std::string(delimiter),result);
  6070. }
  6071. inline bool join_column(const std::size_t& col,
  6072. const row_range_t& row_range,
  6073. const std::string& delimiter,
  6074. std::string& result) const
  6075. {
  6076. if (col > max_column_count_)
  6077. return false;
  6078. else if (row_range_invalid(row_range))
  6079. return false;
  6080. bool appended = false;
  6081. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  6082. {
  6083. const row_index_range_t& r = dsv_index_.row_index[i];
  6084. if (col < dsv_index_.token_count(r))
  6085. {
  6086. row_type row = row_type(i,dsv_index_);
  6087. const range_t& range = row.token(col);
  6088. if (!delimiter.empty() && appended)
  6089. result.append(delimiter);
  6090. appended = false;
  6091. if (range.first != range.second)
  6092. {
  6093. result.append(range.first,range.second);
  6094. appended = true;
  6095. }
  6096. }
  6097. }
  6098. return true;
  6099. }
  6100. inline bool join_column(const std::size_t& col,
  6101. const std::string& delimiter,
  6102. std::string& result) const
  6103. {
  6104. return join_column(col,all_rows(),delimiter,result);
  6105. }
  6106. template <typename Predicate>
  6107. inline bool join_column(const std::size_t& col,
  6108. const row_range_t& row_range,
  6109. Predicate predicate,
  6110. const std::string& delimiter,
  6111. std::string& result) const
  6112. {
  6113. if (col > max_column_count_)
  6114. return false;
  6115. else if (row_range_invalid(row_range))
  6116. return false;
  6117. bool appended = false;
  6118. const std::size_t pre_end_index = row_range.second - 1;
  6119. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  6120. {
  6121. const row_index_range_t& r = dsv_index_.row_index[i];
  6122. if (col < dsv_index_.token_count(r))
  6123. {
  6124. row_type row = row_type(i,dsv_index_);
  6125. const range_t& range = row.token(col);
  6126. if (!delimiter.empty() && appended && (pre_end_index != i))
  6127. result.append(delimiter);
  6128. appended = false;
  6129. if (range.first != range.second)
  6130. {
  6131. if (predicate(row))
  6132. {
  6133. result.append(range.first,range.second);
  6134. appended = true;
  6135. }
  6136. }
  6137. }
  6138. }
  6139. return true;
  6140. }
  6141. template <typename Predicate>
  6142. inline bool join_column(const std::size_t& col,
  6143. Predicate p,
  6144. const std::string& delimiter,
  6145. std::string& result) const
  6146. {
  6147. return join_column(col,all_rows(),p,delimiter,result);
  6148. }
  6149. template <typename TransitionPredicate, typename Function>
  6150. inline bool sequential_partition(const row_range_t& row_range,
  6151. TransitionPredicate p,
  6152. Function f)
  6153. {
  6154. if (row_range_invalid(row_range))
  6155. return false;
  6156. row_range_t r(row_range.first,row_range.first);
  6157. for (row_range_t::first_type i = row_range.first; i < row_range.second; ++i)
  6158. {
  6159. if (p(row_type(i,dsv_index_)))
  6160. {
  6161. if (r.first != r.second)
  6162. {
  6163. r.second = i;
  6164. if (!f(*this,r))
  6165. return false;
  6166. }
  6167. r.first = r.second;
  6168. }
  6169. else
  6170. r.second = i;
  6171. }
  6172. if (r.first != row_range.second)
  6173. {
  6174. r.second = row_range.second;
  6175. if (!f(*this,r))
  6176. return false;
  6177. }
  6178. return true;
  6179. }
  6180. template <typename TransitionPredicate, typename Function>
  6181. inline bool sequential_partition(TransitionPredicate p, Function f)
  6182. {
  6183. return sequential_partition(all_rows(),p,f);
  6184. }
  6185. static inline token_grid::options default_options()
  6186. {
  6187. return options();
  6188. }
  6189. template <typename Function>
  6190. inline std::size_t for_each_row(const row_range_t& row_range, Function f) const
  6191. {
  6192. if (row_range_invalid(row_range))
  6193. return 0;
  6194. std::size_t row_count = 0;
  6195. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  6196. {
  6197. f(row_type(i,dsv_index_));
  6198. ++row_count;
  6199. }
  6200. return row_count;
  6201. }
  6202. template <typename Function>
  6203. inline std::size_t for_each_row(Function f) const
  6204. {
  6205. return for_each_row(all_rows(),f);
  6206. }
  6207. bool load(const std::string& file_name,
  6208. const token_grid::options& options)
  6209. {
  6210. file_name_ = file_name;
  6211. if ((load_from_file_) && (0 != buffer_))
  6212. {
  6213. delete [] buffer_;
  6214. buffer_ = 0;
  6215. }
  6216. buffer_size_ = 0;
  6217. min_column_count_ = 0;
  6218. max_column_count_ = 0;
  6219. options_ = options;
  6220. load_from_file_ = true;
  6221. state_ = load();
  6222. if (state_)
  6223. return true;
  6224. else
  6225. {
  6226. file_name_ = "";
  6227. if ((load_from_file_) && (0 != buffer_))
  6228. {
  6229. delete [] buffer_;
  6230. buffer_ = 0;
  6231. }
  6232. return false;
  6233. }
  6234. }
  6235. bool load(unsigned char* buffer,
  6236. const std::size_t buffer_size,
  6237. const token_grid::options& options)
  6238. {
  6239. file_name_ = "";
  6240. if ((load_from_file_) && (0 != buffer_))
  6241. {
  6242. delete [] buffer_;
  6243. buffer_ = 0;
  6244. }
  6245. min_column_count_ = 0;
  6246. max_column_count_ = 0;
  6247. options_ = options;
  6248. load_from_file_ = false;
  6249. buffer_ = buffer;
  6250. buffer_size_ = buffer_size;
  6251. state_ = load();
  6252. if (state_)
  6253. return true;
  6254. else
  6255. {
  6256. file_name_ = "";
  6257. if ((load_from_file_) && (0 != buffer_))
  6258. {
  6259. delete [] buffer_;
  6260. buffer_ = 0;
  6261. }
  6262. return false;
  6263. }
  6264. }
  6265. private:
  6266. token_grid(const token_grid& tg);
  6267. token_grid& operator=(const token_grid& tg);
  6268. struct is_empty_token
  6269. {
  6270. inline bool operator()(const range_t& r) const
  6271. {
  6272. return r.first == r.second;
  6273. }
  6274. };
  6275. struct insufficient_number_of_columns
  6276. {
  6277. insufficient_number_of_columns(const std::size_t& noc)
  6278. : num_of_cols(noc)
  6279. {}
  6280. inline bool operator()(const row_type& row) const
  6281. {
  6282. return (num_of_cols != row.size());
  6283. }
  6284. std::size_t num_of_cols;
  6285. };
  6286. struct insufficient_number_of_minmax_columns
  6287. {
  6288. insufficient_number_of_minmax_columns(const std::size_t& min_col, const std::size_t& max_col)
  6289. : min_column_count(min_col),
  6290. max_column_count(max_col)
  6291. {}
  6292. inline bool operator()(const row_type& row) const
  6293. {
  6294. return (row.size() < min_column_count) || (max_column_count < row.size());
  6295. }
  6296. std::size_t min_column_count;
  6297. std::size_t max_column_count;
  6298. };
  6299. class double_quotes_predicate
  6300. {
  6301. public:
  6302. double_quotes_predicate(const std::string& delimiters)
  6303. : in_bracket_range_(false),
  6304. mdp_(delimiters)
  6305. {}
  6306. inline bool operator()(const unsigned char c) const
  6307. {
  6308. if ('"' == c)
  6309. {
  6310. in_bracket_range_ = !in_bracket_range_;
  6311. return false;
  6312. }
  6313. else if (in_bracket_range_)
  6314. return false;
  6315. else
  6316. return mdp_(c);
  6317. }
  6318. inline void reset()
  6319. {
  6320. in_bracket_range_ = false;
  6321. }
  6322. private:
  6323. mutable bool in_bracket_range_;
  6324. mutable strtk::multiple_char_delimiter_predicate mdp_;
  6325. };
  6326. inline bool load()
  6327. {
  6328. if (load_from_file_ && !load_buffer_from_file())
  6329. return false;
  6330. dsv_index_.token_list.clear();
  6331. dsv_index_.row_index.clear();
  6332. multiple_char_delimiter_predicate text_newline_predicate(options_.row_delimiters);
  6333. if (!options_.support_dquotes)
  6334. {
  6335. multiple_char_delimiter_predicate token_predicate(options_.column_delimiters);
  6336. strtk::split(text_newline_predicate,
  6337. buffer_, buffer_ + buffer_size_,
  6338. strtk::functional_inserter(
  6339. row_processor<multiple_char_delimiter_predicate>(dsv_index_,token_predicate,options_.column_split_option)),
  6340. strtk::split_options::compress_delimiters);
  6341. }
  6342. else
  6343. {
  6344. double_quotes_predicate token_predicate_dblq(options_.column_delimiters);
  6345. strtk::split(text_newline_predicate,
  6346. buffer_, buffer_ + buffer_size_,
  6347. strtk::functional_inserter(
  6348. row_processor<double_quotes_predicate>(dsv_index_,token_predicate_dblq,options_.column_split_option)),
  6349. strtk::split_options::compress_delimiters);
  6350. if (options_.trim_dquotes)
  6351. {
  6352. for (std::size_t i = 0; i < dsv_index_.token_list.size(); ++i)
  6353. {
  6354. if (
  6355. ((*(dsv_index_.token_list[i].first )) == '"') &&
  6356. ((*(dsv_index_.token_list[i].second - 1)) == '"')
  6357. )
  6358. {
  6359. ++dsv_index_.token_list[i].first;
  6360. --dsv_index_.token_list[i].second;
  6361. }
  6362. }
  6363. }
  6364. }
  6365. update_minmax_columns();
  6366. return true;
  6367. }
  6368. inline bool load_buffer_from_file()
  6369. {
  6370. std::ifstream stream(file_name_.c_str(),std::ios::binary);
  6371. if (!stream)
  6372. return false;
  6373. stream.seekg (0,std::ios::end);
  6374. buffer_size_ = static_cast<std::size_t>(stream.tellg());
  6375. if (0 == buffer_size_)
  6376. return false;
  6377. stream.seekg (0,std::ios::beg);
  6378. buffer_ = new unsigned char[buffer_size_];
  6379. stream.read(reinterpret_cast<char*>(buffer_),static_cast<std::streamsize>(buffer_size_));
  6380. stream.close();
  6381. return true;
  6382. }
  6383. template <typename OutputIterator>
  6384. inline void process_token(const range_t& range, OutputIterator out) const
  6385. {
  6386. typedef typename std::iterator_traits<OutputIterator>::value_type output_type;
  6387. (*out) = string_to_type_converter<output_type>(range.first,range.second);
  6388. ++out;
  6389. }
  6390. template <typename OutputIterator>
  6391. inline void process_token_checked(const range_t& range, OutputIterator out) const
  6392. {
  6393. typedef typename std::iterator_traits<OutputIterator>::value_type output_type;
  6394. output_type value;
  6395. if (string_to_type_converter(range.first,range.second,value))
  6396. {
  6397. (*out) = value;
  6398. ++out;
  6399. }
  6400. }
  6401. inline bool row_range_invalid(const row_range_t& row_range) const
  6402. {
  6403. if (row_range.first > dsv_index_.row_index.size())
  6404. return true;
  6405. else if (row_range.second > dsv_index_.row_index.size())
  6406. return true;
  6407. else if (row_range.first > row_range.second)
  6408. return true;
  6409. else
  6410. return false;
  6411. }
  6412. inline void update_minmax_columns()
  6413. {
  6414. min_column_count_ = std::numeric_limits<std::size_t>::max();
  6415. max_column_count_ = std::numeric_limits<std::size_t>::min();
  6416. for (std::size_t i = 0; i < dsv_index_.row_index.size(); ++i)
  6417. {
  6418. const row_index_range_t& r = dsv_index_.row_index[i];
  6419. const std::size_t number_of_tokens = dsv_index_.token_count(r);
  6420. if (number_of_tokens > max_column_count_)
  6421. max_column_count_ = number_of_tokens;
  6422. if (number_of_tokens < min_column_count_)
  6423. min_column_count_ = number_of_tokens;
  6424. }
  6425. }
  6426. private:
  6427. store dsv_index_;
  6428. std::string file_name_;
  6429. unsigned char* buffer_;
  6430. std::size_t buffer_size_;
  6431. std::size_t min_column_count_;
  6432. std::size_t max_column_count_;
  6433. options options_;
  6434. bool load_from_file_;
  6435. bool state_;
  6436. };
  6437. template <typename T>
  6438. inline bool convert_string_range(const std::pair<std::string::const_iterator,std::string::const_iterator>& range, T& t)
  6439. {
  6440. if (range.first == range.second) return false;
  6441. t = string_to_type_converter<T>(std::string(range.first,range.second));
  6442. return true;
  6443. }
  6444. struct empty_range
  6445. {
  6446. public:
  6447. template <typename InputIterator>
  6448. inline bool operator()(const InputIterator begin, const InputIterator end)
  6449. {
  6450. return (0 == std::distance(begin,end));
  6451. }
  6452. };
  6453. struct nonempty_range
  6454. {
  6455. public:
  6456. template <typename InputIterator>
  6457. inline bool operator()(const InputIterator begin, const InputIterator end)
  6458. {
  6459. return (0 != std::distance(begin,end));
  6460. }
  6461. };
  6462. template <typename OutputIterator>
  6463. struct filter_non_empty_range
  6464. {
  6465. public:
  6466. filter_non_empty_range(OutputIterator out)
  6467. : out_(out)
  6468. {}
  6469. template <typename Iterator>
  6470. inline void operator() (const std::pair<Iterator,Iterator>& range)
  6471. {
  6472. if (range.first != range.second)
  6473. {
  6474. *out_++ = range;
  6475. }
  6476. }
  6477. private:
  6478. OutputIterator out_;
  6479. };
  6480. template <typename OutputPredicate>
  6481. struct filter_on_wildcard_match
  6482. {
  6483. public:
  6484. filter_on_wildcard_match(const std::string& match_pattern,
  6485. OutputPredicate& predicate,
  6486. bool allow_through_on_match = true)
  6487. : allow_through_on_match_(allow_through_on_match),
  6488. match_pattern_(match_pattern),
  6489. predicate_(predicate)
  6490. {}
  6491. template <typename Iterator>
  6492. inline void operator() (const std::pair<Iterator,Iterator>& range) const
  6493. {
  6494. if (match(match_pattern_.begin(),match_pattern_.end(),range.first,range.second,'*','?') ^ allow_through_on_match_)
  6495. {
  6496. predicate_(range);
  6497. }
  6498. }
  6499. inline void operator() (const std::string& s) const
  6500. {
  6501. if (match(match_pattern_,s) ^ allow_through_on_match_)
  6502. {
  6503. predicate_(s);
  6504. }
  6505. }
  6506. private:
  6507. filter_on_wildcard_match(const filter_on_wildcard_match& fom);
  6508. filter_on_wildcard_match& operator=(const filter_on_wildcard_match& fom);
  6509. bool allow_through_on_match_;
  6510. std::string match_pattern_;
  6511. OutputPredicate& predicate_;
  6512. };
  6513. template <typename OutputPredicate>
  6514. struct filter_on_match
  6515. {
  6516. public:
  6517. filter_on_match(const std::string* begin, const std::string* end,
  6518. OutputPredicate predicate,
  6519. bool case_insensitive,
  6520. bool allow_through_on_match = true)
  6521. : case_insensitive_(case_insensitive),
  6522. allow_through_on_match_(allow_through_on_match),
  6523. begin_(begin),
  6524. end_(end),
  6525. predicate_(predicate)
  6526. {}
  6527. template <typename Iterator>
  6528. inline void operator() (const std::pair<Iterator,Iterator>& range) const
  6529. {
  6530. for (const std::string* itr = begin_; end_ != itr; ++itr)
  6531. {
  6532. if (
  6533. (case_insensitive_ &&
  6534. (imatch((*itr).data(),(*itr).data() + (*itr).size(),range.first,range.second))) ||
  6535. (!case_insensitive_ && std::equal((*itr).begin(),(*itr).end(),range.first))
  6536. )
  6537. {
  6538. if (allow_through_on_match_)
  6539. {
  6540. predicate_(range);
  6541. }
  6542. return;
  6543. }
  6544. }
  6545. if (!allow_through_on_match_)
  6546. {
  6547. predicate_(range);
  6548. }
  6549. }
  6550. inline void operator() (const std::string& s) const
  6551. {
  6552. for (const std::string* itr = begin_; end_ != itr; ++itr)
  6553. {
  6554. if (
  6555. (case_insensitive_ &&
  6556. (imatch((*itr).begin(),(*itr).end(),s.begin(),s.end()))) ||
  6557. (!case_insensitive_ && std::equal((*itr).begin(),(*itr).end(),s.begin()))
  6558. )
  6559. {
  6560. if (allow_through_on_match_)
  6561. {
  6562. predicate_(s);
  6563. return;
  6564. }
  6565. }
  6566. }
  6567. if (!allow_through_on_match_)
  6568. {
  6569. predicate_(s);
  6570. return;
  6571. }
  6572. }
  6573. private:
  6574. filter_on_match& operator=(const filter_on_match& fom);
  6575. private:
  6576. bool case_insensitive_;
  6577. bool allow_through_on_match_;
  6578. const std::string* begin_;
  6579. const std::string* end_;
  6580. OutputPredicate predicate_;
  6581. };
  6582. template <typename Iterator, typename MatchPredicate>
  6583. inline void skip_while_matching(Iterator& itr,
  6584. const Iterator& end,
  6585. const MatchPredicate& predicate)
  6586. {
  6587. while (end != itr)
  6588. {
  6589. if (predicate(*itr))
  6590. ++itr;
  6591. else
  6592. break;
  6593. }
  6594. }
  6595. template <std::size_t length>
  6596. struct size_equal_to
  6597. {
  6598. template <typename Iterator>
  6599. inline bool operator()(const Iterator begin, const Iterator end) const
  6600. {
  6601. return length == std::distance(begin,end);
  6602. }
  6603. template <typename Iterator>
  6604. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6605. {
  6606. return length == std::distance(range.first,range.second);
  6607. }
  6608. template <typename T,
  6609. typename Allocator,
  6610. template <typename,typename> class Sequence>
  6611. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6612. {
  6613. return length == sequence.size();
  6614. }
  6615. template <typename T,
  6616. typename Comparator,
  6617. typename Allocator>
  6618. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6619. {
  6620. return length == set.size();
  6621. }
  6622. template <typename T,
  6623. typename Comparator,
  6624. typename Allocator>
  6625. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6626. {
  6627. return length == multiset.size();
  6628. }
  6629. inline bool operator()(const std::string& str) const
  6630. {
  6631. return length == str.size();
  6632. }
  6633. };
  6634. template <std::size_t length>
  6635. struct size_less_than
  6636. {
  6637. template <typename Iterator>
  6638. inline bool operator()(const Iterator begin, const Iterator end) const
  6639. {
  6640. return std::distance(begin,end) < static_cast<typename std::iterator_traits<Iterator>::difference_type>(length);
  6641. }
  6642. template <typename Iterator>
  6643. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6644. {
  6645. return std::distance(range.first,range.second) < static_cast<typename std::iterator_traits<Iterator>::difference_type>(length);
  6646. }
  6647. template <typename T,
  6648. typename Allocator,
  6649. template <typename,typename> class Sequence>
  6650. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6651. {
  6652. return sequence.size() < length;
  6653. }
  6654. template <typename T,
  6655. typename Comparator,
  6656. typename Allocator>
  6657. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6658. {
  6659. return set.size() < length;
  6660. }
  6661. template <typename T,
  6662. typename Comparator,
  6663. typename Allocator>
  6664. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6665. {
  6666. return multiset.size() < length;
  6667. }
  6668. inline bool operator()(const std::string& str) const
  6669. {
  6670. return str.size() < length;
  6671. }
  6672. };
  6673. template <std::size_t length>
  6674. struct size_greater_than
  6675. {
  6676. template <typename Iterator>
  6677. inline bool operator()(const Iterator begin, const Iterator end) const
  6678. {
  6679. return std::distance(begin,end) > static_cast<typename std::iterator_traits<Iterator>::difference_type>(length);
  6680. }
  6681. template <typename Iterator>
  6682. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6683. {
  6684. return std::distance(range.first,range.second) > static_cast<typename std::iterator_traits<Iterator>::difference_type>(length);
  6685. }
  6686. template <typename T,
  6687. typename Allocator,
  6688. template <typename,typename> class Sequence>
  6689. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6690. {
  6691. return sequence.size() > length;
  6692. }
  6693. template <typename T,
  6694. typename Comparator,
  6695. typename Allocator>
  6696. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6697. {
  6698. return set.size() > length;
  6699. }
  6700. template <typename T,
  6701. typename Comparator,
  6702. typename Allocator>
  6703. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6704. {
  6705. return multiset.size() > length;
  6706. }
  6707. inline bool operator()(const std::string& str) const
  6708. {
  6709. return str.size() > length;
  6710. }
  6711. };
  6712. struct size_is_even
  6713. {
  6714. template <typename Iterator>
  6715. inline bool operator()(const Iterator begin, const Iterator end) const
  6716. {
  6717. return 0 == (std::distance(begin,end) % 2);
  6718. }
  6719. template <typename Iterator>
  6720. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6721. {
  6722. return 0 == (std::distance(range.first,range.second) % 2);
  6723. }
  6724. template <typename T,
  6725. typename Allocator,
  6726. template <typename,typename> class Sequence>
  6727. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6728. {
  6729. return 0 == (sequence.size() % 2);
  6730. }
  6731. template <typename T,
  6732. typename Comparator,
  6733. typename Allocator>
  6734. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6735. {
  6736. return 0 == (set.size() % 2);
  6737. }
  6738. template <typename T,
  6739. typename Comparator,
  6740. typename Allocator>
  6741. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6742. {
  6743. return 0 == (multiset.size() % 2);
  6744. }
  6745. inline bool operator()(const std::string& str) const
  6746. {
  6747. return 0 == (str.size() % 2);
  6748. }
  6749. };
  6750. struct size_is_odd
  6751. {
  6752. template <typename Iterator>
  6753. inline bool operator()(const Iterator begin, const Iterator end) const
  6754. {
  6755. return 0 != (std::distance(begin,end) % 2);
  6756. }
  6757. template <typename Iterator>
  6758. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6759. {
  6760. return 0 != (std::distance(range.first,range.second) % 2);
  6761. }
  6762. template <typename T,
  6763. typename Allocator,
  6764. template <typename,typename> class Sequence>
  6765. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6766. {
  6767. return 0 != (sequence.size() % 2);
  6768. }
  6769. template <typename T,
  6770. typename Comparator,
  6771. typename Allocator>
  6772. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6773. {
  6774. return 0 != (set.size() % 2);
  6775. }
  6776. template <typename T,
  6777. typename Comparator,
  6778. typename Allocator>
  6779. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6780. {
  6781. return 0 != (multiset.size() % 2);
  6782. }
  6783. inline bool operator()(const std::string& str) const
  6784. {
  6785. return 0 != (str.size() % 2);
  6786. }
  6787. };
  6788. template <typename InputIterator,
  6789. typename T1, typename T2, typename T3, typename T4,
  6790. typename T5, typename T6, typename T7, typename T8,
  6791. typename T9, typename T10, typename T11, typename T12>
  6792. inline bool parse(const InputIterator begin,
  6793. const InputIterator end,
  6794. const std::string& delimiters,
  6795. T1& t1, T2& t2, T3& t3, T4& t4,
  6796. T5& t5, T6& t6, T7& t7, T8& t8,
  6797. T9& t9, T10& t10, T11& t11, T12& t12)
  6798. {
  6799. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6800. details::convert_type_assert<itr_type>();
  6801. static const std::size_t token_count = 12;
  6802. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6803. typedef iterator_type* iterator_type_ptr;
  6804. iterator_type token_list[token_count];
  6805. const std::size_t parsed_token_count = split_n(delimiters,
  6806. begin,end,
  6807. token_count,
  6808. token_list,
  6809. split_options::compress_delimiters);
  6810. if (token_count > parsed_token_count)
  6811. return false;
  6812. iterator_type_ptr itr = token_list;
  6813. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  6814. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  6815. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  6816. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  6817. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  6818. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  6819. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  6820. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  6821. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  6822. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr;
  6823. if (!string_to_type_converter((*itr).first,(*itr).second,t11)) return false; ++itr;
  6824. if (!string_to_type_converter((*itr).first,(*itr).second,t12)) return false;
  6825. return true;
  6826. }
  6827. template <typename InputIterator,
  6828. typename T1, typename T2, typename T3, typename T4,
  6829. typename T5, typename T6, typename T7, typename T8,
  6830. typename T9, typename T10, typename T11>
  6831. inline bool parse(const InputIterator begin,
  6832. const InputIterator end,
  6833. const std::string& delimiters,
  6834. T1& t1, T2& t2, T3& t3, T4& t4,
  6835. T5& t5, T6& t6, T7& t7, T8& t8,
  6836. T9& t9, T10& t10, T11& t11)
  6837. {
  6838. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6839. details::convert_type_assert<itr_type>();
  6840. static const std::size_t token_count = 11;
  6841. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6842. typedef iterator_type* iterator_type_ptr;
  6843. iterator_type token_list[token_count];
  6844. const std::size_t parsed_token_count = split_n(delimiters,
  6845. begin,end,
  6846. token_count,
  6847. token_list,
  6848. split_options::compress_delimiters);
  6849. if (token_count > parsed_token_count)
  6850. return false;
  6851. iterator_type_ptr itr = token_list;
  6852. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  6853. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  6854. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  6855. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  6856. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  6857. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  6858. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  6859. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  6860. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  6861. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr;
  6862. if (!string_to_type_converter((*itr).first,(*itr).second,t11)) return false;
  6863. return true;
  6864. }
  6865. template <typename InputIterator,
  6866. typename T1, typename T2, typename T3, typename T4,
  6867. typename T5, typename T6, typename T7, typename T8,
  6868. typename T9, typename T10>
  6869. inline bool parse(const InputIterator begin,
  6870. const InputIterator end,
  6871. const std::string& delimiters,
  6872. T1& t1, T2& t2, T3& t3, T4& t4,
  6873. T5& t5, T6& t6, T7& t7, T8& t8,
  6874. T9& t9, T10& t10)
  6875. {
  6876. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6877. details::convert_type_assert<itr_type>();
  6878. static const std::size_t token_count = 10;
  6879. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6880. typedef iterator_type* iterator_type_ptr;
  6881. iterator_type token_list[token_count];
  6882. const std::size_t parsed_token_count = split_n(delimiters,
  6883. begin,end,
  6884. token_count,
  6885. token_list,
  6886. split_options::compress_delimiters);
  6887. if (token_count > parsed_token_count)
  6888. return false;
  6889. iterator_type_ptr itr = token_list;
  6890. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  6891. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  6892. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  6893. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  6894. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  6895. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  6896. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  6897. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  6898. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  6899. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false;
  6900. return true;
  6901. }
  6902. template <typename InputIterator,
  6903. typename T1, typename T2, typename T3, typename T4,
  6904. typename T5, typename T6, typename T7, typename T8,
  6905. typename T9>
  6906. inline bool parse(const InputIterator begin,
  6907. const InputIterator end,
  6908. const std::string& delimiters,
  6909. T1& t1, T2& t2, T3& t3, T4& t4,
  6910. T5& t5, T6& t6, T7& t7, T8& t8,
  6911. T9& t9)
  6912. {
  6913. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6914. details::convert_type_assert<itr_type>();
  6915. static const std::size_t token_count = 9;
  6916. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6917. typedef iterator_type* iterator_type_ptr;
  6918. iterator_type token_list[token_count];
  6919. const std::size_t parsed_token_count = split_n(delimiters,
  6920. begin,end,
  6921. token_count,
  6922. token_list,
  6923. split_options::compress_delimiters);
  6924. if (token_count > parsed_token_count)
  6925. return false;
  6926. iterator_type_ptr itr = token_list;
  6927. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6928. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  6929. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  6930. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  6931. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  6932. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  6933. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  6934. if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false; ++itr;
  6935. if (!string_to_type_converter((*itr).first,(*itr).second,t9)) return false;
  6936. return true;
  6937. }
  6938. template <typename InputIterator,
  6939. typename T1, typename T2, typename T3, typename T4,
  6940. typename T5, typename T6, typename T7, typename T8>
  6941. inline bool parse(const InputIterator begin,
  6942. const InputIterator end,
  6943. const std::string& delimiters,
  6944. T1& t1, T2& t2, T3& t3, T4& t4,
  6945. T5& t5, T6& t6, T7& t7, T8& t8)
  6946. {
  6947. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6948. details::convert_type_assert<itr_type>();
  6949. static const std::size_t token_count = 8;
  6950. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6951. typedef iterator_type* iterator_type_ptr;
  6952. iterator_type token_list[token_count];
  6953. const std::size_t parsed_token_count = split_n(delimiters,
  6954. begin,end,
  6955. token_count,
  6956. token_list,
  6957. split_options::compress_delimiters);
  6958. if (token_count > parsed_token_count)
  6959. return false;
  6960. iterator_type_ptr itr = token_list;
  6961. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6962. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  6963. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  6964. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  6965. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  6966. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  6967. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  6968. if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false;
  6969. return true;
  6970. }
  6971. template <typename InputIterator,
  6972. typename T1, typename T2, typename T3, typename T4,
  6973. typename T5, typename T6, typename T7>
  6974. inline bool parse(const InputIterator begin,
  6975. const InputIterator end,
  6976. const std::string& delimiters,
  6977. T1& t1, T2& t2, T3& t3, T4& t4,
  6978. T5& t5, T6& t6, T7& t7)
  6979. {
  6980. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6981. details::convert_type_assert<itr_type>();
  6982. static const std::size_t token_count = 7;
  6983. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6984. typedef iterator_type* iterator_type_ptr;
  6985. iterator_type token_list[token_count];
  6986. const std::size_t parsed_token_count = split_n(delimiters,
  6987. begin,end,
  6988. token_count,
  6989. token_list,
  6990. split_options::compress_delimiters);
  6991. if (token_count > parsed_token_count)
  6992. return false;
  6993. iterator_type_ptr itr = token_list;
  6994. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6995. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  6996. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  6997. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  6998. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  6999. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7000. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false;
  7001. return true;
  7002. }
  7003. template <typename InputIterator,
  7004. typename T1, typename T2, typename T3, typename T4,
  7005. typename T5, typename T6>
  7006. inline bool parse(const InputIterator begin,
  7007. const InputIterator end,
  7008. const std::string& delimiters,
  7009. T1& t1, T2& t2, T3& t3, T4& t4,
  7010. T5& t5, T6& t6)
  7011. {
  7012. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7013. details::convert_type_assert<itr_type>();
  7014. static const std::size_t token_count = 6;
  7015. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7016. typedef iterator_type* iterator_type_ptr;
  7017. iterator_type token_list[token_count];
  7018. const std::size_t parsed_token_count = split_n(delimiters,
  7019. begin,end,
  7020. token_count,
  7021. token_list,
  7022. split_options::compress_delimiters);
  7023. if (token_count > parsed_token_count)
  7024. return false;
  7025. iterator_type_ptr itr = token_list;
  7026. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7027. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7028. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7029. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7030. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7031. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false;
  7032. return true;
  7033. }
  7034. template <typename InputIterator,
  7035. typename T1, typename T2, typename T3, typename T4,
  7036. typename T5>
  7037. inline bool parse(const InputIterator begin,
  7038. const InputIterator end,
  7039. const std::string& delimiters,
  7040. T1& t1, T2& t2, T3& t3, T4& t4,
  7041. T5& t5)
  7042. {
  7043. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7044. details::convert_type_assert<itr_type>();
  7045. static const std::size_t token_count = 5;
  7046. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7047. typedef iterator_type* iterator_type_ptr;
  7048. iterator_type token_list[token_count];
  7049. const std::size_t parsed_token_count = split_n(delimiters,
  7050. begin,end,
  7051. token_count,
  7052. token_list,
  7053. split_options::compress_delimiters);
  7054. if (token_count > parsed_token_count)
  7055. return false;
  7056. iterator_type_ptr itr = token_list;
  7057. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7058. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7059. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7060. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7061. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false;
  7062. return true;
  7063. }
  7064. template <typename InputIterator,
  7065. typename T1, typename T2, typename T3, typename T4>
  7066. inline bool parse(const InputIterator begin,
  7067. const InputIterator end,
  7068. const std::string& delimiters,
  7069. T1& t1, T2& t2, T3& t3, T4& t4)
  7070. {
  7071. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7072. details::convert_type_assert<itr_type>();
  7073. static const std::size_t token_count = 4;
  7074. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7075. typedef iterator_type* iterator_type_ptr;
  7076. iterator_type token_list[token_count];
  7077. const std::size_t parsed_token_count = split_n(delimiters,
  7078. begin,end,
  7079. token_count,
  7080. token_list,
  7081. split_options::compress_delimiters);
  7082. if (token_count > parsed_token_count)
  7083. return false;
  7084. iterator_type_ptr itr = token_list;
  7085. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7086. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7087. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7088. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false;
  7089. return true;
  7090. }
  7091. template <typename InputIterator,
  7092. typename T1, typename T2, typename T3>
  7093. inline bool parse(const InputIterator begin,
  7094. const InputIterator end,
  7095. const std::string& delimiters,
  7096. T1& t1, T2& t2, T3& t3)
  7097. {
  7098. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7099. details::convert_type_assert<itr_type>();
  7100. static const std::size_t token_count = 3;
  7101. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7102. typedef iterator_type* iterator_type_ptr;
  7103. iterator_type token_list[token_count];
  7104. const std::size_t parsed_token_count = split_n(delimiters,
  7105. begin,end,
  7106. token_count,
  7107. token_list,
  7108. split_options::compress_delimiters);
  7109. if (token_count > parsed_token_count)
  7110. return false;
  7111. iterator_type_ptr itr = token_list;
  7112. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7113. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7114. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false;
  7115. return true;
  7116. }
  7117. template <typename InputIterator, typename T1, typename T2>
  7118. inline bool parse(const InputIterator begin,
  7119. const InputIterator end,
  7120. const std::string& delimiters,
  7121. T1& t1, T2& t2)
  7122. {
  7123. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7124. details::convert_type_assert<itr_type>();
  7125. static const std::size_t token_count = 2;
  7126. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7127. typedef iterator_type* iterator_type_ptr;
  7128. iterator_type token_list[token_count];
  7129. const std::size_t parsed_token_count = split_n(delimiters,
  7130. begin,end,
  7131. token_count,
  7132. token_list,
  7133. split_options::compress_delimiters);
  7134. if (token_count > parsed_token_count)
  7135. return false;
  7136. iterator_type_ptr itr = token_list;
  7137. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7138. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false;
  7139. return true;
  7140. }
  7141. template <typename InputIterator, typename T>
  7142. inline bool parse(const InputIterator begin,
  7143. const InputIterator end,
  7144. const std::string& delimiters,
  7145. T& t)
  7146. {
  7147. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7148. details::convert_type_assert<itr_type>();
  7149. static const std::size_t token_count = 1;
  7150. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7151. typedef iterator_type* iterator_type_ptr;
  7152. iterator_type token_list[token_count];
  7153. const std::size_t parsed_token_count = split_n(delimiters,
  7154. begin,end,
  7155. token_count,
  7156. token_list,
  7157. split_options::compress_delimiters);
  7158. if (token_count > parsed_token_count)
  7159. return false;
  7160. iterator_type_ptr itr = token_list;
  7161. return string_to_type_converter((*itr).first,(*itr).second,t);
  7162. }
  7163. template <typename InputIterator,
  7164. typename T,
  7165. typename Allocator,
  7166. template <typename,typename> class Sequence>
  7167. inline std::size_t parse(const InputIterator begin,
  7168. const InputIterator end,
  7169. const std::string& delimiters,
  7170. Sequence<T,Allocator>& sequence,
  7171. const split_options::type& split_option = split_options::compress_delimiters)
  7172. {
  7173. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7174. details::convert_type_assert<itr_type>();
  7175. if (1 == delimiters.size())
  7176. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7177. begin,end,
  7178. range_to_type_back_inserter(sequence),
  7179. split_option);
  7180. else
  7181. return split(multiple_char_delimiter_predicate(delimiters),
  7182. begin, end,
  7183. range_to_type_back_inserter(sequence),
  7184. split_option);
  7185. }
  7186. template <typename InputIterator,
  7187. typename T,
  7188. typename Comparator,
  7189. typename Allocator>
  7190. inline std::size_t parse(const InputIterator begin,
  7191. const InputIterator end,
  7192. const std::string& delimiters,
  7193. std::set<T,Comparator,Allocator>& set,
  7194. const split_options::type& split_option = split_options::compress_delimiters)
  7195. {
  7196. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7197. details::convert_type_assert<itr_type>();
  7198. if (1 == delimiters.size())
  7199. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7200. begin,end,
  7201. range_to_type_inserter(set),
  7202. split_option);
  7203. else
  7204. return split(multiple_char_delimiter_predicate(delimiters),
  7205. begin,end,
  7206. range_to_type_inserter(set),
  7207. split_option);
  7208. }
  7209. template <typename InputIterator,
  7210. typename T,
  7211. typename Comparator,
  7212. typename Allocator>
  7213. inline std::size_t parse(const InputIterator begin,
  7214. const InputIterator end,
  7215. const std::string& delimiters,
  7216. std::multiset<T,Comparator,Allocator>& multiset,
  7217. const split_options::type& split_option = split_options::compress_delimiters)
  7218. {
  7219. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7220. details::convert_type_assert<itr_type>();
  7221. if (1 == delimiters.size())
  7222. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7223. begin,end,
  7224. range_to_type_inserter(multiset),
  7225. split_option);
  7226. else
  7227. return split(multiple_char_delimiter_predicate(delimiters),
  7228. begin,end,
  7229. range_to_type_inserter(multiset),
  7230. split_option);
  7231. }
  7232. template <typename InputIterator,
  7233. typename T,
  7234. typename Container>
  7235. inline std::size_t parse(const InputIterator begin,
  7236. const InputIterator end,
  7237. const std::string& delimiters,
  7238. std::queue<T,Container>& queue,
  7239. const split_options::type& split_option = split_options::compress_delimiters)
  7240. {
  7241. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7242. details::convert_type_assert<itr_type>();
  7243. if (1 == delimiters.size())
  7244. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7245. begin,end,
  7246. range_to_type_push_inserter(queue),
  7247. split_option);
  7248. else
  7249. return split(multiple_char_delimiter_predicate(delimiters),
  7250. begin,end,
  7251. range_to_type_push_inserter(queue),
  7252. split_option);
  7253. }
  7254. template <typename InputIterator,
  7255. typename T,
  7256. typename Container>
  7257. inline std::size_t parse(const InputIterator begin,
  7258. const InputIterator end,
  7259. const std::string& delimiters,
  7260. std::stack<T,Container>& stack,
  7261. const split_options::type& split_option = split_options::compress_delimiters)
  7262. {
  7263. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7264. details::convert_type_assert<itr_type>();
  7265. if (1 == delimiters.size())
  7266. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7267. begin,end,
  7268. range_to_type_push_inserter(stack),
  7269. split_option);
  7270. else
  7271. return split(multiple_char_delimiter_predicate(delimiters),
  7272. begin, end,
  7273. range_to_type_push_inserter(stack),
  7274. split_option);
  7275. }
  7276. template <typename InputIterator,
  7277. typename T,
  7278. typename Container,
  7279. typename Comparator>
  7280. inline std::size_t parse(const InputIterator begin,
  7281. const InputIterator end,
  7282. const std::string& delimiters,
  7283. std::priority_queue<T,Container,Comparator>& priority_queue,
  7284. const split_options::type& split_option = split_options::compress_delimiters)
  7285. {
  7286. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7287. details::convert_type_assert<itr_type>();
  7288. if (1 == delimiters.size())
  7289. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7290. begin,end,
  7291. range_to_type_push_inserter(priority_queue),
  7292. split_option);
  7293. else
  7294. return split(multiple_char_delimiter_predicate(delimiters),
  7295. begin,end,
  7296. range_to_type_push_inserter(priority_queue),
  7297. split_option);
  7298. }
  7299. template <typename InputIterator,
  7300. typename T,
  7301. typename Allocator,
  7302. template <typename,typename> class Sequence>
  7303. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7304. const std::string& delimiters,
  7305. Sequence<T,Allocator>& sequence,
  7306. const split_options::type& split_option = split_options::compress_delimiters)
  7307. {
  7308. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7309. details::convert_type_assert<itr_type>();
  7310. if (1 == delimiters.size())
  7311. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7312. range.first,range.second,
  7313. range_to_type_back_inserter(sequence),
  7314. split_option);
  7315. else
  7316. return split(multiple_char_delimiter_predicate(delimiters),
  7317. range.first,range.second,
  7318. range_to_type_back_inserter(sequence),
  7319. split_option);
  7320. }
  7321. template <typename InputIterator,
  7322. typename T,
  7323. typename Comparator,
  7324. typename Allocator>
  7325. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7326. const std::string& delimiters,
  7327. std::set<T,Comparator,Allocator>& set,
  7328. const split_options::type& split_option = split_options::compress_delimiters)
  7329. {
  7330. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7331. details::convert_type_assert<itr_type>();
  7332. if (1 == delimiters.size())
  7333. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7334. range.first,range.second,
  7335. range_to_type_inserter(set),
  7336. split_option);
  7337. else
  7338. return split(multiple_char_delimiter_predicate(delimiters),
  7339. range.first,range.second,
  7340. range_to_type_inserter(set),
  7341. split_option);
  7342. }
  7343. template <typename InputIterator,
  7344. typename T,
  7345. typename Comparator,
  7346. typename Allocator>
  7347. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7348. const std::string& delimiters,
  7349. std::multiset<T,Comparator,Allocator>& multiset,
  7350. const split_options::type& split_option = split_options::compress_delimiters)
  7351. {
  7352. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7353. details::convert_type_assert<itr_type>();
  7354. if (1 == delimiters.size())
  7355. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7356. range.first,range.second,
  7357. range_to_type_inserter(multiset),
  7358. split_option);
  7359. else
  7360. return split(multiple_char_delimiter_predicate(delimiters),
  7361. range.first,range.second,
  7362. range_to_type_inserter(multiset),
  7363. split_option);
  7364. }
  7365. template <typename InputIterator,
  7366. typename T,
  7367. typename Container>
  7368. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7369. const std::string& delimiters,
  7370. std::queue<T,Container>& queue,
  7371. const split_options::type& split_option = split_options::compress_delimiters)
  7372. {
  7373. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7374. details::convert_type_assert<itr_type>();
  7375. if (1 == delimiters.size())
  7376. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7377. range.first,range.second,
  7378. range_to_type_push_inserter(queue),
  7379. split_option);
  7380. else
  7381. return split(multiple_char_delimiter_predicate(delimiters),
  7382. range.first,range.second,
  7383. range_to_type_push_inserter(queue),
  7384. split_option);
  7385. }
  7386. template <typename InputIterator,
  7387. typename T,
  7388. typename Container>
  7389. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7390. const std::string& delimiters,
  7391. std::stack<T,Container>& stack,
  7392. const split_options::type& split_option = split_options::compress_delimiters)
  7393. {
  7394. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7395. details::convert_type_assert<itr_type>();
  7396. if (1 == delimiters.size())
  7397. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7398. range.first,range.second,
  7399. range_to_type_push_inserter(stack),
  7400. split_option);
  7401. else
  7402. return split(multiple_char_delimiter_predicate(delimiters),
  7403. range.first,range.second,
  7404. range_to_type_push_inserter(stack),
  7405. split_option);
  7406. }
  7407. template <typename InputIterator,
  7408. typename T,
  7409. typename Container,
  7410. typename Comparator>
  7411. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7412. const std::string& delimiters,
  7413. std::priority_queue<T,Container,Comparator>& priority_queue,
  7414. const split_options::type& split_option = split_options::compress_delimiters)
  7415. {
  7416. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7417. details::convert_type_assert<itr_type>();
  7418. if (1 == delimiters.size())
  7419. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7420. range.first,range.second,
  7421. range_to_type_push_inserter(priority_queue),
  7422. split_option);
  7423. else
  7424. return split(multiple_char_delimiter_predicate(delimiters),
  7425. range.first,range.second,
  7426. range_to_type_push_inserter(priority_queue),
  7427. split_option);
  7428. }
  7429. namespace details
  7430. {
  7431. class container_adder
  7432. {
  7433. private:
  7434. class container_adder_base
  7435. {
  7436. public:
  7437. typedef const char* itr_type;
  7438. virtual ~container_adder_base(){}
  7439. template <typename InputIterator>
  7440. inline bool add(const InputIterator begin, const InputIterator end) const
  7441. {
  7442. return add_impl(begin,end);
  7443. }
  7444. template <typename InputIterator>
  7445. inline bool add(const std::pair<InputIterator,InputIterator>& range) const
  7446. {
  7447. return add(range.first,range.second);
  7448. }
  7449. protected:
  7450. virtual bool add_impl(const itr_type begin, const itr_type end) const = 0;
  7451. };
  7452. template <typename T,
  7453. typename Allocator,
  7454. template <typename,typename> class Sequence>
  7455. class sequence_adder_impl : public container_adder_base
  7456. {
  7457. public:
  7458. typedef Sequence<T,Allocator> sequence_t;
  7459. sequence_adder_impl(sequence_t& seq)
  7460. : sequence_(seq)
  7461. {}
  7462. protected:
  7463. bool add_impl(const itr_type begin, const itr_type end) const
  7464. {
  7465. T t;
  7466. if (!string_to_type_converter(begin,end,t)) return false;
  7467. sequence_.push_back(t);
  7468. return true;
  7469. }
  7470. private:
  7471. sequence_adder_impl operator=(const sequence_adder_impl&);
  7472. sequence_t& sequence_;
  7473. };
  7474. template <typename T,
  7475. typename Comparator,
  7476. typename Allocator,
  7477. template <typename,typename,typename> class Set>
  7478. class set_adder_impl : public container_adder_base
  7479. {
  7480. public:
  7481. set_adder_impl(Set<T,Comparator,Allocator>& set)
  7482. : set_(set)
  7483. {}
  7484. bool add_impl(const itr_type begin, const itr_type end) const
  7485. {
  7486. T t;
  7487. if (!string_to_type_converter(begin,end,t)) return false;
  7488. set_.insert(t);
  7489. return true;
  7490. }
  7491. private:
  7492. set_adder_impl operator=(const set_adder_impl&);
  7493. Set<T,Comparator,Allocator>& set_;
  7494. };
  7495. template <typename T,
  7496. typename Container,
  7497. typename Comparator>
  7498. class pq_adder_impl : public container_adder_base
  7499. {
  7500. public:
  7501. pq_adder_impl(std::priority_queue<T,Container,Comparator>& pq)
  7502. : pq_(pq)
  7503. {}
  7504. bool add_impl(const itr_type begin, const itr_type end) const
  7505. {
  7506. T t;
  7507. if (!string_to_type_converter(begin,end,t)) return false;
  7508. pq_.push(t);
  7509. return true;
  7510. }
  7511. private:
  7512. pq_adder_impl operator=(const pq_adder_impl&);
  7513. std::priority_queue<T,Container,Comparator>& pq_;
  7514. };
  7515. template <typename T,
  7516. typename Container,
  7517. template <typename,typename> class SContainer>
  7518. class stack_queue_adder_impl : public container_adder_base
  7519. {
  7520. public:
  7521. stack_queue_adder_impl(SContainer<T,Container>& container)
  7522. : container_(container)
  7523. {}
  7524. bool add_impl(const itr_type begin, const itr_type end) const
  7525. {
  7526. T t;
  7527. if (!string_to_type_converter(begin,end,t)) return false;
  7528. container_.push(t);
  7529. return true;
  7530. }
  7531. private:
  7532. stack_queue_adder_impl operator=(const stack_queue_adder_impl&);
  7533. SContainer<T,Container>& container_;
  7534. };
  7535. public:
  7536. template <typename T, typename Allocator>
  7537. container_adder(std::vector<T,Allocator>& vec)
  7538. : container_adder_base_(new(buffer)sequence_adder_impl<T,Allocator,std::vector>(vec))
  7539. {}
  7540. template <typename T, typename Allocator>
  7541. container_adder(std::deque<T,Allocator>& deq)
  7542. : container_adder_base_(new(buffer)sequence_adder_impl<T,Allocator,std::deque>(deq))
  7543. {}
  7544. template <typename T, typename Allocator>
  7545. container_adder(std::list<T,Allocator>& list)
  7546. : container_adder_base_(new(buffer)sequence_adder_impl<T,Allocator,std::list>(list))
  7547. {}
  7548. template <typename T, typename Comparator, typename Allocator>
  7549. container_adder(std::set<T,Comparator,Allocator>& set)
  7550. : container_adder_base_(new(buffer)set_adder_impl<T,Comparator,Allocator,std::set>(set))
  7551. {}
  7552. template <typename T, typename Comparator, typename Allocator>
  7553. container_adder(std::multiset<T,Comparator,Allocator>& multiset)
  7554. : container_adder_base_(new(buffer)set_adder_impl<T,Comparator,Allocator,std::multiset>(multiset))
  7555. {}
  7556. template <typename T, typename Container, typename Comparator>
  7557. container_adder(std::priority_queue<T,Container,Comparator>& pq)
  7558. : container_adder_base_(new(buffer)pq_adder_impl<T,Container,Comparator>(pq))
  7559. {}
  7560. template <typename T, typename Container>
  7561. container_adder(std::queue<T,Container>& queue)
  7562. : container_adder_base_(new(buffer)stack_queue_adder_impl<T,Container,std::queue>(queue))
  7563. {}
  7564. template <typename T, typename Container>
  7565. container_adder(std::stack<T,Container>& stack)
  7566. : container_adder_base_(new(buffer)stack_queue_adder_impl<T,Container,std::stack>(stack))
  7567. {}
  7568. template <typename InputIterator>
  7569. inline bool add(InputIterator begin, InputIterator end) const
  7570. {
  7571. return container_adder_base_->add(begin,end);
  7572. }
  7573. template <typename InputIterator>
  7574. inline bool add(std::pair<InputIterator,InputIterator>& range) const
  7575. {
  7576. return add(range.first,range.second);
  7577. }
  7578. template <typename InputIterator>
  7579. inline bool operator()(const InputIterator begin, const InputIterator end)
  7580. {
  7581. InputIterator itr = begin;
  7582. while (end != itr)
  7583. {
  7584. if (!add(*itr)) return false;
  7585. ++itr;
  7586. }
  7587. return true;
  7588. }
  7589. private:
  7590. mutable container_adder_base* container_adder_base_;
  7591. unsigned char buffer[64];
  7592. };
  7593. template <typename T,typename is_stl_container_result>
  7594. struct ca_type { typedef T& type; };
  7595. template <typename T>
  7596. struct ca_type <T,details::yes_t> { typedef details::container_adder type; };
  7597. }
  7598. template <typename InputIterator,
  7599. typename T1, typename T2, typename T3,
  7600. typename T4, typename T5, typename T6,
  7601. typename T7, typename T8, typename T9,
  7602. typename T10, typename T11>
  7603. inline bool parse(const InputIterator begin, const InputIterator end,
  7604. const std::string& delimiters,
  7605. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7,
  7606. T8& t8, T9& t9, T10& t10, T11& t11,
  7607. details::container_adder ca)
  7608. {
  7609. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7610. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7611. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7612. details::convert_type_assert<itr_type>();
  7613. std::deque<iterator_type> token_list;
  7614. if (1 == delimiters.size())
  7615. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7616. begin,end,
  7617. std::back_inserter(token_list),
  7618. split_options::compress_delimiters);
  7619. else
  7620. split(multiple_char_delimiter_predicate(delimiters),
  7621. begin,end,
  7622. std::back_inserter(token_list),
  7623. split_options::compress_delimiters);
  7624. if (token_list.size() < 12) return false;
  7625. iterator_type_ptr itr = token_list.begin();
  7626. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  7627. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  7628. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  7629. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  7630. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  7631. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  7632. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  7633. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  7634. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  7635. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr;
  7636. if (!string_to_type_converter((*itr).first,(*itr).second,t11)) return false; ++itr;
  7637. return ca(itr,token_list.end());
  7638. }
  7639. template <typename InputIterator,
  7640. typename T1, typename T2, typename T3,
  7641. typename T4, typename T5, typename T6,
  7642. typename T7, typename T8, typename T9,
  7643. typename T10>
  7644. inline bool parse(const InputIterator begin, const InputIterator end,
  7645. const std::string& delimiters,
  7646. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9, T10& t10,
  7647. details::container_adder ca)
  7648. {
  7649. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7650. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7651. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7652. details::convert_type_assert<itr_type>();
  7653. std::deque<iterator_type> token_list;
  7654. if (1 == delimiters.size())
  7655. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7656. begin,end,
  7657. std::back_inserter(token_list),
  7658. split_options::compress_delimiters);
  7659. else
  7660. split(multiple_char_delimiter_predicate(delimiters),
  7661. begin,end,
  7662. std::back_inserter(token_list),
  7663. split_options::compress_delimiters);
  7664. if (token_list.size() < 11) return false;
  7665. iterator_type_ptr itr = token_list.begin();
  7666. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  7667. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  7668. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  7669. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  7670. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  7671. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  7672. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  7673. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  7674. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  7675. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr;
  7676. return ca(itr,token_list.end());
  7677. }
  7678. template <typename InputIterator,
  7679. typename T1, typename T2, typename T3,
  7680. typename T4, typename T5, typename T6,
  7681. typename T7, typename T8, typename T9>
  7682. inline bool parse(const InputIterator begin, const InputIterator end,
  7683. const std::string& delimiters,
  7684. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9,
  7685. details::container_adder ca)
  7686. {
  7687. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7688. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7689. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7690. details::convert_type_assert<itr_type>();
  7691. std::deque<iterator_type> token_list;
  7692. if (1 == delimiters.size())
  7693. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7694. begin,end,
  7695. std::back_inserter(token_list),
  7696. split_options::compress_delimiters);
  7697. else
  7698. split(multiple_char_delimiter_predicate(delimiters),
  7699. begin,end,
  7700. std::back_inserter(token_list),
  7701. split_options::compress_delimiters);
  7702. if (token_list.size() < 10) return false;
  7703. iterator_type_ptr itr = token_list.begin();
  7704. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7705. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7706. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7707. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7708. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7709. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7710. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  7711. if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false; ++itr;
  7712. if (!string_to_type_converter((*itr).first,(*itr).second,t9)) return false; ++itr;
  7713. return ca(itr,token_list.end());
  7714. }
  7715. template <typename InputIterator,
  7716. typename T1, typename T2, typename T3,
  7717. typename T4, typename T5, typename T6,
  7718. typename T7, typename T8>
  7719. inline bool parse(const InputIterator begin, const InputIterator end,
  7720. const std::string& delimiters,
  7721. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8,
  7722. details::container_adder ca)
  7723. {
  7724. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7725. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7726. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7727. details::convert_type_assert<itr_type>();
  7728. std::deque<iterator_type> token_list;
  7729. if (1 == delimiters.size())
  7730. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7731. begin,end,
  7732. std::back_inserter(token_list),
  7733. split_options::compress_delimiters);
  7734. else
  7735. split(multiple_char_delimiter_predicate(delimiters),
  7736. begin,end,
  7737. std::back_inserter(token_list),
  7738. split_options::compress_delimiters);
  7739. if (token_list.size() < 9) return false;
  7740. iterator_type_ptr itr = token_list.begin();
  7741. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7742. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7743. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7744. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7745. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7746. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7747. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  7748. if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false; ++itr;
  7749. return ca(itr,token_list.end());
  7750. }
  7751. template <typename InputIterator,
  7752. typename T1, typename T2, typename T3,
  7753. typename T4, typename T5, typename T6, typename T7>
  7754. inline bool parse(const InputIterator begin, const InputIterator end,
  7755. const std::string& delimiters,
  7756. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7,
  7757. details::container_adder ca)
  7758. {
  7759. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7760. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7761. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7762. details::convert_type_assert<itr_type>();
  7763. std::deque<iterator_type> token_list;
  7764. if (1 == delimiters.size())
  7765. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7766. begin,end,
  7767. std::back_inserter(token_list),
  7768. split_options::compress_delimiters);
  7769. else
  7770. split(multiple_char_delimiter_predicate(delimiters),
  7771. begin,end,
  7772. std::back_inserter(token_list),
  7773. split_options::compress_delimiters);
  7774. if (token_list.size() < 8) return false;
  7775. iterator_type_ptr itr = token_list.begin();
  7776. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7777. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7778. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7779. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7780. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7781. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7782. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  7783. return ca(itr,token_list.end());
  7784. }
  7785. template <typename InputIterator,
  7786. typename T1, typename T2, typename T3,
  7787. typename T4, typename T5, typename T6>
  7788. inline bool parse(const InputIterator begin, const InputIterator end,
  7789. const std::string& delimiters,
  7790. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  7791. details::container_adder ca)
  7792. {
  7793. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7794. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7795. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7796. details::convert_type_assert<itr_type>();
  7797. std::deque<iterator_type> token_list;
  7798. if (1 == delimiters.size())
  7799. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7800. begin,end,
  7801. std::back_inserter(token_list),
  7802. split_options::compress_delimiters);
  7803. else
  7804. split(multiple_char_delimiter_predicate(delimiters),
  7805. begin,end,
  7806. std::back_inserter(token_list),
  7807. split_options::compress_delimiters);
  7808. if (token_list.size() < 7) return false;
  7809. iterator_type_ptr itr = token_list.begin();
  7810. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7811. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7812. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7813. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7814. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7815. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7816. return ca(itr,token_list.end());
  7817. }
  7818. template <typename InputIterator,
  7819. typename T1, typename T2, typename T3,
  7820. typename T4, typename T5>
  7821. inline bool parse(const InputIterator begin, const InputIterator end,
  7822. const std::string& delimiters,
  7823. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  7824. details::container_adder ca)
  7825. {
  7826. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7827. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7828. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7829. details::convert_type_assert<itr_type>();
  7830. std::deque<iterator_type> token_list;
  7831. if (1 == delimiters.size())
  7832. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7833. begin,end,
  7834. std::back_inserter(token_list),
  7835. split_options::compress_delimiters);
  7836. else
  7837. split(multiple_char_delimiter_predicate(delimiters),
  7838. begin,end,
  7839. std::back_inserter(token_list),
  7840. split_options::compress_delimiters);
  7841. if (token_list.size() < 6) return false;
  7842. iterator_type_ptr itr = token_list.begin();
  7843. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7844. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7845. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7846. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7847. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7848. return ca(itr,token_list.end());
  7849. }
  7850. template <typename InputIterator,
  7851. typename T1, typename T2, typename T3, typename T4>
  7852. inline bool parse(const InputIterator begin, const InputIterator end,
  7853. const std::string& delimiters,
  7854. T1& t1, T2& t2, T3& t3, T4& t4,
  7855. details::container_adder ca)
  7856. {
  7857. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7858. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7859. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7860. details::convert_type_assert<itr_type>();
  7861. std::deque<iterator_type> token_list;
  7862. if (1 == delimiters.size())
  7863. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7864. begin,end,
  7865. std::back_inserter(token_list),
  7866. split_options::compress_delimiters);
  7867. else
  7868. split(multiple_char_delimiter_predicate(delimiters),
  7869. begin,end,
  7870. std::back_inserter(token_list),
  7871. split_options::compress_delimiters);
  7872. if (token_list.size() < 5) return false;
  7873. iterator_type_ptr itr = token_list.begin();
  7874. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7875. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7876. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7877. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7878. return ca(itr,token_list.end());
  7879. }
  7880. template <typename InputIterator,
  7881. typename T1, typename T2, typename T3>
  7882. inline bool parse(const InputIterator begin, const InputIterator end,
  7883. const std::string& delimiters,
  7884. T1& t1, T2& t2, T3& t3,
  7885. details::container_adder ca)
  7886. {
  7887. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7888. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7889. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7890. details::convert_type_assert<itr_type>();
  7891. std::deque<iterator_type> token_list;
  7892. if (1 == delimiters.size())
  7893. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7894. begin,end,
  7895. std::back_inserter(token_list),
  7896. split_options::compress_delimiters);
  7897. else
  7898. split(multiple_char_delimiter_predicate(delimiters),
  7899. begin,end,
  7900. std::back_inserter(token_list),
  7901. split_options::compress_delimiters);
  7902. if (token_list.size() < 4) return false;
  7903. iterator_type_ptr itr = token_list.begin();
  7904. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7905. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7906. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7907. return ca(itr,token_list.end());
  7908. }
  7909. template <typename InputIterator,
  7910. typename T1, typename T2>
  7911. inline bool parse(const InputIterator begin, const InputIterator end,
  7912. const std::string& delimiters,
  7913. T1& t1, T2& t2,
  7914. details::container_adder ca)
  7915. {
  7916. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7917. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7918. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7919. details::convert_type_assert<itr_type>();
  7920. std::deque<iterator_type> token_list;
  7921. if (1 == delimiters.size())
  7922. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7923. begin,end,
  7924. std::back_inserter(token_list),
  7925. split_options::compress_delimiters);
  7926. else
  7927. split(multiple_char_delimiter_predicate(delimiters),
  7928. begin,end,
  7929. std::back_inserter(token_list),
  7930. split_options::compress_delimiters);
  7931. if (token_list.size() < 3) return false;
  7932. iterator_type_ptr itr = token_list.begin();
  7933. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7934. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7935. return ca(itr,token_list.end());
  7936. }
  7937. template <typename InputIterator, typename T1>
  7938. inline bool parse(const InputIterator begin, const InputIterator end,
  7939. const std::string& delimiters,
  7940. T1& t1,
  7941. details::container_adder ca)
  7942. {
  7943. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7944. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7945. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7946. details::convert_type_assert<itr_type>();
  7947. std::deque<iterator_type> token_list;
  7948. if (1 == delimiters.size())
  7949. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7950. begin,end,
  7951. std::back_inserter(token_list),
  7952. split_options::compress_delimiters);
  7953. else
  7954. split(multiple_char_delimiter_predicate(delimiters),
  7955. begin,end,
  7956. std::back_inserter(token_list),
  7957. split_options::compress_delimiters);
  7958. if (token_list.size() < 2) return false;
  7959. iterator_type_ptr itr = token_list.begin();
  7960. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7961. return ca(itr,token_list.end());
  7962. }
  7963. template <typename InputIterator,
  7964. typename T,
  7965. typename Allocator,
  7966. template <typename,typename> class Sequence>
  7967. inline std::size_t parse_n(const InputIterator begin,
  7968. const InputIterator end,
  7969. const std::string& delimiters,
  7970. const std::size_t& n,
  7971. Sequence<T,Allocator>& sequence,
  7972. const split_options::type& split_option = split_options::compress_delimiters)
  7973. {
  7974. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7975. const std::size_t original_size = sequence.size();
  7976. details::convert_type_assert<itr_type>();
  7977. if (1 == delimiters.size())
  7978. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7979. begin,end,
  7980. n,
  7981. range_to_type_back_inserter(sequence),
  7982. split_option);
  7983. else
  7984. split_n(multiple_char_delimiter_predicate(delimiters),
  7985. begin,end,
  7986. n,
  7987. range_to_type_back_inserter(sequence),
  7988. split_option);
  7989. return sequence.size() - original_size;
  7990. }
  7991. template <typename InputIterator,
  7992. typename T,
  7993. typename Comparator,
  7994. typename Allocator>
  7995. inline std::size_t parse_n(const InputIterator begin,
  7996. const InputIterator end,
  7997. const std::string& delimiters,
  7998. const std::size_t& n,
  7999. std::set<T,Comparator,Allocator>& set,
  8000. const split_options::type& split_option = split_options::compress_delimiters)
  8001. {
  8002. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  8003. const std::size_t original_size = set.size();
  8004. details::convert_type_assert<itr_type>();
  8005. if (1 == delimiters.size())
  8006. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  8007. begin,end,
  8008. n,
  8009. range_to_type_inserter(set),
  8010. split_option);
  8011. else
  8012. split_n(multiple_char_delimiter_predicate(delimiters),
  8013. begin,end,
  8014. n,
  8015. range_to_type_inserter(set),
  8016. split_option);
  8017. return set.size() - original_size;
  8018. }
  8019. template <typename InputIterator,
  8020. typename T,
  8021. typename Comparator,
  8022. typename Allocator>
  8023. inline std::size_t parse_n(const InputIterator begin,
  8024. const InputIterator end,
  8025. const std::string& delimiters,
  8026. const std::size_t& n,
  8027. std::multiset<T,Comparator,Allocator>& multiset,
  8028. const split_options::type& split_option = split_options::compress_delimiters)
  8029. {
  8030. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  8031. const std::size_t original_size = multiset.size();
  8032. details::convert_type_assert<itr_type>();
  8033. if (1 == delimiters.size())
  8034. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  8035. begin,end,
  8036. n,
  8037. range_to_type_inserter(multiset),
  8038. split_option);
  8039. else
  8040. split_n(multiple_char_delimiter_predicate(delimiters),
  8041. begin,end,
  8042. n,
  8043. range_to_type_inserter(multiset),
  8044. split_option);
  8045. return multiset.size() - original_size;
  8046. }
  8047. template <typename InputIterator,
  8048. typename T,
  8049. typename Container>
  8050. inline std::size_t parse_n(const InputIterator begin,
  8051. const InputIterator end,
  8052. const std::string& delimiters,
  8053. const std::size_t& n,
  8054. std::queue<T,Container>& queue,
  8055. const split_options::type& split_option = split_options::compress_delimiters)
  8056. {
  8057. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  8058. const std::size_t original_size = queue.size();
  8059. details::convert_type_assert<itr_type>();
  8060. if (1 == delimiters.size())
  8061. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  8062. begin,end,
  8063. n,
  8064. range_to_type_push_inserter(queue),
  8065. split_option);
  8066. else
  8067. split_n(multiple_char_delimiter_predicate(delimiters),
  8068. begin,end,
  8069. n,
  8070. range_to_type_push_inserter(queue),
  8071. split_option);
  8072. return queue.size() - original_size;
  8073. }
  8074. template <typename InputIterator,
  8075. typename T,
  8076. typename Container>
  8077. inline std::size_t parse_n(const InputIterator begin,
  8078. const InputIterator end,
  8079. const std::string& delimiters,
  8080. const std::size_t& n,
  8081. std::stack<T,Container>& stack,
  8082. const split_options::type& split_option = split_options::compress_delimiters)
  8083. {
  8084. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  8085. const std::size_t original_size = stack.size();
  8086. details::convert_type_assert<itr_type>();
  8087. if (1 == delimiters.size())
  8088. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  8089. begin,end,
  8090. n,
  8091. range_to_type_push_inserter(stack),
  8092. split_option);
  8093. else
  8094. split_n(multiple_char_delimiter_predicate(delimiters),
  8095. begin,end,
  8096. n,
  8097. range_to_type_push_inserter(stack),
  8098. split_option);
  8099. return stack.size() - original_size;
  8100. }
  8101. template <typename InputIterator,
  8102. typename T,
  8103. typename Container,
  8104. typename Comparator>
  8105. inline std::size_t parse_n(const InputIterator begin,
  8106. const InputIterator end,
  8107. const std::string& delimiters,
  8108. const std::size_t& n,
  8109. std::priority_queue<T,Container,Comparator>& priority_queue,
  8110. const split_options::type& split_option = split_options::compress_delimiters)
  8111. {
  8112. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  8113. const std::size_t original_size = priority_queue.size();
  8114. details::convert_type_assert<itr_type>();
  8115. if (1 == delimiters.size())
  8116. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  8117. begin,end,
  8118. n,
  8119. range_to_type_push_inserter(priority_queue),
  8120. split_option);
  8121. else
  8122. split_n(multiple_char_delimiter_predicate(delimiters),
  8123. begin,end,
  8124. n,
  8125. range_to_type_push_inserter(priority_queue),
  8126. split_option);
  8127. return priority_queue.size() - original_size;
  8128. }
  8129. template <typename InputIterator, typename T>
  8130. inline std::size_t parse_n(const InputIterator begin,
  8131. const InputIterator end,
  8132. const std::string& delimiters,
  8133. const std::size_t& n,
  8134. T* out,
  8135. const split_options::type& split_option = split_options::compress_delimiters)
  8136. {
  8137. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  8138. std::size_t insert_count = 0;
  8139. details::convert_type_assert<itr_type>();
  8140. if (1 == delimiters.size())
  8141. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  8142. begin,end,
  8143. n,
  8144. range_to_ptr_type(out,insert_count),
  8145. split_option);
  8146. else
  8147. split_n(multiple_char_delimiter_predicate(delimiters),
  8148. begin,end,
  8149. n,
  8150. range_to_ptr_type(out,insert_count),
  8151. split_option);
  8152. return insert_count;
  8153. }
  8154. template <typename InputIterator,
  8155. typename T,
  8156. typename Allocator,
  8157. template <typename,typename> class Sequence>
  8158. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8159. const std::string& delimiters,
  8160. const std::size_t& n,
  8161. Sequence<T,Allocator>& sequence,
  8162. const split_options::type& split_option = split_options::compress_delimiters)
  8163. {
  8164. return parse(range.first,range.second,delimiters,n,sequence,split_option);
  8165. }
  8166. template <typename InputIterator,
  8167. typename T,
  8168. typename Comparator,
  8169. typename Allocator>
  8170. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8171. const std::string& delimiters,
  8172. const std::size_t& n,
  8173. std::set<T,Comparator,Allocator>& set,
  8174. const split_options::type& split_option = split_options::compress_delimiters)
  8175. {
  8176. return parse(range.first,range.second,delimiters,n,set,split_option);
  8177. }
  8178. template <typename InputIterator,
  8179. typename T,
  8180. typename Comparator,
  8181. typename Allocator>
  8182. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8183. const std::string& delimiters,
  8184. const std::size_t& n,
  8185. std::multiset<T,Comparator,Allocator>& multiset,
  8186. const split_options::type& split_option = split_options::compress_delimiters)
  8187. {
  8188. return parse(range.first,range.second,delimiters,n,multiset,split_option);
  8189. }
  8190. template <typename InputIterator,
  8191. typename T,
  8192. typename Container>
  8193. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8194. const std::string& delimiters,
  8195. const std::size_t& n,
  8196. std::queue<T,Container>& queue,
  8197. const split_options::type& split_option = split_options::compress_delimiters)
  8198. {
  8199. return parse(range.first,range.second,delimiters,n,queue,split_option);
  8200. }
  8201. template <typename InputIterator,
  8202. typename T,
  8203. typename Container>
  8204. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8205. const std::string& delimiters,
  8206. const std::size_t& n,
  8207. std::stack<T,Container>& stack,
  8208. const split_options::type& split_option = split_options::compress_delimiters)
  8209. {
  8210. return parse(range.first,range.second,delimiters,n,stack,split_option);
  8211. }
  8212. template <typename InputIterator,
  8213. typename T,
  8214. typename Container,
  8215. typename Comparator>
  8216. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8217. const std::string& delimiters,
  8218. const std::size_t& n,
  8219. std::priority_queue<T,Container,Comparator>& priority_queue,
  8220. const split_options::type& split_option = split_options::compress_delimiters)
  8221. {
  8222. return parse(range.first,range.second,delimiters,n,priority_queue,split_option);
  8223. }
  8224. template <typename T1, typename T2, typename T3, typename T4,
  8225. typename T5, typename T6, typename T7, typename T8,
  8226. typename T9, typename T10, typename T11, typename T12>
  8227. inline bool parse(const std::string& data,
  8228. const std::string& delimiters,
  8229. T1& t1, T2& t2, T3& t3, T4& t4,
  8230. T5& t5, T6& t6, T7& t7, T8& t8,
  8231. T9& t9, T10& t10, T11& t11, T12& t12)
  8232. {
  8233. return parse(data.data(),
  8234. data.data() + data.size(),
  8235. delimiters,
  8236. t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,
  8237. typename details::ca_type<T12, typename details::is_stl_container<T12>::result_t>::type(t12));
  8238. }
  8239. template <typename T1, typename T2, typename T3, typename T4,
  8240. typename T5, typename T6, typename T7, typename T8,
  8241. typename T9, typename T10, typename T11>
  8242. inline bool parse(const std::string& data,
  8243. const std::string& delimiters,
  8244. T1& t1, T2& t2, T3& t3, T4& t4,
  8245. T5& t5, T6& t6, T7& t7, T8& t8,
  8246. T9& t9, T10& t10, T11& t11)
  8247. {
  8248. return parse(data.data(),
  8249. data.data() + data.size(),
  8250. delimiters,
  8251. t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,
  8252. typename details::ca_type<T11, typename details::is_stl_container<T11>::result_t>::type(t11));
  8253. }
  8254. template <typename T1, typename T2, typename T3, typename T4,
  8255. typename T5, typename T6, typename T7, typename T8,
  8256. typename T9, typename T10>
  8257. inline bool parse(const std::string& data,
  8258. const std::string& delimiters,
  8259. T1& t1, T2& t2, T3& t3, T4& t4,
  8260. T5& t5, T6& t6, T7& t7, T8& t8,
  8261. T9& t9, T10& t10)
  8262. {
  8263. return parse(data.data(),
  8264. data.data() + data.size(),
  8265. delimiters,
  8266. t1,t2,t3,t4,t5,t6,t7,t8,t9,
  8267. typename details::ca_type<T10, typename details::is_stl_container<T10>::result_t>::type(t10));
  8268. }
  8269. template <typename T1, typename T2, typename T3, typename T4,
  8270. typename T5, typename T6, typename T7, typename T8,
  8271. typename T9>
  8272. inline bool parse(const std::string& data,
  8273. const std::string& delimiters,
  8274. T1& t1, T2& t2, T3& t3, T4& t4,
  8275. T5& t5, T6& t6, T7& t7, T8& t8,
  8276. T9& t9)
  8277. {
  8278. return parse(data.data(),
  8279. data.data() + data.size(),
  8280. delimiters,
  8281. t1,t2,t3,t4,t5,t6,t7,t8,
  8282. typename details::ca_type<T9, typename details::is_stl_container<T9>::result_t>::type(t9));
  8283. }
  8284. template <typename T1, typename T2, typename T3, typename T4,
  8285. typename T5, typename T6, typename T7, typename T8>
  8286. inline bool parse(const std::string& data,
  8287. const std::string& delimiters,
  8288. T1& t1, T2& t2, T3& t3, T4& t4,
  8289. T5& t5, T6& t6, T7& t7, T8& t8)
  8290. {
  8291. return parse(data.data(),
  8292. data.data() + data.size(),
  8293. delimiters,
  8294. t1,t2,t3,t4,t5,t6,t7,
  8295. typename details::ca_type<T8, typename details::is_stl_container<T8>::result_t>::type(t8));
  8296. }
  8297. template <typename T1, typename T2, typename T3, typename T4,
  8298. typename T5, typename T6, typename T7>
  8299. inline bool parse(const std::string& data,
  8300. const std::string& delimiters,
  8301. T1& t1, T2& t2, T3& t3, T4& t4,
  8302. T5& t5, T6& t6, T7& t7)
  8303. {
  8304. return parse(data.data(),
  8305. data.data() + data.size(),
  8306. delimiters,
  8307. t1,t2,t3,t4,t5,t6,
  8308. typename details::ca_type<T7, typename details::is_stl_container<T7>::result_t>::type(t7));
  8309. }
  8310. template <typename T1, typename T2, typename T3, typename T4,
  8311. typename T5, typename T6>
  8312. inline bool parse(const std::string& data,
  8313. const std::string& delimiters,
  8314. T1& t1, T2& t2, T3& t3, T4& t4,
  8315. T5& t5, T6& t6)
  8316. {
  8317. return parse(data.data(),
  8318. data.data() + data.size(),
  8319. delimiters,
  8320. t1,t2,t3,t4,t5,
  8321. typename details::ca_type<T6,typename details::is_stl_container<T6>::result_t>::type(t6));
  8322. }
  8323. template <typename T1, typename T2, typename T3, typename T4,
  8324. typename T5>
  8325. inline bool parse(const std::string& data,
  8326. const std::string& delimiters,
  8327. T1& t1, T2& t2, T3& t3, T4& t4,
  8328. T5& t5)
  8329. {
  8330. return parse(data.data(),
  8331. data.data() + data.size(),
  8332. delimiters,
  8333. t1,t2,t3,t4,
  8334. typename details::ca_type<T5, typename details::is_stl_container<T5>::result_t>::type(t5));
  8335. }
  8336. template <typename T1, typename T2, typename T3, typename T4>
  8337. inline bool parse(const std::string& data,
  8338. const std::string& delimiters,
  8339. T1& t1, T2& t2, T3& t3, T4& t4)
  8340. {
  8341. return parse(data.data(),
  8342. data.data() + data.size(),
  8343. delimiters,
  8344. t1,t2,t3,
  8345. typename details::ca_type<T4, typename details::is_stl_container<T4>::result_t>::type(t4));
  8346. }
  8347. template <typename T1, typename T2, typename T3>
  8348. inline bool parse(const std::string& data,
  8349. const std::string& delimiters,
  8350. T1& t1, T2& t2, T3& t3)
  8351. {
  8352. return parse(data.data(),
  8353. data.data() + data.size(),
  8354. delimiters,
  8355. t1,t2,
  8356. typename details::ca_type<T3, typename details::is_stl_container<T3>::result_t>::type(t3));
  8357. }
  8358. template <typename T1, typename T2>
  8359. inline bool parse(const std::string& data,
  8360. const std::string& delimiters,
  8361. T1& t1, T2& t2)
  8362. {
  8363. return parse(data.data(),
  8364. data.data() + data.size(),
  8365. delimiters,
  8366. t1,
  8367. typename details::ca_type<T2, typename details::is_stl_container<T2>::result_t>::type(t2));
  8368. }
  8369. template <typename T>
  8370. inline bool parse(const std::string& data,
  8371. const std::string& delimiters,
  8372. T& t)
  8373. {
  8374. return parse(data.data(),
  8375. data.data() + data.size(),
  8376. delimiters,
  8377. typename details::ca_type<T,typename details::is_stl_container<T>::result_t>::type(t));
  8378. }
  8379. template <typename T,
  8380. typename Allocator,
  8381. template <typename,typename> class Sequence>
  8382. inline std::size_t parse(const std::string& data,
  8383. const std::string& delimiters,
  8384. Sequence<T,Allocator>& sequence,
  8385. const split_options::type& split_option = split_options::compress_delimiters)
  8386. {
  8387. return parse(data.data(),
  8388. data.data() + data.size(),
  8389. delimiters,
  8390. sequence,
  8391. split_option);
  8392. }
  8393. template <typename T,
  8394. typename Comparator,
  8395. typename Allocator>
  8396. inline std::size_t parse(const std::string& data,
  8397. const std::string& delimiters,
  8398. std::set<T,Comparator,Allocator>& set,
  8399. const split_options::type& split_option = split_options::compress_delimiters)
  8400. {
  8401. return parse(data.data(),
  8402. data.data() + data.size(),
  8403. delimiters,
  8404. set,
  8405. split_option);
  8406. }
  8407. template <typename T,
  8408. typename Comparator,
  8409. typename Allocator>
  8410. inline std::size_t parse(const std::string& data,
  8411. const std::string& delimiters,
  8412. std::multiset<T,Comparator,Allocator>& multiset,
  8413. const split_options::type& split_option = split_options::compress_delimiters)
  8414. {
  8415. return parse(data.data(),
  8416. data.data() + data.size(),
  8417. delimiters,
  8418. multiset,
  8419. split_option);
  8420. }
  8421. template <typename T,
  8422. typename Container>
  8423. inline std::size_t parse(const std::string& data,
  8424. const std::string& delimiters,
  8425. std::queue<T,Container>& queue,
  8426. const split_options::type& split_option = split_options::compress_delimiters)
  8427. {
  8428. return parse(data.data(),
  8429. data.data() + data.size(),
  8430. delimiters,
  8431. queue,
  8432. split_option);
  8433. }
  8434. template <typename T,
  8435. typename Container>
  8436. inline std::size_t parse(const std::string& data,
  8437. const std::string& delimiters,
  8438. std::stack<T,Container>& stack,
  8439. const split_options::type& split_option = split_options::compress_delimiters)
  8440. {
  8441. return parse(data.data(),
  8442. data.data() + data.size(),
  8443. delimiters,
  8444. stack,
  8445. split_option);
  8446. }
  8447. template <typename T,
  8448. typename Container,
  8449. typename Comparator>
  8450. inline std::size_t parse(const std::string& data,
  8451. const std::string& delimiters,
  8452. std::priority_queue<T,Container,Comparator>& priority_queue,
  8453. const split_options::type& split_option = split_options::compress_delimiters)
  8454. {
  8455. return parse(data.data(),
  8456. data.data() + data.size(),
  8457. delimiters,
  8458. priority_queue,
  8459. split_option);
  8460. }
  8461. template <typename T,
  8462. typename Allocator,
  8463. template <typename,typename> class Sequence>
  8464. inline std::size_t parse(const int& argc, char* argv[],
  8465. Sequence<T,Allocator>& sequence,
  8466. const bool break_on_fail = true)
  8467. {
  8468. T tmp;
  8469. for (int i = 0; i < argc; ++i)
  8470. {
  8471. if (!string_to_type_converter(std::string(argv[i]),tmp))
  8472. {
  8473. if (break_on_fail)
  8474. return i;
  8475. else
  8476. continue;
  8477. }
  8478. sequence.push_back(tmp);
  8479. }
  8480. return argc;
  8481. }
  8482. template <typename T1, typename T2, typename T3, typename T4,
  8483. typename T5, typename T6, typename T7, typename T8,
  8484. typename T9>
  8485. inline std::size_t parse(const int& argc, char* argv[],
  8486. T1& t1, T2& t2, T3& t3, T4& t4,
  8487. T5& t5, T6& t6, T7& t7, T8& t8,
  8488. T9& t9)
  8489. {
  8490. if (9 != argc) return 0;
  8491. std::size_t result = 0;
  8492. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8493. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8494. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8495. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8496. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8497. if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result;
  8498. if (!string_to_type_converter(std::string(argv[6]),t7)) return result; ++result;
  8499. if (!string_to_type_converter(std::string(argv[7]),t8)) return result; ++result;
  8500. if (!string_to_type_converter(std::string(argv[8]),t9)) return result; ++result;
  8501. return result;
  8502. }
  8503. template <typename T1, typename T2, typename T3, typename T4,
  8504. typename T5, typename T6, typename T7, typename T8>
  8505. inline std::size_t parse(const int& argc, char* argv[],
  8506. T1& t1, T2& t2, T3& t3, T4& t4,
  8507. T5& t5, T6& t6, T7& t7, T8& t8)
  8508. {
  8509. if (8 != argc) return 0;
  8510. std::size_t result = 0;
  8511. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8512. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8513. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8514. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8515. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8516. if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result;
  8517. if (!string_to_type_converter(std::string(argv[6]),t7)) return result; ++result;
  8518. if (!string_to_type_converter(std::string(argv[7]),t8)) return result; ++result;
  8519. return result;
  8520. }
  8521. template <typename T1, typename T2, typename T3, typename T4,
  8522. typename T5, typename T6, typename T7>
  8523. inline std::size_t parse(const int& argc, char* argv[],
  8524. T1& t1, T2& t2, T3& t3, T4& t4,
  8525. T5& t5, T6& t6, T7& t7)
  8526. {
  8527. if (7 != argc) return 0;
  8528. std::size_t result = 0;
  8529. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8530. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8531. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8532. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8533. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8534. if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result;
  8535. if (!string_to_type_converter(std::string(argv[6]),t7)) return result; ++result;
  8536. return result;
  8537. }
  8538. template <typename T1, typename T2, typename T3, typename T4,
  8539. typename T5, typename T6>
  8540. inline std::size_t parse(const int& argc, char* argv[],
  8541. T1& t1, T2& t2, T3& t3, T4& t4,
  8542. T5& t5, T6& t6)
  8543. {
  8544. if (6 != argc) return 0;
  8545. std::size_t result = 0;
  8546. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8547. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8548. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8549. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8550. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8551. if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result;
  8552. return result;
  8553. }
  8554. template <typename T1, typename T2, typename T3, typename T4, typename T5>
  8555. inline std::size_t parse(const int& argc, char* argv[],
  8556. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5)
  8557. {
  8558. if (5 != argc) return 0;
  8559. std::size_t result = 0;
  8560. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8561. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8562. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8563. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8564. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8565. return result;
  8566. }
  8567. template <typename T1, typename T2, typename T3, typename T4>
  8568. inline std::size_t parse(const int& argc, char* argv[],
  8569. T1& t1, T2& t2, T3& t3, T4& t4)
  8570. {
  8571. if (4 != argc) return 0;
  8572. std::size_t result = 0;
  8573. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8574. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8575. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8576. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8577. return result;
  8578. }
  8579. template <typename T1, typename T2, typename T3>
  8580. inline std::size_t parse(const int& argc, char* argv[],
  8581. T1& t1, T2& t2, T3& t3)
  8582. {
  8583. if (3 != argc) return 0;
  8584. std::size_t result = 0;
  8585. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8586. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8587. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8588. return result;
  8589. }
  8590. template <typename T1, typename T2>
  8591. inline std::size_t parse(const int& argc, char* argv[],
  8592. T1& t1, T2& t2)
  8593. {
  8594. if (2 != argc) return 0;
  8595. std::size_t result = 0;
  8596. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8597. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8598. return result;
  8599. }
  8600. template <typename T1>
  8601. inline std::size_t parse(const int& argc, char* argv[],
  8602. T1& t1)
  8603. {
  8604. if (1 != argc) return 0;
  8605. std::size_t result = 0;
  8606. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8607. return result;
  8608. }
  8609. #define strtk_parse_begin(Type) \
  8610. namespace strtk { \
  8611. bool parse(const std::string& data, const std::string& delimiters, Type& t)\
  8612. { return parse(data,delimiters \
  8613. #define strtk_parse_type(T) \
  8614. ,t.T \
  8615. #define strtk_parse_hex_type(T) \
  8616. ,t.T \
  8617. #define strtk_parse_ignore_token() \
  8618. ,ignore_token() \
  8619. #define strtk_parse_end() \
  8620. );}} \
  8621. template <typename T,
  8622. typename Allocator,
  8623. template <typename,typename> class Sequence>
  8624. inline std::size_t parse_n(const std::string& data,
  8625. const std::string& delimiters,
  8626. const std::size_t& n,
  8627. Sequence<T,Allocator>& sequence,
  8628. const split_options::type& split_option = split_options::compress_delimiters)
  8629. {
  8630. return parse_n(data.data(),
  8631. data.data() + data.size(),
  8632. delimiters,
  8633. n,
  8634. sequence,
  8635. split_option);
  8636. }
  8637. template <typename T,
  8638. typename Comparator,
  8639. typename Allocator>
  8640. inline std::size_t parse_n(const std::string& data,
  8641. const std::string& delimiters,
  8642. const std::size_t& n,
  8643. std::set<T,Comparator,Allocator>& set,
  8644. const split_options::type& split_option = split_options::compress_delimiters)
  8645. {
  8646. return parse_n(data.data(),
  8647. data.data() + data.size(),
  8648. delimiters,
  8649. n,
  8650. set,
  8651. split_option);
  8652. }
  8653. template <typename T,
  8654. typename Comparator,
  8655. typename Allocator>
  8656. inline std::size_t parse_n(const std::string& data,
  8657. const std::string& delimiters,
  8658. const std::size_t& n,
  8659. std::multiset<T,Comparator,Allocator>& multiset,
  8660. const split_options::type& split_option = split_options::compress_delimiters)
  8661. {
  8662. return parse_n(data.data(),
  8663. data.data() + data.size(),
  8664. delimiters,
  8665. n,
  8666. multiset,
  8667. split_option);
  8668. }
  8669. template <typename T,
  8670. typename Container>
  8671. inline std::size_t parse_n(const std::string& data,
  8672. const std::string& delimiters,
  8673. const std::size_t& n,
  8674. std::queue<T,Container>& queue,
  8675. const split_options::type& split_option = split_options::compress_delimiters)
  8676. {
  8677. return parse_n(data.data(),
  8678. data.data() + data.size(),
  8679. delimiters,
  8680. n,
  8681. queue,
  8682. split_option);
  8683. }
  8684. template <typename T,
  8685. typename Container>
  8686. inline std::size_t parse_n(const std::string& data,
  8687. const std::string& delimiters,
  8688. const std::size_t& n,
  8689. std::stack<T,Container>& stack,
  8690. const split_options::type& split_option = split_options::compress_delimiters)
  8691. {
  8692. return parse_n(data.data(),
  8693. data.data() + data.size(),
  8694. delimiters,
  8695. n,
  8696. stack,
  8697. split_option);
  8698. }
  8699. template <typename T,
  8700. typename Container,
  8701. typename Comparator>
  8702. inline std::size_t parse_n(const std::string& data,
  8703. const std::string& delimiters,
  8704. const std::size_t& n,
  8705. std::priority_queue<T,Container,Comparator>& priority_queue,
  8706. const split_options::type& split_option = split_options::compress_delimiters)
  8707. {
  8708. return parse_n(data.data(),
  8709. data.data() + data.size(),
  8710. delimiters,
  8711. n,
  8712. priority_queue,
  8713. split_option);
  8714. }
  8715. template <typename T>
  8716. inline std::size_t parse_n(const std::string& data,
  8717. const std::string& delimiters,
  8718. const std::size_t& n,
  8719. T* out,
  8720. const split_options::type& split_option = split_options::compress_delimiters)
  8721. {
  8722. return parse_n(data.data(),
  8723. data.data() + data.size(),
  8724. delimiters,
  8725. n,
  8726. out,
  8727. split_option);
  8728. }
  8729. template <typename T1, typename T2, typename T3, typename T4,
  8730. typename T5, typename T6, typename T7, typename T8,
  8731. typename T9, typename T10, typename T11, typename T12>
  8732. inline bool parse_line(std::ifstream& stream,
  8733. const std::string& delimiters,
  8734. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8735. T7& t7, T8& t8, T9& t9, T10& t10, T11& t11, T12& t12)
  8736. {
  8737. if (!stream)
  8738. return false;
  8739. std::string data;
  8740. data.reserve(strtk::one_kilobyte);
  8741. if (!std::getline(stream,data))
  8742. return false;
  8743. if (data.empty() || delimiters.empty())
  8744. return false;
  8745. return strtk::parse(data.data(),
  8746. data.data() + data.size(),
  8747. delimiters,
  8748. t1,t2,t3,t4,t5,t6,
  8749. t7,t8,t9,t10,t11,t12);
  8750. }
  8751. template <typename T1, typename T2, typename T3, typename T4,
  8752. typename T5, typename T6, typename T7, typename T8,
  8753. typename T9, typename T10, typename T11>
  8754. inline bool parse_line(std::ifstream& stream,
  8755. const std::string& delimiters,
  8756. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8757. T7& t7, T8& t8, T9& t9, T10& t10, T11& t11)
  8758. {
  8759. if (!stream)
  8760. return false;
  8761. std::string data;
  8762. data.reserve(strtk::one_kilobyte);
  8763. if (!std::getline(stream,data))
  8764. return false;
  8765. if (data.empty() || delimiters.empty())
  8766. return false;
  8767. return strtk::parse(data.data(),
  8768. data.data() + data.size(),
  8769. delimiters,
  8770. t1,t2,t3,t4,t5,t6,
  8771. t7,t8,t9,t10,t11);
  8772. }
  8773. template <typename T1, typename T2, typename T3, typename T4,
  8774. typename T5, typename T6, typename T7, typename T8,
  8775. typename T9, typename T10>
  8776. inline bool parse_line(std::ifstream& stream,
  8777. const std::string& delimiters,
  8778. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8779. T7& t7, T8& t8, T9& t9, T10& t10)
  8780. {
  8781. if (!stream)
  8782. return false;
  8783. std::string data;
  8784. data.reserve(strtk::one_kilobyte);
  8785. if (!std::getline(stream,data))
  8786. return false;
  8787. if (data.empty() || delimiters.empty())
  8788. return false;
  8789. return strtk::parse(data.data(),
  8790. data.data() + data.size(),
  8791. delimiters,
  8792. t1,t2,t3,t4,t5,t6,
  8793. t7,t8,t9,t10);
  8794. }
  8795. template <typename T1, typename T2, typename T3, typename T4,
  8796. typename T5, typename T6, typename T7, typename T8,
  8797. typename T9>
  8798. inline bool parse_line(std::ifstream& stream,
  8799. const std::string& delimiters,
  8800. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8801. T7& t7, T8& t8, T9& t9)
  8802. {
  8803. if (!stream)
  8804. return false;
  8805. std::string data;
  8806. data.reserve(strtk::one_kilobyte);
  8807. if (!std::getline(stream,data))
  8808. return false;
  8809. if (data.empty() || delimiters.empty())
  8810. return false;
  8811. return strtk::parse(data.data(),
  8812. data.data() + data.size(),
  8813. delimiters,
  8814. t1,t2,t3,t4,t5,t6,
  8815. t7,t8,t9);
  8816. }
  8817. template <typename T1, typename T2, typename T3, typename T4,
  8818. typename T5, typename T6, typename T7, typename T8>
  8819. inline bool parse_line(std::ifstream& stream,
  8820. const std::string& delimiters,
  8821. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8822. T7& t7, T8& t8)
  8823. {
  8824. if (!stream)
  8825. return false;
  8826. std::string data;
  8827. data.reserve(strtk::one_kilobyte);
  8828. if (!std::getline(stream,data))
  8829. return false;
  8830. if (data.empty() || delimiters.empty())
  8831. return false;
  8832. return strtk::parse(data.data(),
  8833. data.data() + data.size(),
  8834. delimiters,
  8835. t1,t2,t3,t4,t5,t6,
  8836. t7,t8);
  8837. }
  8838. template <typename T1, typename T2, typename T3, typename T4,
  8839. typename T5, typename T6, typename T7>
  8840. inline bool parse_line(std::ifstream& stream,
  8841. const std::string& delimiters,
  8842. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8843. T7& t7)
  8844. {
  8845. if (!stream)
  8846. return false;
  8847. std::string data;
  8848. data.reserve(strtk::one_kilobyte);
  8849. if (!std::getline(stream,data))
  8850. return false;
  8851. if (data.empty() || delimiters.empty())
  8852. return false;
  8853. return strtk::parse(data.data(),
  8854. data.data() + data.size(),
  8855. delimiters,
  8856. t1,t2,t3,t4,t5,t6,t7);
  8857. }
  8858. template <typename T1, typename T2, typename T3, typename T4,
  8859. typename T5, typename T6>
  8860. inline bool parse_line(std::ifstream& stream,
  8861. const std::string& delimiters,
  8862. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6)
  8863. {
  8864. if (!stream)
  8865. return false;
  8866. std::string data;
  8867. data.reserve(strtk::one_kilobyte);
  8868. if (!std::getline(stream,data))
  8869. return false;
  8870. if (data.empty() || delimiters.empty())
  8871. return false;
  8872. return strtk::parse(data.data(),
  8873. data.data() + data.size(),
  8874. delimiters,
  8875. t1,t2,t3,t4,t5,t6);
  8876. }
  8877. template <typename T1, typename T2, typename T3, typename T4,
  8878. typename T5>
  8879. inline bool parse_line(std::ifstream& stream,
  8880. const std::string& delimiters,
  8881. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5)
  8882. {
  8883. if (!stream)
  8884. return false;
  8885. std::string data;
  8886. data.reserve(strtk::one_kilobyte);
  8887. if (!std::getline(stream,data))
  8888. return false;
  8889. if (data.empty() || delimiters.empty())
  8890. return false;
  8891. return strtk::parse(data.data(),
  8892. data.data() + data.size(),
  8893. delimiters,
  8894. t1,t2,t3,t4,t5);
  8895. }
  8896. template <typename T1, typename T2, typename T3, typename T4>
  8897. inline bool parse_line(std::ifstream& stream,
  8898. const std::string& delimiters,
  8899. T1& t1, T2& t2, T3& t3, T4& t4)
  8900. {
  8901. if (!stream)
  8902. return false;
  8903. std::string data;
  8904. data.reserve(strtk::one_kilobyte);
  8905. if (!std::getline(stream,data))
  8906. return false;
  8907. if (data.empty() || delimiters.empty())
  8908. return false;
  8909. return strtk::parse(data.data(),
  8910. data.data() + data.size(),
  8911. delimiters,
  8912. t1,t2,t3,t4);
  8913. }
  8914. template <typename T1, typename T2, typename T3>
  8915. inline bool parse_line(std::ifstream& stream,
  8916. const std::string& delimiters,
  8917. T1& t1, T2& t2, T3& t3)
  8918. {
  8919. if (!stream)
  8920. return false;
  8921. std::string data;
  8922. data.reserve(strtk::one_kilobyte);
  8923. if (!std::getline(stream,data))
  8924. return false;
  8925. if (data.empty() || delimiters.empty())
  8926. return false;
  8927. return strtk::parse(data.data(),
  8928. data.data() + data.size(),
  8929. delimiters,
  8930. t1,t2,t3);
  8931. }
  8932. template <typename T1, typename T2>
  8933. inline bool parse_line(std::ifstream& stream,
  8934. const std::string& delimiters,
  8935. T1& t1, T2& t2)
  8936. {
  8937. if (!stream)
  8938. return false;
  8939. std::string data;
  8940. data.reserve(strtk::one_kilobyte);
  8941. if (!std::getline(stream,data))
  8942. return false;
  8943. if (data.empty() || delimiters.empty())
  8944. return false;
  8945. return strtk::parse(data.data(),
  8946. data.data() + data.size(),
  8947. delimiters,
  8948. t1,t2);
  8949. }
  8950. template <typename T1>
  8951. inline bool parse_line(std::ifstream& stream,
  8952. const std::string& delimiters,
  8953. T1& t1)
  8954. {
  8955. if (!stream)
  8956. return false;
  8957. std::string data;
  8958. data.reserve(strtk::one_kilobyte);
  8959. if (!std::getline(stream,data))
  8960. return false;
  8961. if (data.empty() || delimiters.empty())
  8962. return false;
  8963. return strtk::parse(data.data(),
  8964. data.data() + data.size(),
  8965. delimiters,
  8966. t1);
  8967. }
  8968. template <typename T,
  8969. typename Allocator,
  8970. template <typename,typename> class Sequence>
  8971. inline std::size_t parse_line(std::ifstream& stream,
  8972. const std::string& delimiters,
  8973. Sequence<T,Allocator>& sequence,
  8974. const split_options::type& split_option = split_options::compress_delimiters)
  8975. {
  8976. if (!stream)
  8977. return 0;
  8978. std::string data;
  8979. data.reserve(strtk::one_kilobyte);
  8980. if (!std::getline(stream,data))
  8981. return 0;
  8982. if (data.empty() || delimiters.empty())
  8983. return false;
  8984. return strtk::parse(data.data(),
  8985. data.data() + data.size(),
  8986. delimiters,
  8987. sequence,
  8988. split_option);
  8989. }
  8990. template <typename T,
  8991. typename Comparator,
  8992. typename Allocator>
  8993. inline std::size_t parse_line(std::ifstream& stream,
  8994. const std::string& delimiters,
  8995. std::set<T,Comparator,Allocator>& set,
  8996. const split_options::type& split_option = split_options::compress_delimiters)
  8997. {
  8998. if (!stream)
  8999. return 0;
  9000. std::string data;
  9001. data.reserve(strtk::one_kilobyte);
  9002. if (!std::getline(stream,data))
  9003. return 0;
  9004. if (data.empty() || delimiters.empty())
  9005. return false;
  9006. return strtk::parse(data.data(),
  9007. data.data() + data.size(),
  9008. delimiters,
  9009. set,
  9010. split_option);
  9011. }
  9012. template <typename T,
  9013. typename Comparator,
  9014. typename Allocator>
  9015. inline std::size_t parse_line(std::ifstream& stream,
  9016. const std::string& delimiters,
  9017. std::multiset<T,Comparator,Allocator>& multiset,
  9018. const split_options::type& split_option = split_options::compress_delimiters)
  9019. {
  9020. if (!stream)
  9021. return 0;
  9022. std::string data;
  9023. data.reserve(strtk::one_kilobyte);
  9024. if (!std::getline(stream,data))
  9025. return 0;
  9026. if (data.empty() || delimiters.empty())
  9027. return false;
  9028. return strtk::parse(data.data(),
  9029. data.data() + data.size(),
  9030. delimiters,
  9031. multiset,
  9032. split_option);
  9033. }
  9034. template <typename T,
  9035. typename Container>
  9036. inline std::size_t parse_line(std::ifstream& stream,
  9037. const std::string& delimiters,
  9038. std::queue<T,Container>& queue,
  9039. const split_options::type& split_option = split_options::compress_delimiters)
  9040. {
  9041. if (!stream)
  9042. return 0;
  9043. std::string data;
  9044. data.reserve(strtk::one_kilobyte);
  9045. if (!std::getline(stream,data))
  9046. return 0;
  9047. if (data.empty() || delimiters.empty())
  9048. return false;
  9049. return strtk::parse(data.data(),
  9050. data.data() + data.size(),
  9051. delimiters,
  9052. queue,
  9053. split_option);
  9054. }
  9055. template <typename T,
  9056. typename Container>
  9057. inline std::size_t parse_line(std::ifstream& stream,
  9058. const std::string& delimiters,
  9059. std::stack<T,Container>& stack,
  9060. const split_options::type& split_option = split_options::compress_delimiters)
  9061. {
  9062. if (!stream)
  9063. return 0;
  9064. std::string data;
  9065. data.reserve(strtk::one_kilobyte);
  9066. if (!std::getline(stream,data))
  9067. return 0;
  9068. if (data.empty() || delimiters.empty())
  9069. return false;
  9070. return strtk::parse(data.data(),
  9071. data.data() + data.size(),
  9072. delimiters,
  9073. stack,
  9074. split_option);
  9075. }
  9076. template <typename T,
  9077. typename Container,
  9078. typename Comparator>
  9079. inline std::size_t parse_line(std::ifstream& stream,
  9080. const std::string& delimiters,
  9081. std::priority_queue<T,Container,Comparator>& priority_queue,
  9082. const split_options::type& split_option = split_options::compress_delimiters)
  9083. {
  9084. if (!stream)
  9085. return 0;
  9086. std::string data;
  9087. data.reserve(strtk::one_kilobyte);
  9088. if (!std::getline(stream,data))
  9089. return 0;
  9090. if (data.empty() || delimiters.empty())
  9091. return false;
  9092. return strtk::parse(data.data(),
  9093. data.data() + data.size(),
  9094. delimiters,
  9095. priority_queue,
  9096. split_option);
  9097. }
  9098. template <typename T,
  9099. typename Allocator,
  9100. template <typename,typename> class Sequence>
  9101. inline std::size_t parse_line_n(std::ifstream& stream,
  9102. const std::string& delimiters,
  9103. const std::size_t& n,
  9104. Sequence<T,Allocator>& sequence,
  9105. const split_options::type& split_option = split_options::compress_delimiters)
  9106. {
  9107. if (!stream)
  9108. return 0;
  9109. std::string data;
  9110. data.reserve(strtk::one_kilobyte);
  9111. if (!std::getline(stream,data))
  9112. return 0;
  9113. if (data.empty() || delimiters.empty())
  9114. return 0;
  9115. return strtk::parse_n(data.data(),
  9116. data.data() + data.size(),
  9117. delimiters,
  9118. n,
  9119. sequence,
  9120. split_option);
  9121. }
  9122. template <typename T,
  9123. typename Comparator,
  9124. typename Allocator>
  9125. inline std::size_t parse_line_n(std::ifstream& stream,
  9126. const std::string& delimiters,
  9127. const std::size_t& n,
  9128. std::set<T,Comparator,Allocator>& set,
  9129. const split_options::type& split_option = split_options::compress_delimiters)
  9130. {
  9131. if (!stream)
  9132. return 0;
  9133. std::string data;
  9134. data.reserve(strtk::one_kilobyte);
  9135. if (!std::getline(stream,data))
  9136. return 0;
  9137. if (data.empty() || delimiters.empty())
  9138. return 0;
  9139. return strtk::parse_n(data.data(),
  9140. data.data() + data.size(),
  9141. delimiters,
  9142. n,
  9143. set,
  9144. split_option);
  9145. }
  9146. template <typename T,
  9147. typename Comparator,
  9148. typename Allocator>
  9149. inline std::size_t parse_line_n(std::ifstream& stream,
  9150. const std::string& delimiters,
  9151. const std::size_t& n,
  9152. std::multiset<T,Comparator,Allocator>& multiset,
  9153. const split_options::type& split_option = split_options::compress_delimiters)
  9154. {
  9155. if (!stream)
  9156. return 0;
  9157. std::string data;
  9158. data.reserve(strtk::one_kilobyte);
  9159. if (!std::getline(stream,data))
  9160. return 0;
  9161. if (data.empty() || delimiters.empty())
  9162. return 0;
  9163. return strtk::parse_n(data.data(),
  9164. data.data() + data.size(),
  9165. delimiters,
  9166. n,
  9167. multiset,
  9168. split_option);
  9169. }
  9170. template <typename T,
  9171. typename Container>
  9172. inline std::size_t parse_line_n(std::ifstream& stream,
  9173. const std::string& delimiters,
  9174. const std::size_t& n,
  9175. std::queue<T,Container>& queue,
  9176. const split_options::type& split_option = split_options::compress_delimiters)
  9177. {
  9178. if (!stream)
  9179. return 0;
  9180. std::string data;
  9181. data.reserve(strtk::one_kilobyte);
  9182. if (!std::getline(stream,data))
  9183. return 0;
  9184. if (data.empty() || delimiters.empty())
  9185. return 0;
  9186. return strtk::parse_n(data.data(),
  9187. data.data() + data.size(),
  9188. delimiters,
  9189. n,
  9190. queue,
  9191. split_option);
  9192. }
  9193. template <typename T,
  9194. typename Container>
  9195. inline std::size_t parse_line_n(std::ifstream& stream,
  9196. const std::string& delimiters,
  9197. const std::size_t& n,
  9198. std::stack<T,Container>& stack,
  9199. const split_options::type& split_option = split_options::compress_delimiters)
  9200. {
  9201. if (!stream)
  9202. return 0;
  9203. std::string data;
  9204. data.reserve(strtk::one_kilobyte);
  9205. if (!std::getline(stream,data))
  9206. return 0;
  9207. if (data.empty() || delimiters.empty())
  9208. return 0;
  9209. return strtk::parse_n(data.data(),
  9210. data.data() + data.size(),
  9211. delimiters,
  9212. n,
  9213. stack,
  9214. split_option);
  9215. }
  9216. template <typename T,
  9217. typename Container,
  9218. typename Comparator>
  9219. inline std::size_t parse_line_n(std::ifstream& stream,
  9220. const std::string& delimiters,
  9221. const std::size_t& n,
  9222. std::priority_queue<T,Container,Comparator>& priority_queue,
  9223. const split_options::type& split_option = split_options::compress_delimiters)
  9224. {
  9225. if (!stream)
  9226. return 0;
  9227. std::string data;
  9228. data.reserve(strtk::one_kilobyte);
  9229. if (!std::getline(stream,data))
  9230. return 0;
  9231. if (data.empty() || delimiters.empty())
  9232. return 0;
  9233. return strtk::parse_n(data.data(),
  9234. data.data() + data.size(),
  9235. delimiters,
  9236. n,
  9237. priority_queue,
  9238. split_option);
  9239. }
  9240. template <typename T1, typename T2, typename T3, typename T4,
  9241. typename T5, typename T6, typename T7, typename T8,
  9242. typename T9, typename T10, typename T11, typename T12>
  9243. inline void construct(std::string& output,
  9244. const std::string& delimiter,
  9245. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9246. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  9247. const T9& t9, const T10& t10, const T11& t11, const T12& t12)
  9248. {
  9249. output += type_to_string( t1); output += delimiter;
  9250. output += type_to_string( t2); output += delimiter;
  9251. output += type_to_string( t3); output += delimiter;
  9252. output += type_to_string( t4); output += delimiter;
  9253. output += type_to_string( t5); output += delimiter;
  9254. output += type_to_string( t6); output += delimiter;
  9255. output += type_to_string( t7); output += delimiter;
  9256. output += type_to_string( t8); output += delimiter;
  9257. output += type_to_string( t9); output += delimiter;
  9258. output += type_to_string(t10); output += delimiter;
  9259. output += type_to_string(t11); output += delimiter;
  9260. output += type_to_string(t12);
  9261. }
  9262. template <typename T1, typename T2, typename T3, typename T4,
  9263. typename T5, typename T6, typename T7, typename T8,
  9264. typename T9, typename T10, typename T11>
  9265. inline void construct(std::string& output,
  9266. const std::string& delimiter,
  9267. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9268. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  9269. const T9& t9, const T10& t10, const T11& t11)
  9270. {
  9271. output += type_to_string( t1); output += delimiter;
  9272. output += type_to_string( t2); output += delimiter;
  9273. output += type_to_string( t3); output += delimiter;
  9274. output += type_to_string( t4); output += delimiter;
  9275. output += type_to_string( t5); output += delimiter;
  9276. output += type_to_string( t6); output += delimiter;
  9277. output += type_to_string( t7); output += delimiter;
  9278. output += type_to_string( t8); output += delimiter;
  9279. output += type_to_string( t9); output += delimiter;
  9280. output += type_to_string(t10); output += delimiter;
  9281. output += type_to_string(t11);
  9282. }
  9283. template <typename T1, typename T2, typename T3, typename T4,
  9284. typename T5, typename T6, typename T7, typename T8,
  9285. typename T9, typename T10>
  9286. inline void construct(std::string& output,
  9287. const std::string& delimiter,
  9288. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9289. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  9290. const T9& t9, const T10& t10)
  9291. {
  9292. output += type_to_string(t1); output += delimiter;
  9293. output += type_to_string(t2); output += delimiter;
  9294. output += type_to_string(t3); output += delimiter;
  9295. output += type_to_string(t4); output += delimiter;
  9296. output += type_to_string(t5); output += delimiter;
  9297. output += type_to_string(t6); output += delimiter;
  9298. output += type_to_string(t7); output += delimiter;
  9299. output += type_to_string(t8); output += delimiter;
  9300. output += type_to_string(t9); output += delimiter;
  9301. output += type_to_string(t10);
  9302. }
  9303. template <typename T1, typename T2, typename T3, typename T4,
  9304. typename T5, typename T6, typename T7, typename T8,
  9305. typename T9>
  9306. inline void construct(std::string& output,
  9307. const std::string& delimiter,
  9308. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9309. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  9310. const T9& t9)
  9311. {
  9312. output += type_to_string(t1); output += delimiter;
  9313. output += type_to_string(t2); output += delimiter;
  9314. output += type_to_string(t3); output += delimiter;
  9315. output += type_to_string(t4); output += delimiter;
  9316. output += type_to_string(t5); output += delimiter;
  9317. output += type_to_string(t6); output += delimiter;
  9318. output += type_to_string(t7); output += delimiter;
  9319. output += type_to_string(t8); output += delimiter;
  9320. output += type_to_string(t9);
  9321. }
  9322. template <typename T1, typename T2, typename T3, typename T4,
  9323. typename T5, typename T6, typename T7, typename T8>
  9324. inline void construct(std::string& output,
  9325. const std::string& delimiter,
  9326. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9327. const T5& t5, const T6& t6, const T7& t7, const T8& t8)
  9328. {
  9329. output += type_to_string(t1); output += delimiter;
  9330. output += type_to_string(t2); output += delimiter;
  9331. output += type_to_string(t3); output += delimiter;
  9332. output += type_to_string(t4); output += delimiter;
  9333. output += type_to_string(t5); output += delimiter;
  9334. output += type_to_string(t6); output += delimiter;
  9335. output += type_to_string(t7); output += delimiter;
  9336. output += type_to_string(t8);
  9337. }
  9338. template <typename T1, typename T2, typename T3, typename T4,
  9339. typename T5, typename T6, typename T7>
  9340. inline void construct(std::string& output,
  9341. const std::string& delimiter,
  9342. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9343. const T5& t5, const T6& t6, const T7& t7)
  9344. {
  9345. output += type_to_string(t1); output += delimiter;
  9346. output += type_to_string(t2); output += delimiter;
  9347. output += type_to_string(t3); output += delimiter;
  9348. output += type_to_string(t4); output += delimiter;
  9349. output += type_to_string(t5); output += delimiter;
  9350. output += type_to_string(t6); output += delimiter;
  9351. output += type_to_string(t7);
  9352. }
  9353. template <typename T1, typename T2, typename T3, typename T4,
  9354. typename T5,typename T6>
  9355. inline void construct(std::string& output,
  9356. const std::string& delimiter,
  9357. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9358. const T5& t5, const T6& t6)
  9359. {
  9360. output += type_to_string(t1); output += delimiter;
  9361. output += type_to_string(t2); output += delimiter;
  9362. output += type_to_string(t3); output += delimiter;
  9363. output += type_to_string(t4); output += delimiter;
  9364. output += type_to_string(t5); output += delimiter;
  9365. output += type_to_string(t6);
  9366. }
  9367. template <typename T1, typename T2, typename T3, typename T4,
  9368. typename T5>
  9369. inline void construct(std::string& output,
  9370. const std::string& delimiter,
  9371. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9372. const T5& t5)
  9373. {
  9374. output += type_to_string(t1); output += delimiter;
  9375. output += type_to_string(t2); output += delimiter;
  9376. output += type_to_string(t3); output += delimiter;
  9377. output += type_to_string(t4); output += delimiter;
  9378. output += type_to_string(t5);
  9379. }
  9380. template <typename T1, typename T2, typename T3, typename T4>
  9381. inline void construct(std::string& output,
  9382. const std::string& delimiter,
  9383. const T1& t1, const T2& t2, const T3& t3, const T4& t4)
  9384. {
  9385. output += type_to_string(t1); output += delimiter;
  9386. output += type_to_string(t2); output += delimiter;
  9387. output += type_to_string(t3); output += delimiter;
  9388. output += type_to_string(t4);
  9389. }
  9390. template <typename T1, typename T2, typename T3>
  9391. inline void construct(std::string& output,
  9392. const std::string& delimiter,
  9393. const T1& t1, const T2& t2, const T3& t3)
  9394. {
  9395. output += type_to_string(t1); output += delimiter;
  9396. output += type_to_string(t2); output += delimiter;
  9397. output += type_to_string(t3);
  9398. }
  9399. template <typename T1, typename T2>
  9400. inline void construct(std::string& output,
  9401. const std::string& delimiter,
  9402. const T1& t1, const T2& t2)
  9403. {
  9404. output += type_to_string(t1); output += delimiter;
  9405. output += type_to_string(t2);
  9406. }
  9407. template <typename InputIterator>
  9408. inline void join(std::string& output,
  9409. const std::string& delimiter,
  9410. const InputIterator begin,
  9411. const InputIterator end)
  9412. {
  9413. InputIterator itr = begin;
  9414. while (end != itr)
  9415. {
  9416. output += type_to_string(*itr);
  9417. if (end == (++itr))
  9418. break;
  9419. else
  9420. output += delimiter;
  9421. }
  9422. }
  9423. template <typename InputIterator>
  9424. inline void join(std::string& output,
  9425. const std::string& delimiter,
  9426. const std::pair<InputIterator,InputIterator>& range)
  9427. {
  9428. InputIterator itr = range.first;
  9429. while (range.second != itr)
  9430. {
  9431. output += type_to_string(*itr);
  9432. if (range.second == (++itr))
  9433. break;
  9434. else
  9435. output += delimiter;
  9436. }
  9437. }
  9438. template <typename T,
  9439. typename Allocator,
  9440. template <typename,typename> class Sequence>
  9441. inline void join(std::string& output,
  9442. const std::string& delimiter,
  9443. const Sequence<T,Allocator>& sequence)
  9444. {
  9445. join(output,delimiter,sequence.begin(),sequence.end());
  9446. }
  9447. template <typename T,
  9448. typename Comparator,
  9449. typename Allocator>
  9450. inline void join(std::string& output,
  9451. const std::string& delimiter,
  9452. const std::set<T,Comparator,Allocator>& set)
  9453. {
  9454. join(output,delimiter,set.begin(),set.end());
  9455. }
  9456. template <typename T,
  9457. typename Comparator,
  9458. typename Allocator>
  9459. inline void join(std::string& output,
  9460. const std::string& delimiter,
  9461. const std::multiset<T,Comparator,Allocator>& multiset)
  9462. {
  9463. join(output,delimiter,multiset.begin(),multiset.end());
  9464. }
  9465. inline void join(std::string& output,
  9466. const std::string& delimiter,
  9467. int argc, char* argv[])
  9468. {
  9469. for (int i = 0; i < argc; ++i)
  9470. {
  9471. output += argv[i];
  9472. if (i < (argc - 1))
  9473. output += delimiter;
  9474. }
  9475. }
  9476. template <typename InputIterator>
  9477. inline std::string join(const std::string& delimiter,
  9478. const InputIterator begin,
  9479. const InputIterator end)
  9480. {
  9481. std::string output;
  9482. output.reserve(one_kilobyte);
  9483. join(output,delimiter,begin,end);
  9484. return output;
  9485. }
  9486. template <typename InputIterator>
  9487. inline std::string join(const std::string& delimiter,
  9488. const std::pair<InputIterator,InputIterator>& range)
  9489. {
  9490. std::string output;
  9491. output.reserve(one_kilobyte);
  9492. join(output,delimiter,range.first,range.second);
  9493. return output;
  9494. }
  9495. template <typename T,
  9496. typename Allocator,
  9497. template <typename,typename> class Sequence>
  9498. inline std::string join(const std::string& delimiter,
  9499. const Sequence<T,Allocator>& sequence)
  9500. {
  9501. if (sequence.empty())
  9502. return "";
  9503. else
  9504. return join(delimiter,sequence.begin(),sequence.end());
  9505. }
  9506. template <typename T,
  9507. typename Comparator,
  9508. typename Allocator>
  9509. inline std::string join(const std::string& delimiter,
  9510. const std::set<T,Comparator,Allocator>& set)
  9511. {
  9512. if (set.empty())
  9513. return "";
  9514. else
  9515. return join(delimiter,set.begin(),set.end());
  9516. }
  9517. template <typename T,
  9518. typename Comparator,
  9519. typename Allocator>
  9520. inline std::string join(const std::string& delimiter,
  9521. const std::multiset<T,Comparator,Allocator>& multiset)
  9522. {
  9523. if (multiset.empty())
  9524. return "";
  9525. else
  9526. return join(delimiter,multiset.begin(),multiset.end());
  9527. }
  9528. inline std::string join(const std::string& delimiter, int argc, char* argv[])
  9529. {
  9530. std::string result;
  9531. result.reserve(one_kilobyte);
  9532. join(result,delimiter,argc,argv);
  9533. return result;
  9534. }
  9535. template <typename InputIterator, typename Predicate>
  9536. inline void join_if(std::string& output,
  9537. const std::string& delimiter,
  9538. Predicate predicate,
  9539. const InputIterator begin,
  9540. const InputIterator end)
  9541. {
  9542. InputIterator itr = begin;
  9543. bool first_time = true;
  9544. while (end != itr)
  9545. {
  9546. if (predicate(*itr))
  9547. {
  9548. if (!first_time)
  9549. output += delimiter;
  9550. else
  9551. first_time = false;
  9552. output += type_to_string(*itr);
  9553. }
  9554. if (end == (++itr))
  9555. break;
  9556. }
  9557. }
  9558. template <typename InputIterator, typename Predicate>
  9559. inline void join_if(std::string& output,
  9560. const std::string& delimiter,
  9561. Predicate predicate,
  9562. const std::pair<InputIterator,InputIterator>& range)
  9563. {
  9564. InputIterator itr = range.first;
  9565. bool first_time = true;
  9566. while (range.second != itr)
  9567. {
  9568. if (predicate(*itr))
  9569. {
  9570. if (!first_time)
  9571. output += delimiter;
  9572. else
  9573. first_time = false;
  9574. output += type_to_string(*itr);
  9575. }
  9576. if (range.second == (++itr))
  9577. break;
  9578. }
  9579. }
  9580. template <typename T,
  9581. typename Predicate,
  9582. typename Allocator,
  9583. template <typename,typename> class Sequence>
  9584. inline void join_if(std::string& output,
  9585. const std::string& delimiter,
  9586. Predicate predicate,
  9587. const Sequence<T,Allocator>& sequence)
  9588. {
  9589. join_if(output,delimiter,predicate,sequence.begin(),sequence.end());
  9590. }
  9591. template <typename T,
  9592. typename Predicate,
  9593. typename Comparator,
  9594. typename Allocator>
  9595. inline void join_if(std::string& output,
  9596. const std::string& delimiter,
  9597. Predicate predicate,
  9598. const std::set<T,Comparator,Allocator>& set)
  9599. {
  9600. join_if(output,delimiter,predicate,set.begin(),set.end());
  9601. }
  9602. template <typename T,
  9603. typename Predicate,
  9604. typename Comparator,
  9605. typename Allocator>
  9606. inline void join_if(std::string& output,
  9607. const std::string& delimiter,
  9608. Predicate predicate,
  9609. const std::multiset<T,Comparator,Allocator>& multiset)
  9610. {
  9611. join_if(output,delimiter,predicate,multiset.begin(),multiset.end());
  9612. }
  9613. template <typename InputIterator, typename Predicate>
  9614. inline std::string join_if(const std::string& delimiter,
  9615. Predicate predicate,
  9616. const InputIterator begin,
  9617. const InputIterator end)
  9618. {
  9619. std::string output;
  9620. output.reserve(one_kilobyte);
  9621. join_if(output,delimiter,predicate,begin,end);
  9622. return output;
  9623. }
  9624. template <typename InputIterator, typename Predicate>
  9625. inline std::string join_if(const std::string& delimiter,
  9626. Predicate predicate,
  9627. const std::pair<InputIterator,InputIterator>& range)
  9628. {
  9629. std::string output;
  9630. output.reserve(one_kilobyte);
  9631. join_if(output,delimiter,predicate,range.first,range.second);
  9632. return output;
  9633. }
  9634. template <typename T,
  9635. typename Predicate,
  9636. typename Allocator,
  9637. template <typename,typename> class Sequence>
  9638. inline std::string join_if(const std::string& delimiter,
  9639. Predicate predicate,
  9640. const Sequence<T,Allocator>& sequence)
  9641. {
  9642. return join(delimiter,predicate,sequence.begin(),sequence.end());
  9643. }
  9644. template <typename T,
  9645. typename Predicate,
  9646. typename Comparator,
  9647. typename Allocator>
  9648. inline std::string join_if(const std::string& delimiter,
  9649. Predicate predicate,
  9650. const std::set<T,Comparator,Allocator>& set)
  9651. {
  9652. return join_if(delimiter,predicate,set.begin(),set.end());
  9653. }
  9654. template <typename T,
  9655. typename Predicate,
  9656. typename Comparator,
  9657. typename Allocator>
  9658. inline std::string join_if(const std::string& delimiter,
  9659. Predicate predicate,
  9660. const std::multiset<T,Comparator,Allocator>& multiset)
  9661. {
  9662. return join_if(delimiter,predicate,multiset.begin(),multiset.end());
  9663. }
  9664. class build_string
  9665. {
  9666. public:
  9667. build_string(const std::size_t& initial_size = 64)
  9668. {
  9669. data_.reserve(initial_size);
  9670. }
  9671. template <typename T>
  9672. inline build_string& operator << (const T& t)
  9673. {
  9674. data_ += type_to_string(t);
  9675. return (*this);
  9676. }
  9677. inline build_string& operator << (const std::string& s)
  9678. {
  9679. data_ += s;
  9680. return (*this);
  9681. }
  9682. inline std::string to_str() const
  9683. {
  9684. return data_;
  9685. }
  9686. inline operator const char* () const
  9687. {
  9688. return data_.data();
  9689. }
  9690. private:
  9691. std::string data_;
  9692. };
  9693. inline void replicate(const std::size_t& n,
  9694. const std::string& str,
  9695. std::string& output)
  9696. {
  9697. if (0 == n) return;
  9698. output.reserve(output.size() + (str.size() * n));
  9699. for (std::size_t i = 0; i < n; ++i)
  9700. {
  9701. output.append(str);
  9702. }
  9703. }
  9704. inline std::string replicate(const std::size_t& n,
  9705. const std::string& str)
  9706. {
  9707. std::string output;
  9708. replicate(n,str,output);
  9709. return output;
  9710. }
  9711. inline void replicate_inplace(const std::size_t& n,
  9712. std::string& str)
  9713. {
  9714. std::string temp_str = str;
  9715. str.reserve(str.size() + (str.size() * n));
  9716. for (std::size_t i = 0; i < n; ++i)
  9717. {
  9718. str.append(temp_str);
  9719. }
  9720. }
  9721. template <typename InputIterator>
  9722. inline void bracketize(std::string& output,
  9723. const std::string& pre,
  9724. const std::string& post,
  9725. const InputIterator begin,
  9726. const InputIterator end)
  9727. {
  9728. InputIterator itr = begin;
  9729. std::string s;
  9730. s.reserve(one_kilobyte);
  9731. while (end != itr)
  9732. {
  9733. s.clear();
  9734. s.append(pre);
  9735. s.append(type_to_string(*itr));
  9736. s.append(post);
  9737. output.append(s);
  9738. ++itr;
  9739. }
  9740. }
  9741. template <typename T,
  9742. typename Allocator,
  9743. template <typename,typename> class Sequence>
  9744. inline void bracketize(std::string& output,
  9745. const std::string& pre,
  9746. const std::string& post,
  9747. Sequence<T,Allocator>& sequence)
  9748. {
  9749. bracketize(output,pre,post,sequence.begin(),sequence.end());
  9750. }
  9751. template <typename T,
  9752. typename Comparator,
  9753. typename Allocator>
  9754. inline void bracketize(std::string& output,
  9755. const std::string& pre,
  9756. const std::string& post,
  9757. std::set<T,Comparator,Allocator>& set)
  9758. {
  9759. bracketize(output,pre,post,set.begin(),set.end());
  9760. }
  9761. template <typename T,
  9762. typename Comparator,
  9763. typename Allocator>
  9764. inline void bracketize(std::string& output,
  9765. const std::string& pre,
  9766. const std::string& post,
  9767. std::multiset<T,Comparator,Allocator>& multiset)
  9768. {
  9769. bracketize(output,pre,post,multiset.begin(),multiset.end());
  9770. }
  9771. template <typename InputIterator>
  9772. inline std::string bracketize(const std::string& pre,
  9773. const std::string& post,
  9774. const InputIterator begin,
  9775. const InputIterator end)
  9776. {
  9777. std::string output;
  9778. output.reserve(one_kilobyte);
  9779. bracketize(output,pre,post,begin,end);
  9780. return output;
  9781. }
  9782. template <typename T,
  9783. typename Allocator,
  9784. template <typename,typename> class Sequence>
  9785. inline std::string bracketize(const std::string& pre,
  9786. const std::string& post,
  9787. Sequence<T,Allocator>& sequence)
  9788. {
  9789. return bracketize(pre,post,sequence.begin(),sequence.end());
  9790. }
  9791. template <typename T,
  9792. typename Comparator,
  9793. typename Allocator>
  9794. inline std::string bracketize(const std::string& pre,
  9795. const std::string& post,
  9796. std::set<T,Comparator,Allocator>& set)
  9797. {
  9798. return bracketize(pre,post,set.begin(),set.end());
  9799. }
  9800. template <typename T,
  9801. typename Comparator,
  9802. typename Allocator>
  9803. inline std::string bracketize(const std::string& pre,
  9804. const std::string& post,
  9805. std::multiset<T,Comparator,Allocator>& multiset)
  9806. {
  9807. return bracketize(pre,post,multiset.begin(),multiset.end());
  9808. }
  9809. template <typename T>
  9810. struct interval_inserter
  9811. {
  9812. typedef T type;
  9813. interval_inserter(const std::size_t& interval, const T& t)
  9814. : count_(0),
  9815. interval_(interval),
  9816. t_(t)
  9817. {}
  9818. inline bool operator()(const type&)
  9819. {
  9820. if (++count_ == interval_)
  9821. {
  9822. count_ = 0;
  9823. return true;
  9824. }
  9825. else
  9826. return false;
  9827. }
  9828. inline T operator()()
  9829. {
  9830. return t_;
  9831. }
  9832. private:
  9833. std::size_t count_;
  9834. std::size_t interval_;
  9835. T t_;
  9836. };
  9837. template <typename Inserter,
  9838. typename InputIterator,
  9839. typename OutputIterator>
  9840. inline std::size_t inserter(Inserter ins,
  9841. const InputIterator begin, const InputIterator end,
  9842. OutputIterator out)
  9843. {
  9844. std::size_t size = 0;
  9845. InputIterator itr = begin;
  9846. while (end != itr)
  9847. {
  9848. (*out) = (*itr);
  9849. ++out;
  9850. if (ins(*itr++))
  9851. {
  9852. (*out) = ins();
  9853. ++out;
  9854. size += 2;
  9855. }
  9856. else
  9857. ++size;
  9858. }
  9859. return size;
  9860. }
  9861. template <typename Iterator, typename T>
  9862. inline void iota(Iterator begin, Iterator end, T value)
  9863. {
  9864. Iterator itr = begin;
  9865. while (end != itr)
  9866. {
  9867. (*itr) = value++;
  9868. ++itr;
  9869. }
  9870. }
  9871. template <typename T>
  9872. inline void iota(typename range::adapter<T>& r, T value)
  9873. {
  9874. iota(r.begin(),r.end(),value);
  9875. }
  9876. template <typename T,
  9877. typename Allocator,
  9878. template <typename,typename> class Sequence>
  9879. inline void iota(Sequence<T,Allocator>& sequence, std::size_t count, T value)
  9880. {
  9881. while (count)
  9882. {
  9883. sequence.push_back(value++);
  9884. --count;
  9885. }
  9886. }
  9887. template <typename T,
  9888. typename Comparator,
  9889. typename Allocator>
  9890. inline void iota(std::set<T,Comparator,Allocator>& set, std::size_t count, T value)
  9891. {
  9892. while (count)
  9893. {
  9894. set.insert(value++);
  9895. --count;
  9896. }
  9897. }
  9898. template <typename T,
  9899. typename Comparator,
  9900. typename Allocator>
  9901. inline void iota(std::multiset<T,Comparator,Allocator>& multiset, std::size_t count, T value)
  9902. {
  9903. while (count)
  9904. {
  9905. multiset.insert(value++);
  9906. --count;
  9907. }
  9908. }
  9909. template <typename OutputIterator, typename T>
  9910. inline void iota(std::size_t count, T value, OutputIterator out)
  9911. {
  9912. while (count)
  9913. {
  9914. (*out) = value++;
  9915. ++out;
  9916. --count;
  9917. }
  9918. }
  9919. template <typename T,
  9920. typename Allocator,
  9921. template <typename,typename> class Sequence>
  9922. inline void iota(Sequence<T,Allocator>& sequence, const T& value)
  9923. {
  9924. strtk::iota(sequence.begin(),sequence.end(),value);
  9925. }
  9926. template <typename T,
  9927. typename Comparator,
  9928. typename Allocator>
  9929. inline void iota(std::set<T,Comparator,Allocator>& set, const T& value)
  9930. {
  9931. strtk::iota(set.begin(),set.end(),value);
  9932. }
  9933. template <typename T,
  9934. typename Comparator,
  9935. typename Allocator>
  9936. inline void iota(std::multiset<T,Comparator,Allocator>& multiset, const T& value)
  9937. {
  9938. strtk::iota(multiset.begin(),multiset.end(),value);
  9939. }
  9940. template <typename InputIterator, typename OutputIterator>
  9941. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9942. const InputIterator begin, InputIterator end,
  9943. OutputIterator out)
  9944. {
  9945. // static assert: InputIterator must be of type std::string
  9946. InputIterator itr = begin;
  9947. while (end != itr)
  9948. {
  9949. const std::string& s = (*itr);
  9950. ++itr;
  9951. if (s.size() < r0)
  9952. continue;
  9953. (*out++) = s.substr(r0,std::min(r1,s.size()) - r0);
  9954. }
  9955. }
  9956. template <typename Allocator,
  9957. template <typename,typename> class Sequence,
  9958. typename OutputIterator>
  9959. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9960. const Sequence<std::string, Allocator>& sequence,
  9961. OutputIterator out)
  9962. {
  9963. cut(r0,r1,sequence.begin(),sequence.end(),out);
  9964. }
  9965. template <typename Iterator>
  9966. inline void cut_inplace(const std::size_t& r0, const std::size_t& r1,
  9967. const Iterator begin, const Iterator end)
  9968. {
  9969. // static assert: InputIterator must be of type std::string
  9970. Iterator itr = begin;
  9971. while (end != itr)
  9972. {
  9973. if ((*itr).size() >= r0)
  9974. {
  9975. (*itr) = (*itr).substr(r0,std::min(r1,(*itr).size()) - r0);
  9976. }
  9977. ++itr;
  9978. }
  9979. }
  9980. template <typename Allocator,
  9981. template <typename,typename> class Sequence>
  9982. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9983. const Sequence<std::string, Allocator>& sequence)
  9984. {
  9985. cut(r0,r1,sequence.begin(),sequence.end());
  9986. }
  9987. template <typename Comparator, typename Allocator>
  9988. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9989. const std::set<std::string, Comparator, Allocator>& set)
  9990. {
  9991. cut(r0,r1,set.begin(),set.end());
  9992. }
  9993. template <typename Comparator, typename Allocator>
  9994. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9995. const std::multiset<std::string, Comparator, Allocator>& multiset)
  9996. {
  9997. cut(r0,r1,multiset.begin(),multiset.end());
  9998. }
  9999. class translation_table
  10000. {
  10001. public:
  10002. translation_table(const std::string& itable, const std::string& otable)
  10003. {
  10004. if (itable.size() != otable.size())
  10005. {
  10006. throw std::runtime_error("translation_table() - Input/Output table size mismatch.");
  10007. }
  10008. strtk::iota(table_, table_ + 256, static_cast<unsigned char>(0));
  10009. for (std::size_t i = 0; i < itable.size(); ++i)
  10010. {
  10011. table_[static_cast<unsigned int>(itable[i])] = static_cast<unsigned char>(otable[i]);
  10012. }
  10013. }
  10014. inline char operator()(const char c) const
  10015. {
  10016. return static_cast<char>(table_[static_cast<unsigned int>(c)]);
  10017. }
  10018. inline unsigned char operator()(const unsigned char c) const
  10019. {
  10020. return static_cast<unsigned char>(table_[static_cast<unsigned int>(c)]);
  10021. }
  10022. private:
  10023. unsigned char table_[256];
  10024. };
  10025. inline std::string translate(const translation_table& trans_table, const std::string& s)
  10026. {
  10027. std::string result = s;
  10028. std::transform(result.begin(),result.end(),result.begin(),trans_table);
  10029. return result;
  10030. }
  10031. inline void translate_inplace(const translation_table& trans_table, std::string& s)
  10032. {
  10033. std::transform(s.begin(),s.end(),s.begin(),trans_table);
  10034. }
  10035. #ifdef strtk_enable_random
  10036. inline void generate_random_data(unsigned char* data,
  10037. std::size_t length,
  10038. unsigned int pre_gen_cnt = 0,
  10039. unsigned int seed = magic_seed)
  10040. {
  10041. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  10042. boost::uniform_int<unsigned int> dist(std::numeric_limits<unsigned int>::min(),std::numeric_limits<unsigned int>::max());
  10043. boost::variate_generator<boost::mt19937&, boost::uniform_int<unsigned int> > rnd(rng,dist);
  10044. if (pre_gen_cnt > 0)
  10045. {
  10046. while (pre_gen_cnt--) rnd();
  10047. }
  10048. unsigned char* itr = data;
  10049. unsigned int* x = 0;
  10050. while (length >= sizeof(unsigned int))
  10051. {
  10052. x = reinterpret_cast<unsigned int*>(itr);
  10053. (*x) = rnd();
  10054. itr += sizeof(unsigned int);
  10055. length -= sizeof(unsigned int);
  10056. }
  10057. if (length > 0)
  10058. {
  10059. itr -= (sizeof(unsigned int) - length);
  10060. x = reinterpret_cast<unsigned int*>(itr);
  10061. (*x) = rnd();
  10062. }
  10063. }
  10064. namespace details
  10065. {
  10066. struct rand_int_type_tag {};
  10067. struct rand_real_type_tag {};
  10068. template <typename T> struct supported_random_type {};
  10069. #define strtk_register_rand_int_type_tag(T) \
  10070. template<> struct supported_random_type<T> { typedef rand_int_type_tag type; enum { value = true }; };
  10071. #define strtk_register_rand_real_type_tag(T) \
  10072. template<> struct supported_random_type<T> { typedef rand_real_type_tag type; enum { value = true }; };
  10073. strtk_register_rand_int_type_tag(char)
  10074. strtk_register_rand_int_type_tag(unsigned char)
  10075. strtk_register_rand_int_type_tag(short)
  10076. strtk_register_rand_int_type_tag(int)
  10077. strtk_register_rand_int_type_tag(long)
  10078. strtk_register_rand_int_type_tag(unsigned short)
  10079. strtk_register_rand_int_type_tag(unsigned int)
  10080. strtk_register_rand_int_type_tag(unsigned long)
  10081. strtk_register_rand_real_type_tag(float)
  10082. strtk_register_rand_real_type_tag(double)
  10083. strtk_register_rand_real_type_tag(long double)
  10084. #undef strtk_register_rand_int_type_tag
  10085. #undef strtk_register_rand_real_type_tag
  10086. template <typename T, typename OutputIterator, typename RandomNumberGenerator>
  10087. inline void generate_random_values_impl(const std::size_t& count,
  10088. const T& min,
  10089. const T& max,
  10090. OutputIterator out,
  10091. RandomNumberGenerator& rng,
  10092. rand_int_type_tag)
  10093. {
  10094. // Note: The implied range will be: [min,max]
  10095. using namespace boost;
  10096. variate_generator<RandomNumberGenerator&,uniform_int<T> > rnd(rng,uniform_int<T>(min,max));
  10097. for (std::size_t i = 0; i < count; ++i, *out++ = rnd()) ;
  10098. }
  10099. template <typename T, typename OutputIterator, typename RandomNumberGenerator>
  10100. inline void generate_random_values_impl(const std::size_t& count,
  10101. const T& min,
  10102. const T& max,
  10103. OutputIterator out,
  10104. RandomNumberGenerator& rng,
  10105. rand_real_type_tag)
  10106. {
  10107. // Note: The implied range will be: [min,max)
  10108. using namespace boost;
  10109. variate_generator<RandomNumberGenerator&, uniform_real<T> > rnd(rng,uniform_real<T>(min,max));
  10110. for (std::size_t i = 0; i < count; ++i, *out++ = rnd()) ;
  10111. }
  10112. } // namespace details
  10113. class uniform_real_rng
  10114. {
  10115. private:
  10116. typedef boost::mt19937 rng_type;
  10117. typedef boost::variate_generator<rng_type, boost::uniform_real<double> > variate_type;
  10118. public:
  10119. uniform_real_rng(const std::size_t& seed = magic_seed,
  10120. std::size_t pregen = 0)
  10121. : rng_(static_cast<rng_type::result_type>(seed)),
  10122. rnd_(rng_,boost::uniform_real<double>(0.0,1.0))
  10123. {
  10124. while (pregen--) rng_();
  10125. }
  10126. inline double operator()()
  10127. {
  10128. return rnd_();
  10129. }
  10130. private:
  10131. rng_type rng_;
  10132. variate_type rnd_;
  10133. };
  10134. template <typename T, typename OutputIterator>
  10135. inline void generate_random_values(const std::size_t& count,
  10136. const T& min,
  10137. const T& max,
  10138. OutputIterator out,
  10139. const std::size_t& seed = magic_seed,
  10140. const std::size_t& pregen = 0)
  10141. {
  10142. typename details::supported_random_type<T>::type type;
  10143. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  10144. for (std::size_t i = 0; i++ < pregen; rng()) ;
  10145. generate_random_values_impl(count,min,max,out,rng,type);
  10146. }
  10147. template <typename T,
  10148. typename Allocator,
  10149. template <typename,typename> class Sequence>
  10150. inline void generate_random_values(const std::size_t& count,
  10151. const T& min,
  10152. const T& max,
  10153. Sequence<T,Allocator>& sequence,
  10154. const std::size_t& seed = magic_seed,
  10155. const std::size_t& pregen = 0)
  10156. {
  10157. typename details::supported_random_type<T>::type type;
  10158. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  10159. for (std::size_t i = 0; i++ < pregen; rng()) ;
  10160. generate_random_values_impl(count,min,max,std::back_inserter(sequence),rng,type);
  10161. }
  10162. template <typename Iterator,
  10163. typename RandomNumberGenerator,
  10164. typename OutputIterator>
  10165. inline void random_permutation(const Iterator begin, const Iterator end,
  10166. RandomNumberGenerator& rng,
  10167. OutputIterator out)
  10168. {
  10169. const std::size_t size = std::distance(begin,end);
  10170. if ((rng. min() < 0.0) || (rng.max() > 1.0)) return;
  10171. std::deque<std::size_t> index;
  10172. for (std::size_t i = 0; i < size; index.push_back(i++)) ;
  10173. while (!index.empty())
  10174. {
  10175. std::size_t idx = static_cast<std::size_t>(index.size() * rng());
  10176. (*out) = *(begin + index[idx]);
  10177. index.erase(index.begin() + idx);
  10178. ++out;
  10179. }
  10180. }
  10181. template <typename Iterator,
  10182. typename OutputIterator>
  10183. inline void random_permutation(const Iterator begin, const Iterator end,
  10184. OutputIterator out,
  10185. const std::size_t& seed = magic_seed,
  10186. const std::size_t& pregen = 0)
  10187. {
  10188. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  10189. for (std::size_t i = 0; i++ < pregen; rng()) ;
  10190. boost::uniform_real<double> dist(0.0,1.0);
  10191. boost::variate_generator<boost::mt19937&, boost::uniform_real<double> > rnd(rng,dist);
  10192. random_permutation(begin,end,rnd,out);
  10193. }
  10194. template <typename T,
  10195. typename Allocator,
  10196. template <typename,typename> class Sequence,
  10197. typename OutputIterator>
  10198. inline void random_permutation(const Sequence<T,Allocator>& sequence,
  10199. OutputIterator out,
  10200. const std::size_t& seed = magic_seed,
  10201. const std::size_t& pregen = 0)
  10202. {
  10203. random_permutation(sequence.begin(),sequence.end(),out,seed,pregen);
  10204. }
  10205. template <typename Iterator,
  10206. typename RandomNumberGenerator,
  10207. typename OutputIterator>
  10208. inline bool random_combination(const Iterator begin, const Iterator end,
  10209. std::size_t set_size,
  10210. RandomNumberGenerator& rng,
  10211. OutputIterator out)
  10212. {
  10213. const std::size_t size = std::distance(begin,end);
  10214. if ((size < set_size) || (rng. min() < 0.0) || (rng.max() > 1.0)) return false;
  10215. std::deque<std::size_t> index;
  10216. for (std::size_t i = 0; i < size; index.push_back(i++)) ;
  10217. while (set_size)
  10218. {
  10219. std::size_t idx = static_cast<std::size_t>(index.size() * rng());
  10220. (*out) = *(begin + index[idx]);
  10221. index.erase(index.begin() + idx);
  10222. ++out;
  10223. --set_size;
  10224. }
  10225. return true;
  10226. }
  10227. template <typename Iterator,
  10228. typename OutputIterator>
  10229. inline void random_combination(const Iterator begin, const Iterator end,
  10230. const std::size_t& set_size,
  10231. OutputIterator out,
  10232. const std::size_t& seed = magic_seed,
  10233. const std::size_t& pregen = 0)
  10234. {
  10235. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  10236. for (std::size_t i = 0; i++ < pregen; rng()) ;
  10237. boost::uniform_real<double> dist(0.0,1.0);
  10238. boost::variate_generator<boost::mt19937&, boost::uniform_real<double> > rnd(rng,dist);
  10239. random_combination(begin,end,set_size,rnd,out);
  10240. }
  10241. template <typename T,
  10242. typename Allocator,
  10243. template <typename,typename> class Sequence,
  10244. typename OutputIterator>
  10245. inline void random_combination(const Sequence<T,Allocator>& sequence,
  10246. const std::size_t& set_size,
  10247. OutputIterator out,
  10248. const std::size_t& seed = magic_seed,
  10249. const std::size_t& pregen = 0)
  10250. {
  10251. random_combination(sequence.begin(),sequence.end(),set_size,out,seed,pregen);
  10252. }
  10253. template <typename Iterator,
  10254. typename OutputIterator,
  10255. typename RandomNumberGenerator>
  10256. inline std::size_t select_k_randomly(const Iterator begin, const Iterator end,
  10257. const std::size_t k,
  10258. OutputIterator out,
  10259. RandomNumberGenerator& rng)
  10260. {
  10261. typedef typename std::iterator_traits<Iterator>::value_type T;
  10262. std::vector<T> selection;
  10263. selection.resize(k);
  10264. Iterator itr = begin;
  10265. std::size_t index = 0;
  10266. while ((index < k) && (end != itr))
  10267. {
  10268. selection[index] = (*itr);
  10269. ++index;
  10270. ++itr;
  10271. }
  10272. if (0 == index)
  10273. return 0;
  10274. else if (index < k)
  10275. {
  10276. std::copy(selection.begin(),selection.begin() + index, out);
  10277. return index;
  10278. }
  10279. double n = k + 1;
  10280. while (end != itr)
  10281. {
  10282. if (rng() < (k / n))
  10283. {
  10284. selection[static_cast<std::size_t>(rng() * k)] = (*itr);
  10285. }
  10286. ++itr;
  10287. ++n;
  10288. }
  10289. std::copy(selection.begin(),selection.end(),out);
  10290. return k;
  10291. }
  10292. template <typename Iterator,
  10293. typename OutputIterator,
  10294. typename RandomNumberGenerator>
  10295. inline void select_1_randomly(const Iterator begin, const Iterator end,
  10296. OutputIterator out,
  10297. RandomNumberGenerator& rng)
  10298. {
  10299. typedef typename std::iterator_traits<Iterator>::value_type T;
  10300. T selection;
  10301. if (begin == end)
  10302. return;
  10303. Iterator itr = begin;
  10304. std::size_t n = 0;
  10305. while (end != itr)
  10306. {
  10307. if (rng() < (1.0 / ++n))
  10308. {
  10309. selection = (*itr);
  10310. }
  10311. ++itr;
  10312. }
  10313. (*out) = selection;
  10314. ++out;
  10315. }
  10316. #endif // strtk_enable_random
  10317. template <typename Iterator>
  10318. inline bool next_combination(const Iterator first, Iterator k, const Iterator last)
  10319. {
  10320. /* Credits: Thomas Draper */
  10321. if ((first == last) || (first == k) || (last == k))
  10322. return false;
  10323. Iterator itr1 = first;
  10324. Iterator itr2 = last;
  10325. ++itr1;
  10326. if (last == itr1)
  10327. return false;
  10328. itr1 = last;
  10329. --itr1;
  10330. itr1 = k;
  10331. --itr2;
  10332. while (first != itr1)
  10333. {
  10334. if (*--itr1 < (*itr2))
  10335. {
  10336. Iterator j = k;
  10337. while (!((*itr1) < (*j))) ++j;
  10338. std::iter_swap(itr1,j);
  10339. ++itr1;
  10340. ++j;
  10341. itr2 = k;
  10342. std::rotate(itr1,j,last);
  10343. while (last != j)
  10344. {
  10345. ++j;
  10346. ++itr2;
  10347. }
  10348. std::rotate(k,itr2,last);
  10349. return true;
  10350. }
  10351. }
  10352. std::rotate(first,k,last);
  10353. return false;
  10354. }
  10355. template <typename T,
  10356. typename Allocator,
  10357. template <typename,typename> class Sequence>
  10358. inline bool next_combination(Sequence<T,Allocator>& sequence, const std::size_t& size)
  10359. {
  10360. return next_combination(sequence.begin(), sequence.begin() + size, sequence.end());
  10361. }
  10362. template <typename Iterator, typename Function>
  10363. inline void for_each_permutation(Iterator begin, Iterator end, Function function)
  10364. {
  10365. do
  10366. {
  10367. function(begin,end);
  10368. }
  10369. while (std::next_permutation(begin,end));
  10370. }
  10371. template <typename Iterator, typename Function>
  10372. inline bool for_each_permutation_conditional(Iterator begin, Iterator end, Function function)
  10373. {
  10374. do
  10375. {
  10376. if (!function(begin,end))
  10377. return false;
  10378. }
  10379. while (std::next_permutation(begin,end));
  10380. return true;
  10381. }
  10382. namespace details
  10383. {
  10384. /*
  10385. Credits:
  10386. (C) Copyright Howard Hinnant 2005-2011.
  10387. Use, modification and distribution are subject to the Boost Software License,
  10388. Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  10389. http://www.boost.org/LICENSE_1_0.txt).
  10390. */
  10391. template <typename Iterator>
  10392. static inline void rotate_discontinuous(Iterator first1, Iterator last1,
  10393. typename std::iterator_traits<Iterator>::difference_type d1,
  10394. Iterator first2, Iterator last2,
  10395. typename std::iterator_traits<Iterator>::difference_type d2)
  10396. {
  10397. using std::swap;
  10398. if (d1 <= d2)
  10399. std::rotate(first2, std::swap_ranges(first1, last1, first2), last2);
  10400. else
  10401. {
  10402. Iterator i1 = last1;
  10403. while (first2 != last2)
  10404. {
  10405. swap(*--i1,*--last2);
  10406. }
  10407. std::rotate(first1, i1, last1);
  10408. }
  10409. }
  10410. template <typename Iterator, class Function>
  10411. inline void combine_discontinuous(Iterator first1, Iterator last1, typename std::iterator_traits<Iterator>::difference_type d1,
  10412. Iterator first2, Iterator last2, typename std::iterator_traits<Iterator>::difference_type d2,
  10413. Function& f,
  10414. typename std::iterator_traits<Iterator>::difference_type d = 0)
  10415. {
  10416. typedef typename std::iterator_traits<Iterator>::difference_type D;
  10417. using std::swap;
  10418. if ((0 == d1) || (0 == d2))
  10419. return f();
  10420. if (1 == d1)
  10421. {
  10422. Iterator i2 = first2;
  10423. while (i2 != last2)
  10424. {
  10425. f();
  10426. swap(*first1, *i2);
  10427. ++i2;
  10428. }
  10429. }
  10430. else
  10431. {
  10432. Iterator f1p = first1;
  10433. std::advance(f1p,1);
  10434. Iterator i2 = first2;
  10435. D d22 = d2;
  10436. while (i2 != last2)
  10437. {
  10438. combine_discontinuous(f1p, last1, d1 - 1, i2, last2, d22, f, d + 1);
  10439. swap(*first1, *i2);
  10440. ++i2;
  10441. --d22;
  10442. }
  10443. }
  10444. f();
  10445. if (0 != d)
  10446. {
  10447. Iterator f2p = first2;
  10448. std::advance(f2p,1);
  10449. rotate_discontinuous(first1, last1, d1, f2p, last2, d2 - 1);
  10450. }
  10451. else
  10452. rotate_discontinuous(first1, last1, d1, first2, last2, d2);
  10453. }
  10454. template <typename Iterator, class Function>
  10455. inline bool combine_discontinuous_conditional(Iterator first1, Iterator last1, typename std::iterator_traits<Iterator>::difference_type d1,
  10456. Iterator first2, Iterator last2, typename std::iterator_traits<Iterator>::difference_type d2,
  10457. Function& f,
  10458. typename std::iterator_traits<Iterator>::difference_type d = 0)
  10459. {
  10460. typedef typename std::iterator_traits<Iterator>::difference_type D;
  10461. using std::swap;
  10462. if (d1 == 0 || d2 == 0)
  10463. return f();
  10464. if (d1 == 1)
  10465. {
  10466. for (Iterator i2 = first2; i2 != last2; ++i2)
  10467. {
  10468. if (!f())
  10469. return false;
  10470. swap(*first1, *i2);
  10471. }
  10472. }
  10473. else
  10474. {
  10475. Iterator f1p = first1;
  10476. std::advance(f1p,1);
  10477. Iterator i2 = first2;
  10478. for (D d22 = d2; i2 != last2; ++i2, --d22)
  10479. {
  10480. if (!combine_discontinuous_conditional(f1p, last1, d1-1, i2, last2, d22, f, d + 1))
  10481. return false;
  10482. swap(*first1, *i2);
  10483. }
  10484. }
  10485. if (!f())
  10486. return false;
  10487. if (d != 0)
  10488. {
  10489. Iterator f2p = first2;
  10490. std::advance(f2p,1);
  10491. rotate_discontinuous(first1, last1, d1, f2p, last2, d2 - 1);
  10492. }
  10493. else
  10494. rotate_discontinuous(first1, last1, d1, first2, last2, d2);
  10495. return true;
  10496. }
  10497. template <class Function, typename Iterator>
  10498. class bound_range
  10499. {
  10500. public:
  10501. bound_range(Function f, Iterator first, Iterator last)
  10502. : f_(f),
  10503. first_(first),
  10504. last_(last)
  10505. {}
  10506. inline void operator()()
  10507. {
  10508. f_(first_,last_);
  10509. }
  10510. private:
  10511. inline bound_range& operator=(const bound_range&);
  10512. Function f_;
  10513. Iterator first_;
  10514. Iterator last_;
  10515. };
  10516. template <class Function, typename Iterator>
  10517. class bound_range_conditional
  10518. {
  10519. public:
  10520. bound_range_conditional(Function f, Iterator first, Iterator last)
  10521. : f_(f),
  10522. first_(first),
  10523. last_(last)
  10524. {}
  10525. inline bool operator()()
  10526. {
  10527. return f_(first_,last_);
  10528. }
  10529. private:
  10530. inline bound_range_conditional& operator=(const bound_range_conditional&);
  10531. Function f_;
  10532. Iterator first_;
  10533. Iterator last_;
  10534. };
  10535. }
  10536. template <typename Iterator, typename Function>
  10537. inline void for_each_combination(Iterator begin, Iterator end,
  10538. const std::size_t& size,
  10539. Function function)
  10540. {
  10541. if (static_cast<typename std::iterator_traits<Iterator>::difference_type>(size) > std::distance(begin,end))
  10542. return;
  10543. Iterator mid = begin + size;
  10544. details::bound_range<Function&,Iterator> func(function,begin,mid);
  10545. details::combine_discontinuous(begin, mid,
  10546. std::distance(begin,mid),
  10547. mid, end,
  10548. std::distance(mid,end),
  10549. func);
  10550. }
  10551. template <typename Iterator, typename Function>
  10552. inline void for_each_combination_conditional(Iterator begin, Iterator end,
  10553. const std::size_t& size,
  10554. Function function)
  10555. {
  10556. if (static_cast<typename std::iterator_traits<Iterator>::difference_type>(size) > std::distance(begin,end))
  10557. return;
  10558. Iterator mid = begin + size;
  10559. details::bound_range_conditional<Function&,Iterator> func(function,begin,mid);
  10560. details::combine_discontinuous_conditional(begin, mid,
  10561. std::distance(begin,mid),
  10562. mid, end,
  10563. std::distance(mid,end),
  10564. func);
  10565. }
  10566. inline unsigned long long int n_choose_k(const unsigned long long int& n, const unsigned long long int& k)
  10567. {
  10568. if (n < k) return 0;
  10569. if (0 == n) return 0;
  10570. if (0 == k) return 1;
  10571. if (n == k) return 1;
  10572. if (1 == k) return n;
  10573. typedef unsigned long long int value_type;
  10574. class n_choose_k_impl
  10575. {
  10576. public:
  10577. n_choose_k_impl(value_type* table, const value_type& dimension)
  10578. : table_(table),
  10579. dimension_(dimension / 2)
  10580. {}
  10581. inline value_type& lookup(const value_type& n, const value_type& k)
  10582. {
  10583. const std::size_t difference = static_cast<std::size_t>(n - k);
  10584. return table_[static_cast<std::size_t>((dimension_ * n) + std::min<value_type>(k,difference))];
  10585. }
  10586. inline value_type compute(const value_type& n, const value_type& k)
  10587. {
  10588. // n-Choose-k = (n-1)-Choose-(k-1) + (n-1)-Choose-k
  10589. if ((0 == k) || (k == n))
  10590. return 1;
  10591. value_type v1 = lookup(n - 1,k - 1);
  10592. if (0 == v1)
  10593. v1 = lookup(n - 1,k - 1) = compute(n - 1,k - 1);
  10594. value_type v2 = lookup(n - 1,k);
  10595. if (0 == v2)
  10596. v2 = lookup(n - 1,k) = compute(n - 1,k);
  10597. return v1 + v2;
  10598. }
  10599. value_type* table_;
  10600. const value_type dimension_;
  10601. private:
  10602. inline n_choose_k_impl& operator=(const n_choose_k_impl&)
  10603. {
  10604. return *this;
  10605. }
  10606. };
  10607. static const std::size_t static_table_dim = 100;
  10608. static const std::size_t static_table_size = static_cast<std::size_t>((static_table_dim * static_table_dim) / 2);
  10609. static value_type static_table[static_table_size];
  10610. static bool static_table_initialized = false;
  10611. if (!static_table_initialized && (n <= static_table_dim))
  10612. {
  10613. std::fill_n(static_table,static_table_size,0);
  10614. static_table_initialized = true;
  10615. }
  10616. const std::size_t table_size = static_cast<std::size_t>(n * (n / 2) + (n & 1));
  10617. unsigned long long int dimension = static_table_dim;
  10618. value_type* table = 0;
  10619. if (table_size <= static_table_size)
  10620. table = static_table;
  10621. else
  10622. {
  10623. dimension = n;
  10624. table = new value_type[table_size];
  10625. std::fill_n(table,table_size,0ULL);
  10626. }
  10627. value_type result = n_choose_k_impl(table,dimension).compute(n,k);
  10628. if (table != static_table)
  10629. delete [] table;
  10630. return result;
  10631. }
  10632. inline void initialize_n_choose_k()
  10633. {
  10634. const unsigned long long int max_n = 100ULL;
  10635. for (unsigned long long int n = 0; n < max_n; ++n)
  10636. {
  10637. for (unsigned long long int k = 0; k < max_n; ++k)
  10638. {
  10639. n_choose_k(n,k);
  10640. }
  10641. }
  10642. }
  10643. template <typename OutputIterator>
  10644. inline void nth_combination_sequence(unsigned long long int n,
  10645. const std::size_t& r,
  10646. const std::size_t& k,
  10647. OutputIterator out,
  10648. const bool complete_index = true)
  10649. {
  10650. //Compute the indicies for the n'th combination of r-choose-k
  10651. //n must be in the range [0,r-choose-k)
  10652. typedef unsigned long long int value_type;
  10653. std::vector<std::size_t> index_list(k,0);
  10654. value_type j = 0;
  10655. value_type x = 0;
  10656. ++n;
  10657. for (std::size_t i = 1; i <= (k - 1); ++i)
  10658. {
  10659. index_list[i - 1] = 0;
  10660. if (1 < i)
  10661. {
  10662. index_list[i - 1] = index_list[i - 2];
  10663. }
  10664. do
  10665. {
  10666. index_list[i - 1] += 1;
  10667. j = n_choose_k(r - index_list[i - 1], k - i);
  10668. x += j;
  10669. }
  10670. while (n > x);
  10671. x -= j;
  10672. }
  10673. index_list[k - 1] = index_list[k - 2] + static_cast<std::size_t>(n) - static_cast<std::size_t>(x);
  10674. for (std::size_t i = 0; i < index_list.size(); --index_list[i++]);
  10675. std::copy(index_list.begin(),index_list.end(),out);
  10676. if (complete_index)
  10677. {
  10678. std::vector<unsigned int> exist_table(r,0);
  10679. for (std::size_t i = 0; i < index_list.size(); ++i)
  10680. {
  10681. exist_table[index_list[i]] = 1;
  10682. }
  10683. for (std::size_t i = 0; i < exist_table.size(); ++i)
  10684. {
  10685. if (0 == exist_table[i])
  10686. {
  10687. (*out) = i;
  10688. ++out;
  10689. }
  10690. }
  10691. }
  10692. }
  10693. template <typename InputIterator, typename OutputIterator>
  10694. inline void nth_combination_sequence(const std::size_t& n,
  10695. const std::size_t& k,
  10696. const InputIterator begin,
  10697. const InputIterator end,
  10698. OutputIterator out,
  10699. const bool complete_index = true)
  10700. {
  10701. const std::size_t length = std::distance(begin,end);
  10702. std::vector<std::size_t> index_list;
  10703. nth_combination_sequence(n,length,k,std::back_inserter(index_list),complete_index);
  10704. for (std::size_t i = 0; i < index_list.size(); ++i)
  10705. {
  10706. (*out) = *(begin + index_list[i]);
  10707. ++out;
  10708. }
  10709. }
  10710. template <typename OutputIterator>
  10711. inline void nth_permutation_sequence(std::size_t n, const std::size_t k, OutputIterator out)
  10712. {
  10713. //Note: n in [0,k!)
  10714. std::vector<std::size_t> factorid (k,0);
  10715. std::vector<std::size_t> permutate(k,0);
  10716. factorid[0] = 1;
  10717. for (std::size_t i = 1; i < k; ++i)
  10718. {
  10719. factorid[i] = factorid[i - 1] * i;
  10720. }
  10721. for (std::size_t i = 0; i < k; ++i)
  10722. {
  10723. permutate[i] = n / factorid[k - i - 1];
  10724. n = n % factorid[k - i - 1];
  10725. }
  10726. for (std::size_t i = k - 1; i > 0; --i)
  10727. {
  10728. for (int j = static_cast<int>(i - 1); j >= 0; --j)
  10729. {
  10730. if (permutate[j] <= permutate[i])
  10731. {
  10732. ++permutate[i];
  10733. }
  10734. }
  10735. }
  10736. for (std::size_t i = 0; i < k; ++i)
  10737. {
  10738. *(out++) = permutate[i];
  10739. }
  10740. }
  10741. template <typename InputIterator, typename OutputIterator>
  10742. inline void nth_permutation_sequence(std::size_t n,
  10743. const InputIterator begin,
  10744. const InputIterator end,
  10745. OutputIterator out)
  10746. {
  10747. const std::size_t size = std::distance(begin,end);
  10748. std::vector<std::size_t> index_list(size,0);
  10749. nth_permutation_sequence(n,size,index_list.begin());
  10750. for (std::size_t i = 0; i < size; ++i)
  10751. {
  10752. *(out++) = (begin + index_list[i]);
  10753. }
  10754. }
  10755. inline std::string nth_permutation_sequence(const std::size_t& n, const std::string& s)
  10756. {
  10757. std::vector<std::size_t> index_list(s.size(),0);
  10758. nth_permutation_sequence(n,s.size(),index_list.begin());
  10759. std::string result;
  10760. result.reserve(s.size());
  10761. for (std::size_t i = 0; i < index_list.size(); ++i)
  10762. {
  10763. result += s[index_list[i]];
  10764. }
  10765. return result;
  10766. }
  10767. template <typename Iterator>
  10768. class combination_iterator : public std::iterator<std::forward_iterator_tag,
  10769. std::pair<Iterator,Iterator>,
  10770. void,
  10771. void>
  10772. {
  10773. public:
  10774. typedef Iterator iterator;
  10775. typedef const iterator const_iterator;
  10776. typedef std::pair<Iterator,Iterator> range_type;
  10777. explicit inline combination_iterator(const std::size_t& k,
  10778. iterator begin, iterator end,
  10779. const bool sorted = true)
  10780. : begin_(begin),
  10781. end_(end),
  10782. middle_(begin + k),
  10783. current_combination_(begin_,middle_)
  10784. {
  10785. if (!sorted)
  10786. {
  10787. std::sort(begin,end);
  10788. }
  10789. }
  10790. template <typename T,
  10791. typename Allocator,
  10792. template <typename,typename> class Sequence>
  10793. explicit inline combination_iterator(const std::size_t& k,
  10794. Sequence<T,Allocator>& seq,
  10795. const bool sorted = true)
  10796. : begin_(seq.begin()),
  10797. end_(seq.end()),
  10798. middle_(begin_ + k),
  10799. current_combination_(begin_,middle_)
  10800. {
  10801. if (!sorted)
  10802. {
  10803. std::sort(begin_,end_);
  10804. }
  10805. }
  10806. explicit inline combination_iterator(const std::size_t& k,
  10807. std::string& str,
  10808. const bool sorted = true)
  10809. : begin_(const_cast<char*>(str.data())),
  10810. end_(const_cast<char*>(str.data() + str.size())),
  10811. middle_(begin_ + k),
  10812. current_combination_(begin_,middle_)
  10813. {
  10814. if (!sorted)
  10815. {
  10816. std::sort(begin_,end_);
  10817. }
  10818. }
  10819. inline combination_iterator(iterator end)
  10820. : begin_(end),
  10821. end_(end),
  10822. middle_(end),
  10823. current_combination_(end,end)
  10824. {}
  10825. inline combination_iterator(const std::string& str)
  10826. : begin_(const_cast<char*>(str.data() + str.size())),
  10827. end_(begin_),
  10828. middle_(end_),
  10829. current_combination_(end_,end_)
  10830. {}
  10831. template <typename T,
  10832. typename Allocator,
  10833. template <typename,typename> class Sequence>
  10834. explicit inline combination_iterator(Sequence<T,Allocator>& seq)
  10835. : begin_(seq.end()),
  10836. end_(seq.end()),
  10837. middle_(end_),
  10838. current_combination_(end_,end_)
  10839. {}
  10840. inline combination_iterator& operator++()
  10841. {
  10842. if (begin_ != end_)
  10843. {
  10844. if (!next_combination(begin_,middle_,end_))
  10845. {
  10846. begin_ = middle_ = end_;
  10847. }
  10848. }
  10849. return (*this);
  10850. }
  10851. inline combination_iterator operator++(int)
  10852. {
  10853. combination_iterator tmp = *this;
  10854. this->operator++();
  10855. return tmp;
  10856. }
  10857. inline combination_iterator& operator+=(const int inc)
  10858. {
  10859. if (inc > 0)
  10860. {
  10861. for (int i = 0; i < inc; ++i, ++(*this)) ;
  10862. }
  10863. return (*this);
  10864. }
  10865. inline range_type operator*() const
  10866. {
  10867. return current_combination_;
  10868. }
  10869. inline bool operator==(const combination_iterator& itr) const
  10870. {
  10871. return (begin_ == itr.begin_ ) &&
  10872. (end_ == itr.end_ ) &&
  10873. (middle_ == itr.middle_);
  10874. }
  10875. inline bool operator!=(const combination_iterator& itr) const
  10876. {
  10877. return !operator==(itr);
  10878. }
  10879. protected:
  10880. iterator begin_;
  10881. iterator end_;
  10882. iterator middle_;
  10883. range_type current_combination_;
  10884. };
  10885. namespace fast
  10886. {
  10887. /*
  10888. Note: The following routines perform no sanity checks at all
  10889. upon the input data. Hence they should only be used with
  10890. data that is known to be completely 'valid'.
  10891. */
  10892. namespace details
  10893. {
  10894. template <typename Iterator, int N>
  10895. struct all_digits_check_impl
  10896. {
  10897. static inline bool process(Iterator)
  10898. {
  10899. throw std::runtime_error("all_digits_check_impl - unsupported value for N.");
  10900. }
  10901. };
  10902. template <typename Iterator>
  10903. struct all_digits_check_impl<Iterator,19>
  10904. {
  10905. static inline bool process(Iterator itr)
  10906. {
  10907. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10908. all_digits_check_impl<Iterator,18>::process(itr + 1);
  10909. }
  10910. };
  10911. template <typename Iterator>
  10912. struct all_digits_check_impl<Iterator,18>
  10913. {
  10914. static inline bool process(Iterator itr)
  10915. {
  10916. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10917. all_digits_check_impl<Iterator,17>::process(itr + 1);
  10918. }
  10919. };
  10920. template <typename Iterator>
  10921. struct all_digits_check_impl<Iterator,17>
  10922. {
  10923. static inline bool process(Iterator itr)
  10924. {
  10925. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10926. all_digits_check_impl<Iterator,16>::process(itr + 1);
  10927. }
  10928. };
  10929. template <typename Iterator>
  10930. struct all_digits_check_impl<Iterator,16>
  10931. {
  10932. static inline bool process(Iterator itr)
  10933. {
  10934. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  10935. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  10936. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  10937. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  10938. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  10939. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  10940. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  10941. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  10942. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  10943. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  10944. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  10945. static_cast<unsigned char>(itr[11] - '0') < 10 &&
  10946. static_cast<unsigned char>(itr[12] - '0') < 10 &&
  10947. static_cast<unsigned char>(itr[13] - '0') < 10 &&
  10948. static_cast<unsigned char>(itr[14] - '0') < 10 &&
  10949. static_cast<unsigned char>(itr[15] - '0') < 10;
  10950. }
  10951. };
  10952. template <typename Iterator>
  10953. struct all_digits_check_impl<Iterator,15>
  10954. {
  10955. static inline bool process(Iterator itr)
  10956. {
  10957. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  10958. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  10959. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  10960. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  10961. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  10962. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  10963. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  10964. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  10965. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  10966. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  10967. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  10968. static_cast<unsigned char>(itr[11] - '0') < 10 &&
  10969. static_cast<unsigned char>(itr[12] - '0') < 10 &&
  10970. static_cast<unsigned char>(itr[13] - '0') < 10 &&
  10971. static_cast<unsigned char>(itr[14] - '0') < 10;
  10972. }
  10973. };
  10974. template <typename Iterator>
  10975. struct all_digits_check_impl<Iterator,14>
  10976. {
  10977. static inline bool process(Iterator itr)
  10978. {
  10979. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  10980. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  10981. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  10982. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  10983. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  10984. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  10985. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  10986. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  10987. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  10988. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  10989. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  10990. static_cast<unsigned char>(itr[11] - '0') < 10 &&
  10991. static_cast<unsigned char>(itr[12] - '0') < 10 &&
  10992. static_cast<unsigned char>(itr[13] - '0') < 10;
  10993. }
  10994. };
  10995. template <typename Iterator>
  10996. struct all_digits_check_impl<Iterator,13>
  10997. {
  10998. static inline bool process(Iterator itr)
  10999. {
  11000. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  11001. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  11002. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  11003. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  11004. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  11005. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  11006. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  11007. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  11008. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  11009. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  11010. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  11011. static_cast<unsigned char>(itr[11] - '0') < 10 &&
  11012. static_cast<unsigned char>(itr[12] - '0') < 10;
  11013. }
  11014. };
  11015. template <typename Iterator>
  11016. struct all_digits_check_impl<Iterator,12>
  11017. {
  11018. static inline bool process(Iterator itr)
  11019. {
  11020. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  11021. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  11022. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  11023. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  11024. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  11025. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  11026. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  11027. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  11028. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  11029. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  11030. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  11031. static_cast<unsigned char>(itr[11] - '0') < 10;
  11032. }
  11033. };
  11034. template <typename Iterator>
  11035. struct all_digits_check_impl<Iterator,11>
  11036. {
  11037. static inline bool process(Iterator itr)
  11038. {
  11039. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  11040. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  11041. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  11042. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  11043. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  11044. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  11045. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  11046. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  11047. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  11048. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  11049. static_cast<unsigned char>(itr[10] - '0') < 10;
  11050. }
  11051. };
  11052. template <typename Iterator>
  11053. struct all_digits_check_impl<Iterator,10>
  11054. {
  11055. static inline bool process(Iterator itr)
  11056. {
  11057. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11058. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11059. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11060. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  11061. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  11062. static_cast<unsigned char>(itr[5] - '0') < 10 &&
  11063. static_cast<unsigned char>(itr[6] - '0') < 10 &&
  11064. static_cast<unsigned char>(itr[7] - '0') < 10 &&
  11065. static_cast<unsigned char>(itr[8] - '0') < 10 &&
  11066. static_cast<unsigned char>(itr[9] - '0') < 10;
  11067. }
  11068. };
  11069. template <typename Iterator>
  11070. struct all_digits_check_impl<Iterator,9>
  11071. {
  11072. static inline bool process(Iterator itr)
  11073. {
  11074. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11075. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11076. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11077. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  11078. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  11079. static_cast<unsigned char>(itr[5] - '0') < 10 &&
  11080. static_cast<unsigned char>(itr[6] - '0') < 10 &&
  11081. static_cast<unsigned char>(itr[7] - '0') < 10 &&
  11082. static_cast<unsigned char>(itr[8] - '0') < 10;
  11083. }
  11084. };
  11085. template <typename Iterator>
  11086. struct all_digits_check_impl<Iterator,8>
  11087. {
  11088. static inline bool process(Iterator itr)
  11089. {
  11090. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11091. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11092. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11093. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  11094. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  11095. static_cast<unsigned char>(itr[5] - '0') < 10 &&
  11096. static_cast<unsigned char>(itr[6] - '0') < 10 &&
  11097. static_cast<unsigned char>(itr[7] - '0') < 10;
  11098. }
  11099. };
  11100. template <typename Iterator>
  11101. struct all_digits_check_impl<Iterator,7>
  11102. {
  11103. static inline bool process(Iterator itr)
  11104. {
  11105. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11106. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11107. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11108. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  11109. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  11110. static_cast<unsigned char>(itr[5] - '0') < 10 &&
  11111. static_cast<unsigned char>(itr[6] - '0') < 10;
  11112. }
  11113. };
  11114. template <typename Iterator>
  11115. struct all_digits_check_impl<Iterator,6>
  11116. {
  11117. static inline bool process(Iterator itr)
  11118. {
  11119. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11120. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11121. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11122. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  11123. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  11124. static_cast<unsigned char>(itr[5] - '0') < 10;
  11125. }
  11126. };
  11127. template <typename Iterator>
  11128. struct all_digits_check_impl<Iterator,5>
  11129. {
  11130. static inline bool process(Iterator itr)
  11131. {
  11132. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11133. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11134. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11135. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  11136. static_cast<unsigned char>(itr[4] - '0') < 10;
  11137. }
  11138. };
  11139. template <typename Iterator>
  11140. struct all_digits_check_impl<Iterator,4>
  11141. {
  11142. static inline bool process(Iterator itr)
  11143. {
  11144. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11145. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11146. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11147. static_cast<unsigned char>(itr[3] - '0') < 10;
  11148. }
  11149. };
  11150. template <typename Iterator>
  11151. struct all_digits_check_impl<Iterator,3>
  11152. {
  11153. static inline bool process(Iterator itr)
  11154. {
  11155. return
  11156. static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11157. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11158. static_cast<unsigned char>(itr[2] - '0') < 10;
  11159. }
  11160. };
  11161. template <typename Iterator>
  11162. struct all_digits_check_impl<Iterator,2>
  11163. {
  11164. static inline bool process(Iterator itr)
  11165. {
  11166. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  11167. static_cast<unsigned char>(itr[ 1] - '0') < 10;
  11168. }
  11169. };
  11170. template <typename Iterator>
  11171. struct all_digits_check_impl<Iterator,1>
  11172. {
  11173. static inline bool process(Iterator itr)
  11174. {
  11175. return static_cast<unsigned char>(itr[ 0] - '0') < 10;
  11176. }
  11177. };
  11178. template <typename Iterator>
  11179. struct all_digits_check_impl<Iterator,0>
  11180. {
  11181. static inline bool process(Iterator)
  11182. {
  11183. return true;
  11184. }
  11185. };
  11186. template <typename T, typename Iterator, int N>
  11187. struct numeric_convert_impl
  11188. {
  11189. static inline void process(Iterator, T&)
  11190. { throw std::runtime_error("numeric_convert_impl::process( - unsupported value for N."); }
  11191. };
  11192. template <typename T, typename Iterator>
  11193. struct numeric_convert_impl<T,Iterator,19>
  11194. {
  11195. static inline void process(const Iterator itr, T& t)
  11196. {
  11197. strtk::fast::details::numeric_convert_impl<T,Iterator,18>::process(itr + 1,t);
  11198. t += static_cast<T>((itr[0] - '0') * 1000000000000000000LL);
  11199. }
  11200. };
  11201. template <typename T, typename Iterator>
  11202. struct numeric_convert_impl<T,Iterator,18>
  11203. {
  11204. static inline void process(const Iterator itr, T& t)
  11205. {
  11206. strtk::fast::details::numeric_convert_impl<T,Iterator,17>::process(itr + 1,t);
  11207. t += static_cast<T>((itr[0] - '0') * 100000000000000000LL);
  11208. }
  11209. };
  11210. template <typename T, typename Iterator>
  11211. struct numeric_convert_impl<T,Iterator,17>
  11212. {
  11213. static inline void process(const Iterator itr, T& t)
  11214. {
  11215. numeric_convert_impl<T,Iterator,16>::process(itr + 1,t);
  11216. t += static_cast<T>((itr[0] - '0') * 10000000000000000LL);
  11217. }
  11218. };
  11219. template <typename T, typename Iterator>
  11220. struct numeric_convert_impl<T,Iterator,16>
  11221. {
  11222. static inline void process(const Iterator itr, T& t)
  11223. {
  11224. T x = static_cast<T>(itr[ 0] - '0');
  11225. x = x * 10 + static_cast<T>(itr[ 1] - '0');
  11226. x = x * 10 + static_cast<T>(itr[ 2] - '0');
  11227. x = x * 10 + static_cast<T>(itr[ 3] - '0');
  11228. x = x * 10 + static_cast<T>(itr[ 4] - '0');
  11229. x = x * 10 + static_cast<T>(itr[ 5] - '0');
  11230. x = x * 10 + static_cast<T>(itr[ 6] - '0');
  11231. x = x * 10 + static_cast<T>(itr[ 7] - '0');
  11232. x = x * 10 + static_cast<T>(itr[ 8] - '0');
  11233. x = x * 10 + static_cast<T>(itr[ 9] - '0');
  11234. x = x * 10 + static_cast<T>(itr[10] - '0');
  11235. x = x * 10 + static_cast<T>(itr[11] - '0');
  11236. x = x * 10 + static_cast<T>(itr[12] - '0');
  11237. x = x * 10 + static_cast<T>(itr[13] - '0');
  11238. x = x * 10 + static_cast<T>(itr[14] - '0');
  11239. x = x * 10 + static_cast<T>(itr[15] - '0');
  11240. t = x;
  11241. }
  11242. };
  11243. template <typename T, typename Iterator>
  11244. struct numeric_convert_impl<T,Iterator,15>
  11245. {
  11246. static inline void process(const Iterator itr, T& t)
  11247. {
  11248. T x = static_cast<T>(itr[ 0] - '0');
  11249. x = x * 10 + static_cast<T>(itr[ 1] - '0');
  11250. x = x * 10 + static_cast<T>(itr[ 2] - '0');
  11251. x = x * 10 + static_cast<T>(itr[ 3] - '0');
  11252. x = x * 10 + static_cast<T>(itr[ 4] - '0');
  11253. x = x * 10 + static_cast<T>(itr[ 5] - '0');
  11254. x = x * 10 + static_cast<T>(itr[ 6] - '0');
  11255. x = x * 10 + static_cast<T>(itr[ 7] - '0');
  11256. x = x * 10 + static_cast<T>(itr[ 8] - '0');
  11257. x = x * 10 + static_cast<T>(itr[ 9] - '0');
  11258. x = x * 10 + static_cast<T>(itr[10] - '0');
  11259. x = x * 10 + static_cast<T>(itr[11] - '0');
  11260. x = x * 10 + static_cast<T>(itr[12] - '0');
  11261. x = x * 10 + static_cast<T>(itr[13] - '0');
  11262. x = x * 10 + static_cast<T>(itr[14] - '0');
  11263. t = x;
  11264. }
  11265. };
  11266. template <typename T, typename Iterator>
  11267. struct numeric_convert_impl<T,Iterator,14>
  11268. {
  11269. static inline void process(const Iterator itr, T& t)
  11270. {
  11271. T x = static_cast<T>(itr[ 0] - '0');
  11272. x = x * 10 + static_cast<T>(itr[ 1] - '0');
  11273. x = x * 10 + static_cast<T>(itr[ 2] - '0');
  11274. x = x * 10 + static_cast<T>(itr[ 3] - '0');
  11275. x = x * 10 + static_cast<T>(itr[ 4] - '0');
  11276. x = x * 10 + static_cast<T>(itr[ 5] - '0');
  11277. x = x * 10 + static_cast<T>(itr[ 6] - '0');
  11278. x = x * 10 + static_cast<T>(itr[ 7] - '0');
  11279. x = x * 10 + static_cast<T>(itr[ 8] - '0');
  11280. x = x * 10 + static_cast<T>(itr[ 9] - '0');
  11281. x = x * 10 + static_cast<T>(itr[10] - '0');
  11282. x = x * 10 + static_cast<T>(itr[11] - '0');
  11283. x = x * 10 + static_cast<T>(itr[12] - '0');
  11284. x = x * 10 + static_cast<T>(itr[13] - '0');
  11285. t = x;
  11286. }
  11287. };
  11288. template <typename T, typename Iterator>
  11289. struct numeric_convert_impl<T,Iterator,13>
  11290. {
  11291. static inline void process(const Iterator itr, T& t)
  11292. {
  11293. T x = static_cast<T>(itr[ 0] - '0');
  11294. x = x * 10 + static_cast<T>(itr[ 1] - '0');
  11295. x = x * 10 + static_cast<T>(itr[ 2] - '0');
  11296. x = x * 10 + static_cast<T>(itr[ 3] - '0');
  11297. x = x * 10 + static_cast<T>(itr[ 4] - '0');
  11298. x = x * 10 + static_cast<T>(itr[ 5] - '0');
  11299. x = x * 10 + static_cast<T>(itr[ 6] - '0');
  11300. x = x * 10 + static_cast<T>(itr[ 7] - '0');
  11301. x = x * 10 + static_cast<T>(itr[ 8] - '0');
  11302. x = x * 10 + static_cast<T>(itr[ 9] - '0');
  11303. x = x * 10 + static_cast<T>(itr[10] - '0');
  11304. x = x * 10 + static_cast<T>(itr[11] - '0');
  11305. x = x * 10 + static_cast<T>(itr[12] - '0');
  11306. t = x;
  11307. }
  11308. };
  11309. template <typename T, typename Iterator>
  11310. struct numeric_convert_impl<T,Iterator,12>
  11311. {
  11312. static inline void process(const Iterator itr, T& t)
  11313. {
  11314. T x = static_cast<T>(itr[ 0] - '0');
  11315. x = x * 10 + static_cast<T>(itr[ 1] - '0');
  11316. x = x * 10 + static_cast<T>(itr[ 2] - '0');
  11317. x = x * 10 + static_cast<T>(itr[ 3] - '0');
  11318. x = x * 10 + static_cast<T>(itr[ 4] - '0');
  11319. x = x * 10 + static_cast<T>(itr[ 5] - '0');
  11320. x = x * 10 + static_cast<T>(itr[ 6] - '0');
  11321. x = x * 10 + static_cast<T>(itr[ 7] - '0');
  11322. x = x * 10 + static_cast<T>(itr[ 8] - '0');
  11323. x = x * 10 + static_cast<T>(itr[ 9] - '0');
  11324. x = x * 10 + static_cast<T>(itr[10] - '0');
  11325. x = x * 10 + static_cast<T>(itr[11] - '0');
  11326. t = x;
  11327. }
  11328. };
  11329. template <typename T, typename Iterator>
  11330. struct numeric_convert_impl<T,Iterator,11>
  11331. {
  11332. static inline void process(const Iterator itr, T& t)
  11333. {
  11334. T x = static_cast<T>(itr[ 0] - '0');
  11335. x = x * 10 + static_cast<T>(itr[ 1] - '0');
  11336. x = x * 10 + static_cast<T>(itr[ 2] - '0');
  11337. x = x * 10 + static_cast<T>(itr[ 3] - '0');
  11338. x = x * 10 + static_cast<T>(itr[ 4] - '0');
  11339. x = x * 10 + static_cast<T>(itr[ 5] - '0');
  11340. x = x * 10 + static_cast<T>(itr[ 6] - '0');
  11341. x = x * 10 + static_cast<T>(itr[ 7] - '0');
  11342. x = x * 10 + static_cast<T>(itr[ 8] - '0');
  11343. x = x * 10 + static_cast<T>(itr[ 9] - '0');
  11344. x = x * 10 + static_cast<T>(itr[10] - '0');
  11345. t = x;
  11346. }
  11347. };
  11348. template <typename T, typename Iterator>
  11349. struct numeric_convert_impl<T,Iterator,10>
  11350. {
  11351. static inline void process(const Iterator itr, T& t)
  11352. {
  11353. T x = static_cast<T>(itr[0] - '0');
  11354. x = x * 10 + static_cast<T>(itr[1] - '0');
  11355. x = x * 10 + static_cast<T>(itr[2] - '0');
  11356. x = x * 10 + static_cast<T>(itr[3] - '0');
  11357. x = x * 10 + static_cast<T>(itr[4] - '0');
  11358. x = x * 10 + static_cast<T>(itr[5] - '0');
  11359. x = x * 10 + static_cast<T>(itr[6] - '0');
  11360. x = x * 10 + static_cast<T>(itr[7] - '0');
  11361. x = x * 10 + static_cast<T>(itr[8] - '0');
  11362. x = x * 10 + static_cast<T>(itr[9] - '0');
  11363. t = x;
  11364. }
  11365. };
  11366. template <typename T, typename Iterator>
  11367. struct numeric_convert_impl<T,Iterator,9>
  11368. {
  11369. static inline void process(const Iterator itr, T& t)
  11370. {
  11371. T x = static_cast<T>(itr[0] - '0');
  11372. x = x * 10 + static_cast<T>(itr[1] - '0');
  11373. x = x * 10 + static_cast<T>(itr[2] - '0');
  11374. x = x * 10 + static_cast<T>(itr[3] - '0');
  11375. x = x * 10 + static_cast<T>(itr[4] - '0');
  11376. x = x * 10 + static_cast<T>(itr[5] - '0');
  11377. x = x * 10 + static_cast<T>(itr[6] - '0');
  11378. x = x * 10 + static_cast<T>(itr[7] - '0');
  11379. x = x * 10 + static_cast<T>(itr[8] - '0');
  11380. t = x;
  11381. }
  11382. };
  11383. template <typename T, typename Iterator>
  11384. struct numeric_convert_impl<T,Iterator,8>
  11385. {
  11386. static inline void process(const Iterator itr, T& t)
  11387. {
  11388. T x = static_cast<T>(itr[0] - '0');
  11389. x = x * 10 + static_cast<T>(itr[1] - '0');
  11390. x = x * 10 + static_cast<T>(itr[2] - '0');
  11391. x = x * 10 + static_cast<T>(itr[3] - '0');
  11392. x = x * 10 + static_cast<T>(itr[4] - '0');
  11393. x = x * 10 + static_cast<T>(itr[5] - '0');
  11394. x = x * 10 + static_cast<T>(itr[6] - '0');
  11395. x = x * 10 + static_cast<T>(itr[7] - '0');
  11396. t = x;
  11397. }
  11398. };
  11399. template <typename T, typename Iterator>
  11400. struct numeric_convert_impl<T,Iterator,7>
  11401. {
  11402. static inline void process(const Iterator itr, T& t)
  11403. {
  11404. T x = static_cast<T>(itr[0] - '0');
  11405. x = x * 10 + static_cast<T>(itr[1] - '0');
  11406. x = x * 10 + static_cast<T>(itr[2] - '0');
  11407. x = x * 10 + static_cast<T>(itr[3] - '0');
  11408. x = x * 10 + static_cast<T>(itr[4] - '0');
  11409. x = x * 10 + static_cast<T>(itr[5] - '0');
  11410. x = x * 10 + static_cast<T>(itr[6] - '0');
  11411. t = x;
  11412. }
  11413. };
  11414. template <typename T, typename Iterator>
  11415. struct numeric_convert_impl<T,Iterator,6>
  11416. {
  11417. static inline void process(const Iterator itr, T& t)
  11418. {
  11419. T x = static_cast<T>(itr[0] - '0');
  11420. x = x * 10 + static_cast<T>(itr[1] - '0');
  11421. x = x * 10 + static_cast<T>(itr[2] - '0');
  11422. x = x * 10 + static_cast<T>(itr[3] - '0');
  11423. x = x * 10 + static_cast<T>(itr[4] - '0');
  11424. x = x * 10 + static_cast<T>(itr[5] - '0');
  11425. t = x;
  11426. }
  11427. };
  11428. template <typename T, typename Iterator>
  11429. struct numeric_convert_impl<T,Iterator,5>
  11430. {
  11431. static inline void process(const Iterator itr, T& t)
  11432. {
  11433. T x = static_cast<T>(itr[0] - '0');
  11434. x = x * 10 + static_cast<T>(itr[1] - '0');
  11435. x = x * 10 + static_cast<T>(itr[2] - '0');
  11436. x = x * 10 + static_cast<T>(itr[3] - '0');
  11437. x = x * 10 + static_cast<T>(itr[4] - '0');
  11438. t = x;
  11439. }
  11440. };
  11441. template <typename T, typename Iterator>
  11442. struct numeric_convert_impl<T,Iterator,4>
  11443. {
  11444. static inline void process(const Iterator itr, T& t)
  11445. {
  11446. T x = static_cast<T>(itr[0] - '0');
  11447. x = x * 10 + static_cast<T>(itr[1] - '0');
  11448. x = x * 10 + static_cast<T>(itr[2] - '0');
  11449. x = x * 10 + static_cast<T>(itr[3] - '0');
  11450. t = x;
  11451. }
  11452. };
  11453. template <typename T, typename Iterator>
  11454. struct numeric_convert_impl<T,Iterator,3>
  11455. {
  11456. static inline void process(const Iterator itr, T& t)
  11457. {
  11458. T x = static_cast<T>(itr[0] - '0');
  11459. x = x * 10 + static_cast<T>(itr[1] - '0');
  11460. x = x * 10 + static_cast<T>(itr[2] - '0');
  11461. t = x;
  11462. }
  11463. };
  11464. template <typename T, typename Iterator>
  11465. struct numeric_convert_impl<T,Iterator,2>
  11466. {
  11467. static inline void process(const Iterator itr, T& t)
  11468. {
  11469. t = static_cast<T>(itr[0] - '0') * 10 +
  11470. static_cast<T>(itr[1] - '0');
  11471. }
  11472. };
  11473. template <typename T, typename Iterator>
  11474. struct numeric_convert_impl<T,Iterator,1>
  11475. {
  11476. static inline void process(const Iterator itr, T& t)
  11477. {
  11478. t = static_cast<T>(itr[0] - '0');
  11479. }
  11480. };
  11481. template <typename T, typename Iterator>
  11482. struct numeric_convert_impl<T,Iterator,0>
  11483. {
  11484. static inline void process(const Iterator, T& t)
  11485. {
  11486. t = 0;
  11487. }
  11488. };
  11489. template <typename T, typename NoneSignedTag>
  11490. inline bool negate(T&, NoneSignedTag)
  11491. {
  11492. return false;
  11493. }
  11494. template <typename T>
  11495. inline bool negate(T& t, strtk::details::signed_type_tag)
  11496. {
  11497. t = -t;
  11498. return true;
  11499. }
  11500. } // namespace details
  11501. template <std::size_t N, typename Iterator>
  11502. inline bool all_digits_check(Iterator itr)
  11503. {
  11504. typedef typename strtk::details::is_valid_iterator<Iterator>::type itr_type;
  11505. strtk::details::convert_type_assert<itr_type>();
  11506. return details::all_digits_check_impl<Iterator,N>::process(itr);
  11507. }
  11508. template <std::size_t N>
  11509. inline bool all_digits_check(const std::string& s)
  11510. {
  11511. return all_digits_check<N,const char*>(s.data());
  11512. }
  11513. template <typename Iterator>
  11514. inline bool all_digits_check(const std::size_t& n, Iterator itr)
  11515. {
  11516. switch (n)
  11517. {
  11518. case 0 : return details::all_digits_check_impl<Iterator, 0>::process(itr);
  11519. case 1 : return details::all_digits_check_impl<Iterator, 1>::process(itr);
  11520. case 2 : return details::all_digits_check_impl<Iterator, 2>::process(itr);
  11521. case 3 : return details::all_digits_check_impl<Iterator, 3>::process(itr);
  11522. case 4 : return details::all_digits_check_impl<Iterator, 4>::process(itr);
  11523. case 5 : return details::all_digits_check_impl<Iterator, 5>::process(itr);
  11524. case 6 : return details::all_digits_check_impl<Iterator, 6>::process(itr);
  11525. case 7 : return details::all_digits_check_impl<Iterator, 7>::process(itr);
  11526. case 8 : return details::all_digits_check_impl<Iterator, 8>::process(itr);
  11527. case 9 : return details::all_digits_check_impl<Iterator, 9>::process(itr);
  11528. case 10 : return details::all_digits_check_impl<Iterator,10>::process(itr);
  11529. case 11 : return details::all_digits_check_impl<Iterator,11>::process(itr);
  11530. case 12 : return details::all_digits_check_impl<Iterator,12>::process(itr);
  11531. case 13 : return details::all_digits_check_impl<Iterator,13>::process(itr);
  11532. case 14 : return details::all_digits_check_impl<Iterator,14>::process(itr);
  11533. case 15 : return details::all_digits_check_impl<Iterator,15>::process(itr);
  11534. case 16 : return details::all_digits_check_impl<Iterator,16>::process(itr);
  11535. case 17 : return details::all_digits_check_impl<Iterator,17>::process(itr);
  11536. case 18 : return details::all_digits_check_impl<Iterator,18>::process(itr);
  11537. case 19 : return details::all_digits_check_impl<Iterator,19>::process(itr);
  11538. default : return false;
  11539. }
  11540. }
  11541. template <typename Iterator>
  11542. inline bool all_digits_check(Iterator begin, Iterator end)
  11543. {
  11544. return all_digits_check(std::distance(begin,end),begin);
  11545. }
  11546. inline bool all_digits_check(const std::string& s)
  11547. {
  11548. return all_digits_check(s.size(),s.data());
  11549. }
  11550. template <std::size_t N, typename Iterator>
  11551. inline bool signed_all_digits_check(Iterator itr)
  11552. {
  11553. if (('-' == (*itr)) || ('+' == (*itr)))
  11554. return all_digits_check<Iterator,N - 1>((itr + 1));
  11555. else
  11556. return all_digits_check<Iterator,N>(itr);
  11557. }
  11558. template <typename Iterator>
  11559. inline bool signed_all_digits_check(const std::size_t& n, Iterator itr)
  11560. {
  11561. if (('-' == (*itr)) || ('+' == (*itr)))
  11562. return all_digits_check(n - 1,(itr + 1));
  11563. else
  11564. return all_digits_check(n,itr);
  11565. }
  11566. template <std::size_t N>
  11567. inline bool signed_all_digits_check(const std::string& s)
  11568. {
  11569. return signed_all_digits_check<N,const char*>(s.data());
  11570. }
  11571. template <typename Iterator>
  11572. inline bool signed_all_digits_check(Iterator begin, Iterator end)
  11573. {
  11574. return signed_all_digits_check(std::distance(begin,end),begin);
  11575. }
  11576. inline bool signed_all_digits_check(const std::string& s)
  11577. {
  11578. return signed_all_digits_check(s.size(),s.data());
  11579. }
  11580. template <std::size_t N, typename T, typename Iterator>
  11581. inline void numeric_convert(Iterator itr, T& t, const bool digit_check = false)
  11582. {
  11583. typedef typename strtk::details::is_valid_iterator<Iterator>::type itr_type;
  11584. strtk::details::convert_type_assert<itr_type>();
  11585. if (digit_check)
  11586. {
  11587. if (!all_digits_check<N,Iterator>(itr))
  11588. {
  11589. t = 0;
  11590. return;
  11591. }
  11592. }
  11593. details::numeric_convert_impl<T,Iterator,N>::process(itr,t);
  11594. }
  11595. template <std::size_t N, typename T>
  11596. inline void numeric_convert(const std::string& s, T& t, const bool digit_check = false)
  11597. {
  11598. numeric_convert<N,T,const char*>(s.data(),t,digit_check);
  11599. }
  11600. template <typename T, typename Iterator>
  11601. inline bool numeric_convert(const std::size_t n,
  11602. const Iterator itr, T& t,
  11603. const bool digit_check = false)
  11604. {
  11605. if (digit_check)
  11606. {
  11607. if (!all_digits_check(n,itr))
  11608. {
  11609. return false;
  11610. }
  11611. }
  11612. switch (n)
  11613. {
  11614. case 0 : details::numeric_convert_impl<T,Iterator, 0>::process(itr,t); return true;
  11615. case 1 : details::numeric_convert_impl<T,Iterator, 1>::process(itr,t); return true;
  11616. case 2 : details::numeric_convert_impl<T,Iterator, 2>::process(itr,t); return true;
  11617. case 3 : details::numeric_convert_impl<T,Iterator, 3>::process(itr,t); return true;
  11618. case 4 : details::numeric_convert_impl<T,Iterator, 4>::process(itr,t); return true;
  11619. case 5 : details::numeric_convert_impl<T,Iterator, 5>::process(itr,t); return true;
  11620. case 6 : details::numeric_convert_impl<T,Iterator, 6>::process(itr,t); return true;
  11621. case 7 : details::numeric_convert_impl<T,Iterator, 7>::process(itr,t); return true;
  11622. case 8 : details::numeric_convert_impl<T,Iterator, 8>::process(itr,t); return true;
  11623. case 9 : details::numeric_convert_impl<T,Iterator, 9>::process(itr,t); return true;
  11624. case 10 : details::numeric_convert_impl<T,Iterator,10>::process(itr,t); return true;
  11625. case 11 : details::numeric_convert_impl<T,Iterator,11>::process(itr,t); return true;
  11626. case 12 : details::numeric_convert_impl<T,Iterator,12>::process(itr,t); return true;
  11627. case 13 : details::numeric_convert_impl<T,Iterator,13>::process(itr,t); return true;
  11628. case 14 : details::numeric_convert_impl<T,Iterator,14>::process(itr,t); return true;
  11629. case 15 : details::numeric_convert_impl<T,Iterator,15>::process(itr,t); return true;
  11630. case 16 : details::numeric_convert_impl<T,Iterator,16>::process(itr,t); return true;
  11631. case 17 : details::numeric_convert_impl<T,Iterator,17>::process(itr,t); return true;
  11632. case 18 : details::numeric_convert_impl<T,Iterator,18>::process(itr,t); return true;
  11633. case 19 : details::numeric_convert_impl<T,Iterator,19>::process(itr,t); return true;
  11634. default : return false;
  11635. }
  11636. }
  11637. template <typename T>
  11638. inline bool numeric_convert(const std::string& s, T& t, const bool digit_check = false)
  11639. {
  11640. return numeric_convert(s.size(),s.data(),t,digit_check);
  11641. }
  11642. template <std::size_t N, typename T, typename Iterator>
  11643. inline bool signed_numeric_convert(Iterator itr, T& t, const bool digit_check = false)
  11644. {
  11645. if ('-' == (*itr))
  11646. {
  11647. numeric_convert<N - 1,T,Iterator>((itr + 1),t,digit_check);
  11648. typename strtk::details::supported_conversion_to_type<T>::type type;
  11649. details::negate(t,type);
  11650. }
  11651. else if ('+' == (*itr))
  11652. {
  11653. return numeric_convert<N - 1,T,Iterator>((itr + 1),t,digit_check);
  11654. }
  11655. else
  11656. return numeric_convert<N,T,Iterator>(itr,t,digit_check);
  11657. }
  11658. template <typename T, typename Iterator>
  11659. inline bool signed_numeric_convert(Iterator itr,
  11660. const Iterator end,
  11661. T& t,
  11662. const bool digit_check = false)
  11663. {
  11664. const bool negative = ('-' == (*itr));
  11665. if (negative || ('+' == (*itr)))
  11666. {
  11667. if (end == (++itr))
  11668. return false;
  11669. }
  11670. while ((end != itr) && ('0' == (*itr))) ++itr;
  11671. if (numeric_convert(std::distance(itr,end),itr,t,digit_check))
  11672. {
  11673. t = negative ? -t : t;
  11674. return true;
  11675. }
  11676. else
  11677. return false;
  11678. }
  11679. template <std::size_t N, typename T>
  11680. inline bool signed_numeric_convert(const std::string& s,
  11681. T& t,
  11682. const bool digit_check = false)
  11683. {
  11684. return signed_numeric_convert<N,T,const char*>(s.data(),t,digit_check);
  11685. }
  11686. template <typename T>
  11687. inline bool signed_numeric_convert(const std::string& s,
  11688. T& t,
  11689. const bool digit_check = false)
  11690. {
  11691. return signed_numeric_convert<T,const char*>(s.data(),s.data() + s.size(),t,digit_check);
  11692. }
  11693. } // namespace fast
  11694. namespace binary
  11695. {
  11696. namespace details
  11697. {
  11698. namespace details_endian
  11699. {
  11700. #if (defined(__LITTLE_ENDIAN__)) || \
  11701. (defined(WIN32)) || \
  11702. (defined(_WIN32)) || \
  11703. (defined(__WIN32__)) || \
  11704. (defined(__MINGW32_VERSION)) || \
  11705. (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
  11706. static const bool __le_result = true;
  11707. static const bool __be_result = false;
  11708. #else
  11709. static const bool __le_result = false;
  11710. static const bool __be_result = true;
  11711. #endif
  11712. }
  11713. static inline bool is_little_endian()
  11714. {
  11715. //Is the current architecture/platform little-endian?
  11716. return details_endian::__le_result;
  11717. }
  11718. static inline bool is_big_endian()
  11719. {
  11720. return details_endian::__be_result;
  11721. }
  11722. static inline unsigned short convert(const unsigned short v)
  11723. {
  11724. //static_assert(2 == sizeof(v),"");
  11725. return ((v >> 8) & 0x00FF) | ((v << 8) & 0xFFFF);
  11726. }
  11727. static inline unsigned int convert(const unsigned int v)
  11728. {
  11729. //static_assert(4 == sizeof(v),"");
  11730. return ((v >> 24) & 0x000000FF) | ((v << 24) & 0x0000FF00) |
  11731. ((v << 8) & 0x00FF0000) | ((v >> 8) & 0xFF000000);
  11732. }
  11733. static inline unsigned long long int convert(const unsigned long long int v)
  11734. {
  11735. //static_assert(8 == sizeof(v),"");
  11736. return ((v >> 56) & 0x00000000000000FFLL) | ((v << 56) & 0xFF00000000000000LL) |
  11737. ((v >> 40) & 0x000000000000FF00LL) | ((v << 40) & 0x00FF000000000000LL) |
  11738. ((v >> 24) & 0x0000000000FF0000LL) | ((v << 24) & 0x0000FF0000000000LL) |
  11739. ((v >> 8) & 0x00000000FF000000LL) | ((v << 8) & 0x000000FF00000000LL) ;
  11740. }
  11741. static inline short convert(const short v)
  11742. {
  11743. return static_cast<short>(convert(static_cast<unsigned short>(v)));
  11744. }
  11745. static inline int convert(const int v)
  11746. {
  11747. return static_cast<int>(convert(static_cast<unsigned int>(v)));
  11748. }
  11749. static inline long long int convert(const long long int v)
  11750. {
  11751. return static_cast<long long>(convert(static_cast<unsigned long long int>(v)));
  11752. }
  11753. static inline unsigned short convert_to_be(const unsigned short v)
  11754. {
  11755. return (is_little_endian()) ? convert(v) : v;
  11756. }
  11757. static inline unsigned int convert_to_be(const unsigned int v)
  11758. {
  11759. return (is_little_endian()) ? convert(v) : v;
  11760. }
  11761. static inline unsigned long long int convert_to_be(const unsigned long long int v)
  11762. {
  11763. return (is_little_endian()) ? convert(v) : v;
  11764. }
  11765. static inline short convert_to_be(const short v)
  11766. {
  11767. return (is_little_endian()) ? convert(v) : v;
  11768. }
  11769. static inline int convert_to_be(const int v)
  11770. {
  11771. return (is_little_endian()) ? convert(v) : v;
  11772. }
  11773. static inline long long int convert_to_be(const long long int v)
  11774. {
  11775. return (is_little_endian()) ? convert(v) : v;
  11776. }
  11777. static inline unsigned short convert_to_le(const unsigned short v)
  11778. {
  11779. return (is_big_endian()) ? convert(v) : v;
  11780. }
  11781. static inline unsigned int convert_to_le(const unsigned int v)
  11782. {
  11783. return (is_big_endian()) ? convert(v) : v;
  11784. }
  11785. static inline unsigned long long int convert_to_le(const unsigned long long int v)
  11786. {
  11787. return (is_big_endian()) ? convert(v) : v;
  11788. }
  11789. static inline short convert_to_le(const short v)
  11790. {
  11791. return (is_big_endian()) ? convert(v) : v;
  11792. }
  11793. static inline int convert_to_le(const int v)
  11794. {
  11795. return (is_big_endian()) ? convert(v) : v;
  11796. }
  11797. static inline unsigned long long int convert_to_le(const long long int v)
  11798. {
  11799. return (is_big_endian()) ? convert(v) : v;
  11800. }
  11801. class marker
  11802. {
  11803. private:
  11804. typedef std::pair<std::size_t,char*> mark_type;
  11805. public:
  11806. inline bool reset(std::size_t& v1, char*& v2)
  11807. {
  11808. if (stack_.empty())
  11809. return false;
  11810. v1 = stack_.top().first;
  11811. v2 = stack_.top().second;
  11812. stack_.pop();
  11813. return true;
  11814. }
  11815. inline void mark(const std::size_t& v1,char* v2)
  11816. {
  11817. stack_.push(std::make_pair(v1,v2));
  11818. }
  11819. private:
  11820. std::stack<mark_type> stack_;
  11821. };
  11822. }
  11823. class reader
  11824. {
  11825. public:
  11826. // should be sourced from cstdint
  11827. typedef unsigned int uint32_t;
  11828. typedef unsigned short uint16_t;
  11829. typedef unsigned char uint8_t;
  11830. typedef unsigned long long int uint64_t;
  11831. template <typename T>
  11832. reader(T* buffer,
  11833. const std::size_t& buffer_length)
  11834. : original_buffer_(reinterpret_cast<char*>(buffer)),
  11835. buffer_(reinterpret_cast<char*>(buffer)),
  11836. buffer_length_(buffer_length * sizeof(T)),
  11837. amount_read_sofar_(0)
  11838. {}
  11839. inline bool operator!() const
  11840. {
  11841. return (0 == buffer_length_) ||
  11842. (0 == original_buffer_) ||
  11843. (0 == buffer_);
  11844. }
  11845. inline void reset(const bool clear_buffer = false)
  11846. {
  11847. amount_read_sofar_ = 0;
  11848. buffer_ = original_buffer_;
  11849. if (clear_buffer)
  11850. clear();
  11851. }
  11852. inline std::size_t position() const
  11853. {
  11854. return amount_read_sofar_;
  11855. }
  11856. inline const char* position_ptr() const
  11857. {
  11858. return buffer_ ;
  11859. }
  11860. inline std::size_t amount_read()
  11861. {
  11862. return amount_read_sofar_;
  11863. }
  11864. inline bool rewind(const std::size_t& n_bytes)
  11865. {
  11866. if (n_bytes <= amount_read_sofar_)
  11867. {
  11868. amount_read_sofar_ -= n_bytes;
  11869. buffer_ -= n_bytes;
  11870. return true;
  11871. }
  11872. else
  11873. return false;
  11874. }
  11875. inline bool seek(const int& n_bytes)
  11876. {
  11877. if (n_bytes < 0)
  11878. return rewind(-n_bytes);
  11879. else if (n_bytes > 0)
  11880. {
  11881. if ((amount_read_sofar_ + n_bytes) <= buffer_length_)
  11882. {
  11883. amount_read_sofar_ += n_bytes;
  11884. buffer_ += n_bytes;
  11885. return true;
  11886. }
  11887. else
  11888. return false;
  11889. }
  11890. else
  11891. return true;
  11892. }
  11893. inline void clear()
  11894. {
  11895. reset();
  11896. std::memset(buffer_,0x00,buffer_length_);
  11897. }
  11898. template <typename T>
  11899. inline bool operator()(T*& data, uint32_t& length, const bool read_length = true)
  11900. {
  11901. if (read_length && !operator()(length))
  11902. return false;
  11903. const std::size_t raw_size = length * sizeof(T);
  11904. if (!buffer_capacity_ok(raw_size))
  11905. return false;
  11906. if (read_length)
  11907. {
  11908. data = new T[length];
  11909. }
  11910. std::copy(buffer_, buffer_ + raw_size, reinterpret_cast<char*>(data));
  11911. buffer_ += raw_size;
  11912. amount_read_sofar_ += raw_size;
  11913. return true;
  11914. }
  11915. template <typename T>
  11916. inline bool operator()(T*& data, uint64_t& length, const bool read_length = true)
  11917. {
  11918. uint32_t l = 0;
  11919. if (read_length)
  11920. l = static_cast<uint32_t>(length);
  11921. if (!operator()(data,l,read_length))
  11922. return false;
  11923. if (read_length)
  11924. length = l;
  11925. return true;
  11926. }
  11927. inline bool operator()(std::string& output)
  11928. {
  11929. uint32_t length = 0;
  11930. if (!operator()(length))
  11931. return false;
  11932. if (!buffer_capacity_ok(length))
  11933. return false;
  11934. output.resize(length);
  11935. std::copy(buffer_,
  11936. buffer_ + length,
  11937. const_cast<char*>(output.data()));
  11938. buffer_ += length;
  11939. amount_read_sofar_ += length;
  11940. return true;
  11941. }
  11942. template <typename T1, typename T2>
  11943. inline bool operator()(std::pair<T1,T2>& p)
  11944. {
  11945. if (!operator()(p.first))
  11946. return false;
  11947. if (!operator()(p.second))
  11948. return false;
  11949. return true;
  11950. }
  11951. template <typename T,
  11952. typename Allocator,
  11953. template <typename,typename> class Sequence>
  11954. inline bool operator()(Sequence<T,Allocator>& seq)
  11955. {
  11956. uint32_t size = 0;
  11957. if (!read_pod(size))
  11958. return false;
  11959. const std::size_t raw_size = size * sizeof(T);
  11960. if (!buffer_capacity_ok(raw_size))
  11961. return false;
  11962. T t = T();
  11963. for (std::size_t i = 0; i < size; ++i)
  11964. {
  11965. if (operator()(t))
  11966. seq.push_back(t);
  11967. else
  11968. return false;
  11969. }
  11970. return true;
  11971. }
  11972. template <typename T, typename Allocator>
  11973. inline bool operator()(std::vector<T,Allocator>& vec)
  11974. {
  11975. uint32_t size = 0;
  11976. if (!read_pod(size))
  11977. return false;
  11978. const std::size_t raw_size = size * sizeof(T);
  11979. if (!buffer_capacity_ok(raw_size))
  11980. return false;
  11981. vec.resize(size);
  11982. return selector<T>::type::batch_vector_read(*this,size,vec,false);
  11983. }
  11984. template <typename T,
  11985. typename Comparator,
  11986. typename Allocator>
  11987. inline bool operator()(std::set<T,Comparator,Allocator>& set)
  11988. {
  11989. uint32_t size = 0;
  11990. if (!read_pod(size))
  11991. return false;
  11992. const std::size_t raw_size = size * sizeof(T);
  11993. if (!buffer_capacity_ok(raw_size))
  11994. return false;
  11995. T t;
  11996. for (std::size_t i = 0; i < size; ++i)
  11997. {
  11998. if (!operator()(t))
  11999. return false;
  12000. set.insert(t);
  12001. }
  12002. return true;
  12003. }
  12004. template <typename T,
  12005. typename Allocator,
  12006. typename Comparator>
  12007. inline bool operator()(std::multiset<T,Allocator,Comparator>& multiset)
  12008. {
  12009. uint32_t size = 0;
  12010. if (!read_pod(size))
  12011. return false;
  12012. const std::size_t raw_size = size * sizeof(T);
  12013. if (!buffer_capacity_ok(raw_size))
  12014. return false;
  12015. T t;
  12016. for (std::size_t i = 0; i < size; ++i)
  12017. {
  12018. if (!operator()(t))
  12019. return false;
  12020. multiset.insert(t);
  12021. }
  12022. return true;
  12023. }
  12024. inline bool operator()(std::ifstream& stream, const std::size_t& length)
  12025. {
  12026. if (length > buffer_length_) return false;
  12027. stream.read(original_buffer_,static_cast<std::streamsize>(length));
  12028. return true;
  12029. }
  12030. inline bool operator()(std::ifstream& stream)
  12031. {
  12032. if (0 == amount_read_sofar_) return false;
  12033. stream.read(original_buffer_,static_cast<std::streamsize>(amount_read_sofar_));
  12034. return true;
  12035. }
  12036. template <typename T>
  12037. inline bool operator()(T& output)
  12038. {
  12039. return selector<T>::type::run(*this,output);
  12040. }
  12041. template <typename T>
  12042. inline bool operator()(const T& output)
  12043. {
  12044. return selector<T>::type::run(*this,const_cast<T&>(output));
  12045. }
  12046. template <typename T>
  12047. inline bool be_to_native(T& output)
  12048. {
  12049. //From big-endian to native
  12050. if (details::is_little_endian())
  12051. {
  12052. if (!operator()<T>(output)) return false;
  12053. output = details::convert(output);
  12054. return true;
  12055. }
  12056. else
  12057. return operator()(output);
  12058. }
  12059. template <typename T>
  12060. inline bool le_to_native(T& output)
  12061. {
  12062. //From little-endian to native
  12063. if (details::is_little_endian())
  12064. return operator()(output);
  12065. else
  12066. {
  12067. if (!operator()<T>(output)) return false;
  12068. output = details::convert(output);
  12069. return true;
  12070. }
  12071. }
  12072. template <typename T, std::size_t N>
  12073. inline bool operator()(T (&output)[N])
  12074. {
  12075. const std::size_t raw_size = N * sizeof(T);
  12076. if (buffer_capacity_ok(raw_size))
  12077. {
  12078. std::copy(buffer_,
  12079. buffer_ + raw_size,
  12080. reinterpret_cast<char*>(output));
  12081. buffer_ += raw_size;
  12082. amount_read_sofar_ += raw_size;
  12083. return true;
  12084. }
  12085. else
  12086. return false;
  12087. }
  12088. template <typename T>
  12089. inline bool operator()(T& output, const std::size_t& size)
  12090. {
  12091. if (buffer_capacity_ok(size))
  12092. {
  12093. bool result = strtk::string_to_type_converter<char*,T>(buffer_,buffer_ + size,output);
  12094. buffer_ += size;
  12095. amount_read_sofar_ += size;
  12096. return result;
  12097. }
  12098. else
  12099. return false;
  12100. }
  12101. inline void mark()
  12102. {
  12103. marker_.mark(amount_read_sofar_,buffer_);
  12104. }
  12105. inline bool reset_to_mark()
  12106. {
  12107. return marker_.reset(amount_read_sofar_,buffer_);
  12108. }
  12109. private:
  12110. reader();
  12111. reader(const reader& s);
  12112. reader& operator=(const reader& s);
  12113. inline bool buffer_capacity_ok(const std::size_t& required_read_qty)
  12114. {
  12115. return ((required_read_qty + amount_read_sofar_) <= buffer_length_);
  12116. }
  12117. template <typename Type>
  12118. struct selector
  12119. {
  12120. private:
  12121. template <typename T, typename IsPOD>
  12122. struct selector_impl
  12123. {
  12124. template <typename Reader>
  12125. static inline bool run(Reader& r, T& t)
  12126. {
  12127. return t(r);
  12128. }