PageRenderTime 147ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 1ms

/strtk.hpp

http://strtk.codeplex.com
C++ Header | 13496 lines | 12692 code | 752 blank | 52 comment | 847 complexity | 0a8accbcd9730aa9e8c7743f9e912017 MD5 | raw file
  1. /*
  2. *****************************************************************
  3. * String Toolkit Library *
  4. * *
  5. * Author: Arash Partow (2002-2013) *
  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 <cstddef>
  19. #include <cctype>
  20. #include <cstring>
  21. #include <cerrno>
  22. #include <exception>
  23. #include <cmath>
  24. #include <iterator>
  25. #include <limits>
  26. #include <iostream>
  27. #include <fstream>
  28. #include <sstream>
  29. #include <utility>
  30. #include <algorithm>
  31. #include <string>
  32. #include <vector>
  33. #include <deque>
  34. #include <list>
  35. #include <set>
  36. #include <map>
  37. #include <stack>
  38. #include <queue>
  39. #ifndef strtk_no_tr1_or_boost
  40. #define strtk_enable_lexical_cast
  41. #define strtk_enable_random
  42. #define strtk_enable_regex
  43. #endif
  44. #ifdef strtk_enable_lexical_cast
  45. #include <boost/lexical_cast.hpp>
  46. #endif
  47. #ifdef strtk_enable_random
  48. // Requires definition of a TR1 compatible random library header
  49. //#include <random>
  50. #include <boost/random.hpp>
  51. #endif
  52. #ifdef strtk_enable_regex
  53. // Requires definition of a TR1 compatible regex library header
  54. //#include <regex>
  55. #include <boost/regex.hpp>
  56. #endif
  57. namespace strtk
  58. {
  59. static const std::size_t one_kilobyte = 1024;
  60. static const std::size_t one_megabyte = 1024 * one_kilobyte;
  61. static const std::size_t one_gigabyte = 1024 * one_megabyte;
  62. static const std::size_t magic_seed = 0xA5A5A5A5;
  63. template <typename Tokenizer, typename Function>
  64. inline std::size_t for_each_token(const std::string& buffer,
  65. Tokenizer& tokenizer,
  66. Function function)
  67. {
  68. std::size_t token_count = 0;
  69. tokenizer.assign(buffer);
  70. typename Tokenizer::iterator itr = tokenizer.begin();
  71. typename Tokenizer::const_iterator end = tokenizer.end();
  72. while (end != itr)
  73. {
  74. function(*itr);
  75. ++itr;
  76. ++token_count;
  77. }
  78. return token_count;
  79. }
  80. template <typename Function>
  81. inline std::size_t for_each_line(std::istream& stream,
  82. Function function,
  83. const std::size_t& buffer_size = one_kilobyte)
  84. {
  85. std::string buffer;
  86. buffer.reserve(buffer_size);
  87. std::size_t line_count = 0;
  88. while (std::getline(stream,buffer))
  89. {
  90. function(buffer);
  91. ++line_count;
  92. }
  93. return line_count;
  94. }
  95. template <typename Function>
  96. inline std::size_t for_each_line_n(std::istream& stream,
  97. const std::size_t& n,
  98. Function function,
  99. const std::size_t& buffer_size = one_kilobyte)
  100. {
  101. std::string buffer;
  102. buffer.reserve(buffer_size);
  103. std::size_t line_count = 0;
  104. while (std::getline(stream,buffer))
  105. {
  106. function(buffer);
  107. if (n == ++line_count)
  108. break;
  109. }
  110. return line_count;
  111. }
  112. template <typename Function>
  113. inline std::size_t for_each_line(const std::string& file_name,
  114. Function function,
  115. const std::size_t& buffer_size = one_kilobyte)
  116. {
  117. std::ifstream stream(file_name.c_str());
  118. if (stream)
  119. return for_each_line(stream,function,buffer_size);
  120. else
  121. return 0;
  122. }
  123. template <typename Function>
  124. inline std::size_t for_each_line_n(const std::string& file_name,
  125. const std::size_t& n,
  126. Function function,
  127. const std::size_t& buffer_size = one_kilobyte)
  128. {
  129. std::ifstream stream(file_name.c_str());
  130. if (stream)
  131. return for_each_line_n(stream,n,function,buffer_size);
  132. else
  133. return 0;
  134. }
  135. template <typename Function>
  136. inline std::size_t for_each_line_conditional(std::istream& stream,
  137. Function function,
  138. const std::size_t& buffer_size = one_kilobyte)
  139. {
  140. std::string buffer;
  141. buffer.reserve(buffer_size);
  142. std::size_t line_count = 0;
  143. while (std::getline(stream,buffer))
  144. {
  145. if (!function(buffer))
  146. {
  147. return line_count;
  148. }
  149. ++line_count;
  150. }
  151. return line_count;
  152. }
  153. template <typename Function>
  154. inline std::size_t for_each_line_n_conditional(std::istream& stream,
  155. const std::size_t& n,
  156. Function function,
  157. const std::size_t& buffer_size = one_kilobyte)
  158. {
  159. std::string buffer;
  160. buffer.reserve(buffer_size);
  161. std::size_t line_count = 0;
  162. while (std::getline(stream,buffer))
  163. {
  164. if (!function(buffer))
  165. {
  166. return line_count;
  167. }
  168. if (n == ++line_count)
  169. break;
  170. }
  171. return line_count;
  172. }
  173. template <typename Function>
  174. inline std::size_t for_each_line_conditional(const std::string& file_name,
  175. Function function,
  176. const std::size_t& buffer_size = one_kilobyte)
  177. {
  178. std::ifstream stream(file_name.c_str());
  179. if (stream)
  180. return for_each_line_conditional(stream,function,buffer_size);
  181. else
  182. return 0;
  183. }
  184. template <typename Function>
  185. inline std::size_t for_each_line_n_conditional(const std::string& file_name,
  186. const std::size_t& n,
  187. Function function,
  188. const std::size_t& buffer_size = one_kilobyte)
  189. {
  190. std::ifstream stream(file_name.c_str());
  191. if (stream)
  192. return for_each_line_n_conditional(stream,n,function,buffer_size);
  193. else
  194. return 0;
  195. }
  196. template <typename T>
  197. inline bool read_line_as_value(std::istream& stream,
  198. T& t,
  199. const std::size_t& buffer_size = one_kilobyte)
  200. {
  201. std::string buffer;
  202. buffer.reserve(buffer_size);
  203. if (!std::getline(stream,buffer))
  204. return false;
  205. return string_to_type_converter(buffer,t);
  206. }
  207. namespace details
  208. {
  209. struct not_supported_type_tag {};
  210. struct unsigned_type_tag {};
  211. struct signed_type_tag {};
  212. struct real_type_tag {};
  213. struct byte_type_tag {};
  214. struct bool_type_tag {};
  215. struct hex_number_type_tag {};
  216. struct hex_string_type_tag {};
  217. struct base64_type_tag {};
  218. struct ignore_token_type_tag {};
  219. struct stdstring_type_tag {};
  220. struct stdstring_range_type_tag {};
  221. struct value_type_tag {};
  222. struct sink_type_tag {};
  223. struct stl_seq_type_tag {};
  224. struct attribute_type_tag {};
  225. struct semantic_action_type_tag {};
  226. struct expect_type_tag {};
  227. struct like_type_tag {};
  228. struct inrange_type_tag {};
  229. struct trim_type_tag {};
  230. struct lcase_type_tag {};
  231. struct ucase_type_tag {};
  232. struct fillchararray_type_tag {};
  233. template <typename T>
  234. struct supported_conversion_to_type
  235. {
  236. typedef not_supported_type_tag type;
  237. };
  238. template <typename T>
  239. struct supported_conversion_from_type
  240. {
  241. typedef not_supported_type_tag type;
  242. };
  243. template <bool, typename T = void>
  244. struct enable_if {};
  245. template <typename T>
  246. struct enable_if<true, T> { typedef T type; };
  247. template <typename T>
  248. struct supported_iterator_type
  249. {
  250. enum { value = false };
  251. };
  252. template <typename T>
  253. struct is_valid_iterator
  254. {
  255. typedef typename details::enable_if<details::supported_iterator_type<T>::value,T>::type type;
  256. };
  257. template <typename T> struct numeric;
  258. template <typename T> inline std::size_t type_length(const T&);
  259. struct no_t {};
  260. struct yes_t {};
  261. template <typename T>
  262. struct is_pod
  263. {
  264. typedef no_t result_t;
  265. enum { result = false };
  266. };
  267. template <typename T>
  268. struct is_stl_container
  269. { typedef no_t result_t; };
  270. #define register_stl_container1(C) \
  271. template <typename T1, typename T2>struct is_stl_container<C<T1,T2> >{ typedef yes_t result_t; };
  272. #define register_stl_container2(C) \
  273. template <typename T1, typename T2, typename T3>struct is_stl_container<C<T1,T2,T3> >{ typedef yes_t result_t; };
  274. register_stl_container1(std::vector)
  275. register_stl_container1(std::deque)
  276. register_stl_container1(std::list)
  277. register_stl_container1(std::queue)
  278. register_stl_container1(std::stack)
  279. register_stl_container2(std::set)
  280. register_stl_container2(std::multiset)
  281. register_stl_container2(std::priority_queue)
  282. #undef register_stl_container1
  283. #undef register_stl_container2
  284. } // namespace details
  285. template <typename Iterator, typename T>
  286. inline bool string_to_type_converter(const Iterator begin, const Iterator end, T& t)
  287. {
  288. typedef typename details::is_valid_iterator<Iterator>::type itr_type;
  289. typename details::supported_conversion_to_type<T>::type type;
  290. Iterator itr = begin;
  291. return string_to_type_converter_impl(itr,end,t,type);
  292. }
  293. template <typename Iterator, typename T>
  294. inline bool string_to_type_converter(const std::pair<Iterator,Iterator>& range, T& t)
  295. {
  296. return string_to_type_converter(range.first,range.second,t);
  297. }
  298. template <typename T, typename Iterator>
  299. inline T string_to_type_converter(const Iterator begin, const Iterator end)
  300. {
  301. typedef typename details::is_valid_iterator<Iterator>::type itr_type;
  302. typename details::supported_conversion_to_type<T>::type type;
  303. T t;
  304. Iterator itr = begin;
  305. if (string_to_type_converter_impl(itr,end,t,type))
  306. return t;
  307. else
  308. throw std::invalid_argument("string_to_type_converter() - Failed to convert: " +
  309. std::string(begin,end));
  310. }
  311. template <typename T, typename Iterator>
  312. inline T string_to_type_converter(const std::pair<Iterator,Iterator>& range)
  313. {
  314. return string_to_type_converter<T>(range.first,range.second);
  315. }
  316. template <typename T>
  317. inline bool string_to_type_converter(const std::string& s, T& t)
  318. {
  319. return string_to_type_converter<const char*,T>(s.data(),s.data() + s.size(),t);
  320. }
  321. template <typename T>
  322. inline T string_to_type_converter(const std::string& s)
  323. {
  324. return string_to_type_converter<T>(s.data(),s.data() + s.size());
  325. }
  326. template <typename T>
  327. inline bool type_to_string(const T& t, std::string& s)
  328. {
  329. typename details::supported_conversion_from_type<T>::type type;
  330. return type_to_string_converter_impl(t,s,type);
  331. }
  332. template <typename T>
  333. inline std::string type_to_string(const T& t)
  334. {
  335. std::string s;
  336. if (type_to_string<T>(t,s))
  337. return s;
  338. else
  339. throw std::invalid_argument("type_to_string() - Failed to convert type to string");
  340. }
  341. #define strtk_begin_register_string_to_type \
  342. namespace strtk { namespace details {
  343. #define strtk_end_register_string_to_type \
  344. }}
  345. #define strtk_string_to_type_begin(Type) \
  346. namespace strtk { namespace details { template <typename Iterator> \
  347. inline bool string_to_type_converter_impl(const Iterator& begin, const Iterator& end, \
  348. Type& t, details::not_supported_type_tag&) {
  349. #define strtk_string_to_type_end()\
  350. }}}
  351. template <typename T,
  352. typename Allocator,
  353. template <typename,typename> class Sequence>
  354. inline std::size_t load_from_text_file(std::istream& stream,
  355. Sequence<T,Allocator>& sequence,
  356. const std::size_t& buffer_size = one_kilobyte)
  357. {
  358. if (!stream) return 0;
  359. std::string buffer;
  360. buffer.reserve(buffer_size);
  361. std::size_t line_count = 0;
  362. while (std::getline(stream,buffer))
  363. {
  364. ++line_count;
  365. sequence.push_back(string_to_type_converter<T>(buffer));
  366. }
  367. return line_count;
  368. }
  369. template <typename T,
  370. typename Comparator,
  371. typename Allocator>
  372. inline std::size_t load_from_text_file(std::istream& stream,
  373. std::set<T,Comparator,Allocator>& set,
  374. const std::size_t& buffer_size = one_kilobyte)
  375. {
  376. if (!stream) return 0;
  377. std::string buffer;
  378. buffer.reserve(buffer_size);
  379. std::size_t line_count = 0;
  380. while (std::getline(stream,buffer))
  381. {
  382. ++line_count;
  383. set.insert(string_to_type_converter<T>(buffer));
  384. }
  385. return line_count;
  386. }
  387. template <typename T,
  388. typename Comparator,
  389. typename Allocator>
  390. inline std::size_t load_from_text_file(std::istream& stream,
  391. std::multiset<T,Comparator,Allocator>& multiset,
  392. const std::size_t& buffer_size = one_kilobyte)
  393. {
  394. if (!stream) return 0;
  395. std::string buffer;
  396. buffer.reserve(buffer_size);
  397. std::size_t line_count = 0;
  398. while (std::getline(stream,buffer))
  399. {
  400. ++line_count;
  401. multiset.insert(string_to_type_converter<T>(buffer));
  402. }
  403. return line_count;
  404. }
  405. template <typename T, typename Container>
  406. inline std::size_t load_from_text_file(std::istream& stream,
  407. std::queue<T,Container>& queue,
  408. const std::size_t& buffer_size = one_kilobyte)
  409. {
  410. if (!stream) return 0;
  411. std::string buffer;
  412. buffer.reserve(buffer_size);
  413. std::size_t line_count = 0;
  414. while (std::getline(stream,buffer))
  415. {
  416. ++line_count;
  417. queue.push(string_to_type_converter<T>(buffer));
  418. }
  419. return line_count;
  420. }
  421. template <typename T, typename Container>
  422. inline std::size_t load_from_text_file(std::istream& stream,
  423. std::stack<T,Container>& stack,
  424. const std::size_t& buffer_size = one_kilobyte)
  425. {
  426. if (!stream) return 0;
  427. std::string buffer;
  428. buffer.reserve(buffer_size);
  429. std::size_t line_count = 0;
  430. while (std::getline(stream,buffer))
  431. {
  432. ++line_count;
  433. stack.push(string_to_type_converter<T>(buffer));
  434. }
  435. return line_count;
  436. }
  437. template <typename T,
  438. typename Container,
  439. typename Comparator>
  440. inline std::size_t load_from_text_file(std::istream& stream,
  441. std::priority_queue<T,Container,Comparator>& priority_queue,
  442. const std::size_t& buffer_size = one_kilobyte)
  443. {
  444. if (!stream) return 0;
  445. std::string buffer;
  446. buffer.reserve(buffer_size);
  447. std::size_t line_count = 0;
  448. while (std::getline(stream,buffer))
  449. {
  450. ++line_count;
  451. priority_queue.push(string_to_type_converter<T>(buffer));
  452. }
  453. return line_count;
  454. }
  455. template <typename T,
  456. typename Allocator,
  457. template <typename,typename> class Sequence>
  458. inline std::size_t load_from_text_file(const std::string& file_name,
  459. Sequence<T,Allocator>& sequence,
  460. const std::size_t& buffer_size = one_kilobyte)
  461. {
  462. std::ifstream stream(file_name.c_str());
  463. if (!stream)
  464. return 0;
  465. else
  466. return load_from_text_file(stream,sequence,buffer_size);
  467. }
  468. template <typename T,
  469. typename Comparator,
  470. typename Allocator>
  471. inline std::size_t load_from_text_file(const std::string& file_name,
  472. std::set<T,Comparator,Allocator>& set,
  473. const std::size_t& buffer_size = one_kilobyte)
  474. {
  475. std::ifstream stream(file_name.c_str());
  476. if (!stream)
  477. return 0;
  478. else
  479. return load_from_text_file(stream,set,buffer_size);
  480. }
  481. template <typename T,
  482. typename Comparator,
  483. typename Allocator>
  484. inline std::size_t load_from_text_file(const std::string& file_name,
  485. std::multiset<T,Comparator,Allocator>& multiset,
  486. const std::size_t& buffer_size = one_kilobyte)
  487. {
  488. std::ifstream stream(file_name.c_str());
  489. if (!stream)
  490. return 0;
  491. else
  492. return load_from_text_file(stream,multiset,buffer_size);
  493. }
  494. template <typename T, typename Container>
  495. inline std::size_t load_from_text_file(const std::string& file_name,
  496. std::queue<T,Container>& queue,
  497. const std::size_t& buffer_size = one_kilobyte)
  498. {
  499. std::ifstream stream(file_name.c_str());
  500. if (!stream)
  501. return 0;
  502. else
  503. return load_from_text_file(stream,queue,buffer_size);
  504. }
  505. template <typename T, typename Container>
  506. inline std::size_t load_from_text_file(const std::string& file_name,
  507. std::stack<T,Container>& stack,
  508. const std::size_t& buffer_size = one_kilobyte)
  509. {
  510. std::ifstream stream(file_name.c_str());
  511. if (!stream)
  512. return 0;
  513. else
  514. return load_from_text_file(stream,stack,buffer_size);
  515. }
  516. template <typename T,
  517. typename Container,
  518. typename Comparator>
  519. inline std::size_t load_from_text_file(const std::string& file_name,
  520. std::priority_queue<T,Container,Comparator>& priority_queue,
  521. const std::size_t& buffer_size = one_kilobyte)
  522. {
  523. std::ifstream stream(file_name.c_str());
  524. if (!stream)
  525. return 0;
  526. else
  527. return load_from_text_file(stream,priority_queue,buffer_size);
  528. }
  529. template <typename T,
  530. typename Allocator,
  531. template <typename,typename> class Sequence>
  532. inline std::size_t write_to_text_file(std::ostream& stream,
  533. const Sequence<T,Allocator>& sequence,
  534. const std::string& delimiter = "")
  535. {
  536. if (!stream) return 0;
  537. std::size_t count = 0;
  538. typename Sequence<T,Allocator>::const_iterator itr = sequence.begin();
  539. typename Sequence<T,Allocator>::const_iterator end = sequence.end();
  540. if (!delimiter.empty())
  541. {
  542. while (end != itr)
  543. {
  544. stream << (*itr) << delimiter;
  545. ++itr;
  546. ++count;
  547. }
  548. }
  549. else
  550. {
  551. while (end != itr)
  552. {
  553. stream << (*itr);
  554. ++itr;
  555. ++count;
  556. }
  557. }
  558. return count;
  559. }
  560. template <typename T,
  561. typename Comparator,
  562. typename Allocator>
  563. inline std::size_t write_to_text_file(std::ostream& stream,
  564. const std::set<T,Comparator,Allocator>& set,
  565. const std::string& delimiter = "")
  566. {
  567. if (!stream) return 0;
  568. std::size_t count = 0;
  569. typename std::set<T,Comparator,Allocator>::const_iterator itr = set.begin();
  570. typename std::set<T,Comparator,Allocator>::const_iterator end = set.end();
  571. if (!delimiter.empty())
  572. {
  573. while (end != itr)
  574. {
  575. stream << (*itr) << delimiter;
  576. ++itr;
  577. ++count;
  578. }
  579. }
  580. else
  581. {
  582. while (end != itr)
  583. {
  584. stream << (*itr);
  585. ++itr;
  586. ++count;
  587. }
  588. }
  589. return count;
  590. }
  591. template <typename T,
  592. typename Comparator,
  593. typename Allocator>
  594. inline std::size_t write_to_text_file(std::ostream& stream,
  595. const std::multiset<T,Comparator,Allocator>& multiset,
  596. const std::string& delimiter = "")
  597. {
  598. if (!stream) return 0;
  599. std::size_t count = 0;
  600. typename std::multiset<T,Comparator,Allocator>::const_iterator itr = multiset.begin();
  601. typename std::multiset<T,Comparator,Allocator>::const_iterator end = multiset.end();
  602. if (!delimiter.empty())
  603. {
  604. while (end != itr)
  605. {
  606. stream << (*itr) << delimiter;
  607. ++itr;
  608. ++count;
  609. }
  610. }
  611. else
  612. {
  613. while (end != itr)
  614. {
  615. stream << (*itr);
  616. ++itr;
  617. ++count;
  618. }
  619. }
  620. return count;
  621. }
  622. template <typename T,
  623. typename Allocator,
  624. template <typename,typename> class Sequence>
  625. inline std::size_t write_to_text_file(const std::string& file_name,
  626. const Sequence<T,Allocator>& sequence,
  627. const std::string& delimiter = "")
  628. {
  629. std::ofstream stream(file_name.c_str());
  630. if (!stream)
  631. return 0;
  632. else
  633. return write_to_text_file(stream,sequence,delimiter);
  634. }
  635. template <typename T,
  636. typename Comparator,
  637. typename Allocator>
  638. inline std::size_t write_to_text_file(const std::string& file_name,
  639. const std::set<T,Comparator,Allocator>& set,
  640. const std::string& delimiter = "")
  641. {
  642. std::ofstream stream(file_name.c_str());
  643. if (!stream)
  644. return 0;
  645. else
  646. return write_to_text_file(stream,set,delimiter);
  647. }
  648. template <typename T,
  649. typename Comparator,
  650. typename Allocator>
  651. inline std::size_t write_to_text_file(const std::string& file_name,
  652. const std::multiset<T,Comparator,Allocator>& multiset,
  653. const std::string& delimiter = "")
  654. {
  655. std::ofstream stream(file_name.c_str());
  656. if (!stream)
  657. return 0;
  658. else
  659. return write_to_text_file(stream,multiset,delimiter);
  660. }
  661. template <typename InputIterator, typename OutputIterator>
  662. inline void copy_n(InputIterator itr, std::size_t n, OutputIterator out)
  663. {
  664. while (n)
  665. {
  666. (*out) = (*itr);
  667. ++itr;
  668. ++out;
  669. --n;
  670. }
  671. }
  672. template <typename Predicate,
  673. typename InputIterator,
  674. typename OutputIterator>
  675. inline void copy_if(Predicate predicate,
  676. const InputIterator begin, const InputIterator end,
  677. OutputIterator out)
  678. {
  679. InputIterator itr = begin;
  680. while (end != itr)
  681. {
  682. if (predicate(*itr))
  683. {
  684. *(out++) = (*itr);
  685. }
  686. ++itr;
  687. }
  688. }
  689. template <typename Predicate,
  690. typename InputIterator,
  691. typename OutputIterator>
  692. inline InputIterator copy_while(Predicate predicate,
  693. const InputIterator begin, const InputIterator end,
  694. OutputIterator out)
  695. {
  696. InputIterator itr = begin;
  697. while (end != itr)
  698. {
  699. if (!predicate(*itr))
  700. return itr;
  701. *(out++) = *(itr++);
  702. }
  703. return end;
  704. }
  705. template <typename Predicate,
  706. typename InputIterator,
  707. typename OutputIterator>
  708. inline InputIterator copy_until(Predicate predicate,
  709. const InputIterator begin, const InputIterator end,
  710. OutputIterator out)
  711. {
  712. InputIterator itr = begin;
  713. while (end != itr)
  714. {
  715. if (predicate(*itr))
  716. return itr;
  717. *(out++) = *(itr++);
  718. }
  719. return end;
  720. }
  721. template <typename InputIterator, typename OutputIterator>
  722. inline void extract_unique(const InputIterator begin, const InputIterator end,
  723. OutputIterator out)
  724. {
  725. typedef typename std::iterator_traits<InputIterator>::value_type T;
  726. std::vector<T> buffer(begin,end);
  727. std::sort(buffer.begin(),buffer.end());
  728. std::unique_copy(buffer.begin(),buffer.end(),out);
  729. }
  730. template <typename Predicate, typename InputIterator>
  731. inline bool range_only_contains(Predicate predicate,
  732. const InputIterator begin,
  733. const InputIterator end)
  734. {
  735. InputIterator itr = begin;
  736. while (end != itr)
  737. {
  738. if (!predicate(*itr))
  739. {
  740. return false;
  741. }
  742. ++itr;
  743. }
  744. return true;
  745. }
  746. namespace range
  747. {
  748. template <typename T>
  749. class adapter
  750. {
  751. public:
  752. typedef T value_type;
  753. typedef T* iterator;
  754. typedef const iterator const_iterator;
  755. adapter(T* const begin, T* const end)
  756. : begin_(begin),
  757. end_(end)
  758. {}
  759. adapter(const std::pair<T*,T*>& r)
  760. : begin_(r.first),
  761. end_(r.second)
  762. {}
  763. adapter(T* const begin, const std::size_t length)
  764. : begin_(begin),
  765. end_(begin_ + length)
  766. {}
  767. inline iterator begin() const
  768. {
  769. return begin_;
  770. }
  771. inline iterator end() const
  772. {
  773. return end_;
  774. }
  775. inline std::size_t size() const
  776. {
  777. return std::distance(begin_,end_);
  778. }
  779. inline operator std::string() const
  780. {
  781. return stringify(begin_,end_);
  782. }
  783. inline const T& operator[](const std::size_t& index) const
  784. {
  785. return *(begin_ + index);
  786. }
  787. inline T& operator[](const std::size_t& index)
  788. {
  789. return *(begin_ + index);
  790. }
  791. private:
  792. template <typename Type>
  793. static inline std::string stringify(Type*,Type*)
  794. {
  795. static std::string result = "";
  796. return result;
  797. }
  798. static inline std::string stringify(const char* begin, const char* end)
  799. {
  800. return std::string(begin,end);
  801. }
  802. iterator begin_;
  803. iterator end_;
  804. };
  805. typedef adapter<const char> string;
  806. typedef adapter<const unsigned char> ustring;
  807. template <typename T>
  808. inline adapter<T> type(const T* begin, const T* end)
  809. {
  810. return adapter<T>(begin,end);
  811. }
  812. template <typename T, std::size_t N>
  813. inline adapter<T> type(const T (&t)[N])
  814. {
  815. return adapter<T>(t,N);
  816. }
  817. static inline adapter<const char> type(const std::string& s)
  818. {
  819. return adapter<const char>(s.data(),s.size());
  820. }
  821. template <typename T,
  822. typename Allocator,
  823. template <typename,typename> class Sequence>
  824. inline adapter<typename Sequence<T,Allocator>::iterator> type(const Sequence<T,Allocator>& seq)
  825. {
  826. return adapter<typename Sequence<T,Allocator>::iterator>(seq.begin(),seq.end());
  827. }
  828. inline std::string as_string(const adapter<const char>& a)
  829. {
  830. return std::string(a.begin(),a.end());
  831. }
  832. inline std::string as_string(const adapter<const unsigned char>& a)
  833. {
  834. return std::string(a.begin(),a.end());
  835. }
  836. } // namespace range
  837. template <typename T>
  838. struct single_delimiter_predicate
  839. {
  840. public:
  841. typedef T value_type;
  842. single_delimiter_predicate(const T& d)
  843. : delimiter_(d)
  844. {}
  845. inline bool operator()(const T& d) const
  846. {
  847. return delimiter_ == d;
  848. }
  849. private:
  850. single_delimiter_predicate<T>& operator=(const single_delimiter_predicate<T>&);
  851. const T delimiter_;
  852. };
  853. template <typename T>
  854. struct multiple_delimiter_predicate
  855. {
  856. public:
  857. typedef T value_type;
  858. multiple_delimiter_predicate(const T* d_begin, const T* d_end)
  859. : length_(std::distance(d_begin,d_end)),
  860. delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
  861. delimiter_end_(delimiter_ + length_)
  862. {
  863. std::copy(d_begin,d_end, delimiter_);
  864. }
  865. multiple_delimiter_predicate(const T d[], const std::size_t& length)
  866. : length_(length),
  867. delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
  868. delimiter_end_(delimiter_ + length_)
  869. {
  870. std::copy(d,d + length, delimiter_);
  871. }
  872. template <typename Iterator>
  873. multiple_delimiter_predicate(const Iterator begin, const Iterator end)
  874. : length_(std::distance(begin,end)),
  875. delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
  876. delimiter_end_(delimiter_ + length_)
  877. {
  878. //static_assert(T == std::iterator_traits<Iterator>::value_type);
  879. std::copy(begin,end, delimiter_);
  880. }
  881. template <typename Type>
  882. multiple_delimiter_predicate(const range::adapter<Type>& r)
  883. : length_(std::distance(r.begin(),r.end())),
  884. delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
  885. delimiter_end_(delimiter_ + length_)
  886. {
  887. //static_assert(T == std::iterator_traits<Iterator>::value_type);
  888. std::copy(r.begin(),r.end(), delimiter_);
  889. }
  890. ~multiple_delimiter_predicate()
  891. {
  892. if (length_ > sbo_buffer_size)
  893. {
  894. delete[] delimiter_;
  895. }
  896. }
  897. inline bool operator()(const T& d) const
  898. {
  899. return (std::find(delimiter_,delimiter_end_,d) != delimiter_end_);
  900. }
  901. private:
  902. multiple_delimiter_predicate(const multiple_delimiter_predicate<T>& mdp);
  903. multiple_delimiter_predicate& operator=(const multiple_delimiter_predicate<T>& mdp);
  904. std::size_t length_;
  905. T* delimiter_;
  906. T* delimiter_end_;
  907. enum { sbo_buffer_size = 32 };
  908. T sbo_buffer[sbo_buffer_size];
  909. };
  910. struct multiple_char_delimiter_predicate
  911. {
  912. public:
  913. template <typename Iterator>
  914. multiple_char_delimiter_predicate(const Iterator begin, const Iterator end)
  915. {
  916. setup_delimiter_table(begin,end);
  917. }
  918. multiple_char_delimiter_predicate(const std::string& s)
  919. {
  920. setup_delimiter_table(s.data(),s.data() + s.size());
  921. }
  922. inline bool operator()(const unsigned char& c) const
  923. {
  924. return (delimiter_table_[c]);
  925. }
  926. inline bool operator()(const char& c) const
  927. {
  928. return operator()(static_cast<unsigned char>(c));
  929. }
  930. private:
  931. static const std::size_t table_size = 256;
  932. template <typename Iterator>
  933. inline void setup_delimiter_table(const Iterator begin, const Iterator end)
  934. {
  935. std::fill_n(delimiter_table_,table_size,false);
  936. for (Iterator itr = begin; itr != end; ++itr)
  937. {
  938. delimiter_table_[static_cast<unsigned char>(*itr)] = true;
  939. }
  940. }
  941. bool delimiter_table_[table_size];
  942. };
  943. namespace details
  944. {
  945. template <typename Allocator,
  946. template <typename,typename> class Sequence>
  947. struct index_remover_impl
  948. {
  949. typedef Sequence<std::size_t,Allocator> sequence_t;
  950. index_remover_impl(const sequence_t& sequence)
  951. : itr_(sequence.begin()),
  952. end_(sequence.end()),
  953. current_index_(0),
  954. check_(true)
  955. {}
  956. template <typename T>
  957. inline bool operator()(const T&)
  958. {
  959. if (check_)
  960. {
  961. if (current_index_++ == *itr_)
  962. {
  963. if (end_ == ++itr_)
  964. {
  965. check_ = false;
  966. }
  967. return true;
  968. }
  969. }
  970. return false;
  971. }
  972. typename sequence_t::const_iterator itr_;
  973. typename sequence_t::const_iterator end_;
  974. std::size_t current_index_;
  975. bool check_;
  976. };
  977. }
  978. template <typename Allocator,
  979. template <typename,typename> class Sequence>
  980. inline details::index_remover_impl<Allocator,Sequence> index_remover(const Sequence<std::size_t,Allocator>& sequence)
  981. {
  982. return details::index_remover_impl<Allocator,Sequence>(sequence);
  983. }
  984. template <typename Iterator, typename Predicate>
  985. inline std::size_t remove_inplace(Predicate predicate,
  986. Iterator begin,
  987. Iterator end)
  988. {
  989. Iterator itr1 = begin;
  990. Iterator itr2 = begin;
  991. std::size_t removal_count = 0;
  992. while (end != itr1)
  993. {
  994. if (predicate(*itr1))
  995. {
  996. ++itr1;
  997. ++removal_count;
  998. }
  999. else
  1000. {
  1001. if (itr1 != itr2)
  1002. {
  1003. (*itr2) = (*itr1);
  1004. }
  1005. ++itr1;
  1006. ++itr2;
  1007. }
  1008. }
  1009. return removal_count;
  1010. }
  1011. template <typename T, typename Predicate>
  1012. inline std::size_t remove_inplace(Predicate predicate, const range::adapter<T>& r)
  1013. {
  1014. return remove_inplace(predicate,r.begin(),r.end());
  1015. }
  1016. template <typename Predicate,
  1017. typename T,
  1018. typename Allocator,
  1019. template <typename,typename> class Sequence>
  1020. inline std::size_t remove_inplace(Predicate predicate, Sequence<T,Allocator>& sequence)
  1021. {
  1022. const std::size_t removal_count = remove_inplace(predicate,sequence.begin(),sequence.end());
  1023. sequence.resize(sequence.size() - removal_count);
  1024. return removal_count;
  1025. }
  1026. inline void remove_inplace(const std::string::value_type c, std::string& s)
  1027. {
  1028. const std::size_t removal_count = remove_inplace(single_delimiter_predicate<std::string::value_type>(c),
  1029. const_cast<char*>(s.data()),
  1030. const_cast<char*>(s.data() + s.size()));
  1031. if (removal_count > 0)
  1032. {
  1033. s.resize(s.size() - removal_count);
  1034. }
  1035. }
  1036. template <typename Predicate>
  1037. inline void remove_inplace(Predicate predicate, std::string& s)
  1038. {
  1039. const std::size_t removal_count = remove_inplace(predicate,
  1040. const_cast<char*>(s.data()),
  1041. const_cast<char*>(s.data() + s.size()));
  1042. if (removal_count > 0)
  1043. {
  1044. s.resize(s.size() - removal_count);
  1045. }
  1046. }
  1047. template <typename Iterator, typename Predicate>
  1048. inline std::size_t remove_consecutives_inplace(Predicate predicate,
  1049. Iterator begin,
  1050. Iterator end)
  1051. {
  1052. if (0 == std::distance(begin,end)) return 0;
  1053. Iterator itr1 = begin;
  1054. Iterator itr2 = begin;
  1055. typename std::iterator_traits<Iterator>::value_type prev = *begin;
  1056. std::size_t removal_count = 0;
  1057. ++itr1;
  1058. ++itr2;
  1059. while (end != itr1)
  1060. {
  1061. while ((end != itr1) && (!predicate(*itr1) || !predicate(prev)))
  1062. {
  1063. if (itr1 != itr2)
  1064. {
  1065. (*itr2) = (*itr1);
  1066. }
  1067. prev = (*itr1);
  1068. ++itr1;
  1069. ++itr2;
  1070. }
  1071. while ((end != itr1) && predicate(*itr1))
  1072. {
  1073. ++itr1;
  1074. ++removal_count;
  1075. }
  1076. }
  1077. return removal_count;
  1078. }
  1079. template <typename T, typename Predicate>
  1080. inline std::size_t remove_consecutives_inplace(Predicate predicate, const range::adapter<T>& r)
  1081. {
  1082. return remove_consecutives_inplace(predicate,r.begin(),r.end());
  1083. }
  1084. inline void remove_consecutives_inplace(const std::string::value_type c, std::string& s)
  1085. {
  1086. if (s.empty()) return;
  1087. const std::size_t removal_count = remove_consecutives_inplace(single_delimiter_predicate<std::string::value_type>(c),
  1088. const_cast<char*>(s.data()),
  1089. const_cast<char*>(s.data() + s.size()));
  1090. if (removal_count > 0)
  1091. {
  1092. s.resize(s.size() - removal_count);
  1093. }
  1094. }
  1095. inline void remove_consecutives_inplace(const std::string& rem_chars, std::string& s)
  1096. {
  1097. if (s.empty()) return;
  1098. const std::size_t removal_count = remove_consecutives_inplace(multiple_char_delimiter_predicate(rem_chars),
  1099. const_cast<char*>(s.data()),
  1100. const_cast<char*>(s.data() + s.size()));
  1101. if (removal_count > 0)
  1102. {
  1103. s.resize(s.size() - removal_count);
  1104. }
  1105. }
  1106. namespace details
  1107. {
  1108. #if (defined(__MINGW32_VERSION)) ||\
  1109. (defined(__APPLE__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)) ||\
  1110. (defined(_WIN32) && (_MSC_VER < 1400))
  1111. inline std::size_t strnlength(const char* s, const std::size_t& n)
  1112. {
  1113. const char *end = reinterpret_cast<const char*>(memchr(s, '\0', n));
  1114. return end ? (size_t) (end - s) : n;
  1115. }
  1116. #else
  1117. inline std::size_t strnlength(const char* s, const std::size_t& n)
  1118. {
  1119. return strnlen(s,n);
  1120. }
  1121. #endif
  1122. }
  1123. inline void remove_consecutives_inplace(const char* rem_chars, std::string& s)
  1124. {
  1125. if (s.empty()) return;
  1126. const std::size_t removal_count = remove_consecutives_inplace(multiple_char_delimiter_predicate(
  1127. rem_chars,
  1128. rem_chars + details::strnlength(rem_chars,256)),
  1129. const_cast<char*>(s.data()),
  1130. const_cast<char*>(s.data() + s.size()));
  1131. if (removal_count > 0)
  1132. {
  1133. s.resize(s.size() - removal_count);
  1134. }
  1135. }
  1136. template <typename Predicate>
  1137. inline void remove_consecutives_inplace(Predicate predicate, std::string& s)
  1138. {
  1139. if (s.empty()) return;
  1140. const std::size_t removal_count = remove_consecutives_inplace(predicate,
  1141. const_cast<char*>(s.data()),
  1142. const_cast<char*>(s.data() + s.size()));
  1143. if (removal_count > 0)
  1144. {
  1145. s.resize(s.size() - removal_count);
  1146. }
  1147. }
  1148. template <typename Iterator>
  1149. inline std::size_t remove_consecutives_inplace(Iterator begin, Iterator end)
  1150. {
  1151. if (0 == std::distance(begin,end)) return 0;
  1152. Iterator itr1 = begin; ++itr1;
  1153. Iterator itr2 = begin; ++itr2;
  1154. typename std::iterator_traits<Iterator>::value_type prev = *begin;
  1155. std::size_t removal_count = 0;
  1156. while (end != itr1)
  1157. {
  1158. while ((end != itr1) && (prev != (*itr1)))
  1159. {
  1160. if (itr1 != itr2)
  1161. {
  1162. (*itr2) = (*itr1);
  1163. }
  1164. prev = (*itr1);
  1165. ++itr1;
  1166. ++itr2;
  1167. }
  1168. while ((end != itr1) && (prev == (*itr1)))
  1169. {
  1170. ++itr1;
  1171. ++removal_count;
  1172. }
  1173. }
  1174. return removal_count;
  1175. }
  1176. template <typename T>
  1177. inline std::size_t remove_consecutives_inplace(const range::adapter<T>& r)
  1178. {
  1179. return remove_consecutives_inplace(r.begin(),r.end());
  1180. }
  1181. template <typename T,
  1182. typename Allocator,
  1183. template <typename,typename> class Sequence>
  1184. inline void remove_consecutives_inplace(Sequence<T,Allocator>& sequence)
  1185. {
  1186. const std::size_t removal_count = remove_consecutives_inplace(sequence.begin(),sequence.end());
  1187. sequence.resize(sequence.size() - removal_count);
  1188. }
  1189. inline void remove_consecutives_inplace(std::string& s)
  1190. {
  1191. std::size_t removal_count = remove_consecutives_inplace(const_cast<char*>(s.data()),
  1192. const_cast<char*>(s.data() + s.size()));
  1193. if (removal_count > 0)
  1194. {
  1195. s.resize(s.size() - removal_count);
  1196. }
  1197. }
  1198. inline std::string remove_duplicates(const std::string& str)
  1199. {
  1200. std::string::value_type table[0xFF];
  1201. std::fill_n(table,0xFF,static_cast<char>(0));
  1202. std::string result;
  1203. result.reserve(str.size());
  1204. for (std::size_t i = 0; i < str.size(); ++i)
  1205. {
  1206. const char c = str[i];
  1207. if (0 == table[static_cast<std::size_t>(c)])
  1208. {
  1209. table[static_cast<std::size_t>(c)] = 0x01;
  1210. result += c;
  1211. }
  1212. }
  1213. return result;
  1214. }
  1215. inline std::string remove_duplicates_inplace(std::string& str)
  1216. {
  1217. return remove_duplicates(str);
  1218. }
  1219. template <typename Iterator, typename Predicate>
  1220. inline std::size_t remove_trailing(Predicate predicate,
  1221. Iterator begin,
  1222. Iterator end)
  1223. {
  1224. const std::size_t length = std::distance(begin,end);
  1225. if (0 == length)
  1226. return 0;
  1227. Iterator itr = begin + (length - 1);
  1228. std::size_t removal_count = 0;
  1229. while ((begin != itr) && predicate(*itr))
  1230. {
  1231. --itr;
  1232. ++removal_count;
  1233. }
  1234. return removal_count;
  1235. }
  1236. template <typename T, typename Predicate>
  1237. inline std::size_t remove_trailing(Predicate predicate, const range::adapter<T>& r)
  1238. {
  1239. return remove_trailing(predicate,r.begin(),r.end());
  1240. }
  1241. inline void remove_trailing(const std::string::value_type c, std::string& s)
  1242. {
  1243. if (s.empty()) return;
  1244. const std::size_t removal_count = remove_trailing(single_delimiter_predicate<std::string::value_type>(c),
  1245. const_cast<char*>(s.data()),
  1246. const_cast<char*>(s.data() + s.size()));
  1247. if (removal_count > 0)
  1248. {
  1249. s.resize(s.size() - removal_count);
  1250. }
  1251. }
  1252. inline void remove_trailing(const std::string& rem_chars, std::string& s)
  1253. {
  1254. if (s.empty()) return;
  1255. const std::size_t removal_count = remove_trailing(multiple_char_delimiter_predicate(rem_chars),
  1256. const_cast<char*>(s.data()),
  1257. const_cast<char*>(s.data() + s.size()));
  1258. if (removal_count > 0)
  1259. {
  1260. s.resize(s.size() - removal_count);
  1261. }
  1262. }
  1263. inline void remove_trailing(const char* rem_chars, std::string& s)
  1264. {
  1265. const std::size_t removal_count = remove_trailing(multiple_char_delimiter_predicate(
  1266. rem_chars,
  1267. rem_chars + details::strnlength(rem_chars,256)),
  1268. const_cast<char*>(s.data()),
  1269. const_cast<char*>(s.data() + s.size()));
  1270. if (removal_count > 0)
  1271. {
  1272. s.resize(s.size() - removal_count);
  1273. }
  1274. }
  1275. template <typename Predicate>
  1276. inline void remove_trailing(Predicate predicate, std::string& s)
  1277. {
  1278. if (s.empty()) return;
  1279. const std::size_t removal_count = remove_trailing(predicate,
  1280. const_cast<char*>(s.data()),
  1281. const_cast<char*>(s.data() + s.size()));
  1282. if (removal_count > 0)
  1283. {
  1284. s.resize(s.size() - removal_count);
  1285. }
  1286. }
  1287. template <typename Iterator, typename Predicate>
  1288. inline std::size_t remove_leading(Predicate predicate,
  1289. Iterator begin,
  1290. Iterator end)
  1291. {
  1292. const std::size_t length = std::distance(begin,end);
  1293. if (0 == length)
  1294. return 0;
  1295. Iterator itr = begin;
  1296. std::size_t removal_count = 0;
  1297. while ((end != itr) && predicate(*itr))
  1298. {
  1299. ++itr;
  1300. ++removal_count;
  1301. }
  1302. std::copy(itr,end,begin);
  1303. return removal_count;
  1304. }
  1305. template <typename T, typename Predicate>
  1306. inline std::size_t remove_leading(Predicate predicate, const range::adapter<T>& r)
  1307. {
  1308. return remove_leading(predicate,r.begin(),r.end());
  1309. }
  1310. inline void remove_leading(const std::string::value_type c, std::string& s)
  1311. {
  1312. if (s.empty()) return;
  1313. const std::size_t removal_count = remove_leading(single_delimiter_predicate<std::string::value_type>(c),
  1314. const_cast<char*>(s.data()),
  1315. const_cast<char*>(s.data() + s.size()));
  1316. if (removal_count > 0)
  1317. {
  1318. s.resize(s.size() - removal_count);
  1319. }
  1320. }
  1321. inline void remove_leading(const std::string& rem_chars, std::string& s)
  1322. {
  1323. if (s.empty()) return;
  1324. const std::size_t removal_count = remove_leading(multiple_char_delimiter_predicate(rem_chars),
  1325. const_cast<char*>(s.data()),
  1326. const_cast<char*>(s.data() + s.size()));
  1327. if (removal_count > 0)
  1328. {
  1329. s.resize(s.size() - removal_count);
  1330. }
  1331. }
  1332. inline void remove_leading(const char* rem_chars, std::string& s)
  1333. {
  1334. if (s.empty()) return;
  1335. const std::size_t removal_count = remove_leading(multiple_char_delimiter_predicate(
  1336. rem_chars,
  1337. rem_chars + details::strnlength(rem_chars,256)),
  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_trailing(const std::string& rem_chars, std::string& s)
  1346. {
  1347. remove_leading(rem_chars,s);
  1348. remove_trailing(rem_chars,s);
  1349. }
  1350. template <typename Predicate>
  1351. inline void remove_leading(Predicate predicate, std::string& s)
  1352. {
  1353. if (s.empty()) return;
  1354. const std::size_t removal_count = remove_leading(predicate,
  1355. const_cast<char*>(s.data()),
  1356. const_cast<char*>(s.data() + s.size()));
  1357. if (removal_count > 0)
  1358. {
  1359. s.resize(s.size() - removal_count);
  1360. }
  1361. }
  1362. template <typename Allocator,
  1363. template <typename,typename> class Sequence>
  1364. void remove_empty_strings(Sequence<std::string,Allocator>& seq)
  1365. {
  1366. struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
  1367. seq.erase(std::remove_if(seq.begin(),seq.end(),is_empty::check),seq.end());
  1368. }
  1369. template <typename Allocator>
  1370. void remove_empty_strings(std::list<std::string,Allocator>& l)
  1371. {
  1372. struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
  1373. l.remove_if(is_empty::check);
  1374. }
  1375. template <typename Comparator, typename Allocator>
  1376. void remove_empty_strings(std::set<std::string,Comparator,Allocator>& set)
  1377. {
  1378. struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
  1379. typename std::set<std::string,Comparator,Allocator>::iterator itr = set.begin();
  1380. while (set.end() != itr)
  1381. {
  1382. if ((*itr).empty())
  1383. set.erase(itr++);
  1384. else
  1385. ++itr;
  1386. }
  1387. }
  1388. template <typename Comparator, typename Allocator>
  1389. void remove_empty_strings(std::multiset<std::string,Comparator,Allocator>& set)
  1390. {
  1391. struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
  1392. typename std::multiset<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 Iterator>
  1402. inline void replace(const typename std::iterator_traits<Iterator>::value_type& c1,
  1403. const typename std::iterator_traits<Iterator>::value_type& c2,
  1404. const Iterator begin,
  1405. const Iterator end)
  1406. {
  1407. for (Iterator itr = begin; end != itr; ++itr)
  1408. {
  1409. if (c1 == (*itr))
  1410. {
  1411. (*itr) = c2;
  1412. }
  1413. }
  1414. }
  1415. inline void replace(const std::string::value_type& c0,
  1416. const std::string::value_type& c1,
  1417. std::string& s)
  1418. {
  1419. replace(c0,c1,const_cast<char*>(s.data()),const_cast<char*>(s.data() + s.size()));
  1420. }
  1421. template <typename T>
  1422. inline void replace(const T& c1, const T& c2, const range::adapter<T>& r)
  1423. {
  1424. replace(c1,c2,r.begin(),r.end());
  1425. }
  1426. inline void replace_pattern(const std::string& s, // input
  1427. const std::string& p, // pattern
  1428. const std::string& r, // replacement
  1429. std::string& n)
  1430. {
  1431. if (p.empty() || (p == r))
  1432. {
  1433. n.assign(s);
  1434. return;
  1435. }
  1436. const std::size_t p_size = p.size();
  1437. const std::size_t r_size = r.size();
  1438. int inc = static_cast<int>(r_size) - static_cast<int>(p_size);
  1439. std::size_t pos = 0;
  1440. std::vector<std::size_t> delta_list;
  1441. delta_list.reserve(std::min<std::size_t>(32,(s.size() / p_size) + 1));
  1442. while (std::string::npos != (pos = s.find(p,pos)))
  1443. {
  1444. delta_list.push_back(pos);
  1445. pos += p_size;
  1446. }
  1447. if (delta_list.empty())
  1448. {
  1449. n.assign(s);
  1450. return;
  1451. }
  1452. n.resize(delta_list.size() * inc + s.size(), 0x00);
  1453. char* n_itr = const_cast<char*>(n.data());
  1454. const char* s_end = s.data() + s.size();
  1455. const char* s_itr = s.data();
  1456. const char* r_begin = r.data();
  1457. const char* r_end = r.data() + r_size;
  1458. const std::size_t delta_list_size = delta_list.size();
  1459. std::size_t i = 0;
  1460. std::size_t delta = delta_list[0];
  1461. for ( ; ; )
  1462. {
  1463. std::copy(s_itr, s_itr + delta, n_itr);
  1464. s_itr += p_size + delta;
  1465. n_itr += delta;
  1466. std::copy(r_begin, r_end, n_itr);
  1467. n_itr += r_size;
  1468. if (++i >= delta_list_size)
  1469. break;
  1470. delta = delta_list[i] - (delta_list[i - 1] + p_size);
  1471. }
  1472. if (s_end != s_itr)
  1473. {
  1474. std::copy(s_itr, s_end, n_itr);
  1475. }
  1476. }
  1477. template <typename InputIterator, typename OutputIterator>
  1478. inline std::size_t replace_pattern(const InputIterator s_begin, const InputIterator s_end, // input
  1479. const InputIterator p_begin, const InputIterator p_end, // pattern
  1480. const InputIterator r_begin, const InputIterator r_end, // replacement
  1481. OutputIterator out)
  1482. {
  1483. typedef typename std::iterator_traits<InputIterator>::value_type T;
  1484. InputIterator s_itr = s_begin;
  1485. InputIterator r_itr = r_begin;
  1486. InputIterator p_itr = p_begin;
  1487. const std::size_t p_size = std::distance(p_begin,p_end);
  1488. const std::size_t r_size = std::distance(r_begin,r_end);
  1489. if ((0 == p_size) || ((p_size == r_size) && std::equal(p_begin,p_end,r_begin)))
  1490. {
  1491. std::copy(s_begin,s_end,out);
  1492. return std::distance(s_begin,s_end);
  1493. }
  1494. std::size_t pos = 0;
  1495. std::size_t prev_pos = 0;
  1496. std::size_t count = 0;
  1497. std::size_t new_size = std::distance(s_begin,s_end);
  1498. int inc = r_size - p_size;
  1499. InputIterator temp_s_itr = s_itr;
  1500. while (s_end != s_itr)
  1501. {
  1502. /*
  1503. Need to replace the following search code with
  1504. Knuth-Pratt-Morris or Boyer-Moore string search
  1505. algorithms.
  1506. */
  1507. bool found = true;
  1508. p_itr = p_begin;
  1509. temp_s_itr = s_itr;
  1510. while ((p_end != p_itr) && (s_end != temp_s_itr))
  1511. {
  1512. if (*(temp_s_itr++) != *(p_itr++))
  1513. {
  1514. found = false;
  1515. break;
  1516. }
  1517. }
  1518. if (found && (p_itr == p_end))
  1519. {
  1520. ++count;
  1521. new_size += inc;
  1522. s_itr = temp_s_itr;
  1523. }
  1524. else
  1525. ++s_itr;
  1526. }
  1527. s_itr = s_begin;
  1528. p_itr = p_begin;
  1529. pos = 0;
  1530. prev_pos = 0;
  1531. temp_s_itr = s_itr;
  1532. while (0 < count)
  1533. {
  1534. p_itr = p_begin;
  1535. bool found = true;
  1536. InputIterator pattern_start = temp_s_itr;
  1537. while ((p_end != p_itr) && (s_end != temp_s_itr))
  1538. {
  1539. if (*(temp_s_itr++) != *(p_itr++))
  1540. {
  1541. found = false;
  1542. temp_s_itr = pattern_start;
  1543. ++temp_s_itr;
  1544. break;
  1545. }
  1546. }
  1547. if (!found || (p_itr != p_end)) continue;
  1548. pos = std::distance(s_begin,temp_s_itr) - p_size;
  1549. int diff = pos - prev_pos;
  1550. std::copy(s_itr,s_itr + diff, out);
  1551. s_itr = temp_s_itr;
  1552. std::copy(r_itr,r_end, out);
  1553. pos += p_size;
  1554. prev_pos = pos;
  1555. --count;
  1556. }
  1557. std::copy(s_itr,s_end,out);
  1558. return new_size;
  1559. }
  1560. inline void remove_pattern(const std::string& s,
  1561. const std::string& p,
  1562. std::string& n)
  1563. {
  1564. static const std::string r("");
  1565. replace_pattern(s,p,r,n);
  1566. }
  1567. inline void sort(std::string& s)
  1568. {
  1569. std::sort(s.begin(),s.end());
  1570. }
  1571. template <typename Iterator>
  1572. inline bool match(const Iterator pattern_begin,
  1573. const Iterator pattern_end,
  1574. const Iterator data_begin,
  1575. const Iterator data_end,
  1576. const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
  1577. const typename std::iterator_traits<Iterator>::value_type& zero_or_one)
  1578. {
  1579. /*
  1580. Credits: Adapted from code by Jack Handy (2001)
  1581. */
  1582. if (0 == std::distance(data_begin,data_end)) return false;
  1583. Iterator d_itr = data_begin;
  1584. Iterator p_itr = pattern_begin;
  1585. Iterator c_itr = data_begin;
  1586. Iterator m_itr = data_begin;
  1587. while ((data_end != d_itr) && (zero_or_more != (*p_itr)))
  1588. {
  1589. if (((*p_itr) != (*d_itr)) && (zero_or_one != (*p_itr)))
  1590. {
  1591. return false;
  1592. }
  1593. ++p_itr;
  1594. ++d_itr;
  1595. }
  1596. while (data_end != d_itr)
  1597. {
  1598. if (zero_or_more == (*p_itr))
  1599. {
  1600. if (pattern_end == (++p_itr))
  1601. {
  1602. return true;
  1603. }
  1604. m_itr = p_itr;
  1605. c_itr = d_itr;
  1606. ++c_itr;
  1607. }
  1608. else if (((*p_itr) == (*d_itr)) || (zero_or_one == (*p_itr)))
  1609. {
  1610. ++p_itr;
  1611. ++d_itr;
  1612. }
  1613. else
  1614. {
  1615. p_itr = m_itr;
  1616. d_itr = c_itr++;
  1617. }
  1618. }
  1619. while ((p_itr != pattern_end) && (zero_or_more == (*p_itr))) ++p_itr;
  1620. return (p_itr == pattern_end);
  1621. }
  1622. inline bool match(const std::string& wild_card,
  1623. const std::string& str)
  1624. {
  1625. /*
  1626. * : Zero or more match
  1627. ? : Zero or one match
  1628. */
  1629. return match(wild_card.data(),
  1630. wild_card.data() + wild_card.size(),
  1631. str.data(),
  1632. str.data() + str.size(),
  1633. '*',
  1634. '?');
  1635. }
  1636. inline bool imatch_char(const char c1, const char c2)
  1637. {
  1638. return std::toupper(c1) == std::toupper(c2);
  1639. }
  1640. template <typename InputIterator>
  1641. inline bool imatch(const InputIterator begin1, const InputIterator end1,
  1642. const InputIterator begin2, const InputIterator end2)
  1643. {
  1644. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1645. if (std::distance(begin1,end1) != std::distance(begin2,end2))
  1646. {
  1647. return false;
  1648. }
  1649. InputIterator itr1 = begin1;
  1650. InputIterator itr2 = begin2;
  1651. while (end1 != itr1)
  1652. {
  1653. //if (std::toupper(*itr1, std::locale::classic()) != std::toupper(*it2, std::locale::classic()))
  1654. if (std::toupper(*itr1) != std::toupper(*itr2))
  1655. {
  1656. return false;
  1657. }
  1658. ++itr1;
  1659. ++itr2;
  1660. }
  1661. return true;
  1662. }
  1663. template <typename T>
  1664. inline bool imatch(const range::adapter<T>& r1, const range::adapter<T>& r2)
  1665. {
  1666. return imatch(r1.begin(),r1.end(),r2.begin(),r2.end());
  1667. }
  1668. inline bool imatch(const std::string& s1, const std::string& s2)
  1669. {
  1670. return imatch(s1.data(),
  1671. s1.data() + s1.size(),
  1672. s2.data(),
  1673. s2.data() + s2.size());
  1674. }
  1675. template <typename Iterator>
  1676. inline Iterator imatch(const std::string& s, const Iterator begin, const Iterator end)
  1677. {
  1678. for (const std::string* itr = begin; end != itr; ++itr)
  1679. {
  1680. if (imatch(s,*itr))
  1681. {
  1682. return itr;
  1683. }
  1684. }
  1685. return end;
  1686. }
  1687. template <typename Allocator,
  1688. template <typename,typename> class Sequence>
  1689. inline bool imatch(const std::string& s, const Sequence<std::string,Allocator>& sequence)
  1690. {
  1691. return (sequence.end() != imatch(s,sequence.begin(),sequence.end()));
  1692. }
  1693. template <typename Comparator, typename Allocator>
  1694. inline bool imatch(const std::string& s, const std::set<std::string,Comparator,Allocator>& set)
  1695. {
  1696. return imatch(s,set.begin(),set.end());
  1697. }
  1698. template <typename Comparator, typename Allocator>
  1699. inline bool imatch(const std::string& s, const std::multiset<std::string,Comparator,Allocator>& multiset)
  1700. {
  1701. return imatch(s,multiset.begin(),multiset.end());
  1702. }
  1703. template <typename Iterator, typename OutputIterator>
  1704. inline std::size_t find_all(const Iterator pattern_begin,
  1705. const Iterator pattern_end,
  1706. const Iterator begin,
  1707. const Iterator end,
  1708. OutputIterator out)
  1709. {
  1710. Iterator itr = begin;
  1711. const std::size_t pattern_length = std::distance(pattern_begin,pattern_end);
  1712. std::size_t match_count = 0;
  1713. while (end != (itr = std::search(itr, end, pattern_begin, pattern_end)))
  1714. {
  1715. (*out) = std::make_pair(itr,itr + pattern_length);
  1716. itr += pattern_length;
  1717. ++out;
  1718. ++match_count;
  1719. }
  1720. return match_count;
  1721. }
  1722. template <typename Iterator,
  1723. typename Range,
  1724. typename Allocator,
  1725. template <typename,typename> class Sequence>
  1726. inline std::size_t find_all(const Iterator pattern_begin,
  1727. const Iterator pattern_end,
  1728. const Iterator begin,
  1729. const Iterator end,
  1730. Sequence<Range,Allocator>& seq)
  1731. {
  1732. return find_all(pattern_begin,pattern_end,begin,end,std::back_inserter(seq));
  1733. }
  1734. inline std::size_t ifind(const std::string& pattern, const std::string& data)
  1735. {
  1736. if (pattern.size() > data.size())
  1737. return std::string::npos;
  1738. const char* result_itr = std::search(data.data(),data.data() + data.size(),
  1739. pattern.data(), pattern.data() + pattern.size(),
  1740. imatch_char);
  1741. if ((data.data() + data.size()) == result_itr)
  1742. return std::string::npos;
  1743. else
  1744. return std::distance(data.data(),result_itr);
  1745. }
  1746. template <typename Iterator, typename OutputIterator>
  1747. inline std::size_t ifind_all(const Iterator pattern_begin,
  1748. const Iterator pattern_end,
  1749. const Iterator begin,
  1750. const Iterator end,
  1751. OutputIterator out)
  1752. {
  1753. Iterator itr = begin;
  1754. const std::size_t pattern_length = std::distance(pattern_begin,pattern_end);
  1755. std::size_t match_count = 0;
  1756. while (end != (itr = std::search(itr, end, pattern_begin, pattern_end, imatch_char)))
  1757. {
  1758. (*out) = std::make_pair(itr,itr + pattern_length);
  1759. itr += pattern_length;
  1760. ++out;
  1761. ++match_count;
  1762. }
  1763. return match_count;
  1764. }
  1765. template <typename OutputIterator>
  1766. inline std::size_t find_all(const std::string& pattern,
  1767. const std::string& data,
  1768. OutputIterator out)
  1769. {
  1770. return find_all(pattern.data(), pattern.data() + pattern.size(),
  1771. data.data(), data.data() + data.size(),
  1772. out);
  1773. }
  1774. template <typename Range,
  1775. typename Allocator,
  1776. template <typename,typename> class Sequence>
  1777. inline std::size_t find_all(const std::string& pattern,
  1778. const std::string& data,
  1779. Sequence<Range,Allocator>& seq)
  1780. {
  1781. return find_all(pattern,data,std::back_inserter(seq));
  1782. }
  1783. template <typename OutputIterator>
  1784. inline std::size_t ifind_all(const std::string& pattern,
  1785. const std::string& data,
  1786. OutputIterator out)
  1787. {
  1788. return ifind_all(pattern.data(), pattern.data() + pattern.size(),
  1789. data.data(), data.data() + data.size(),
  1790. out);
  1791. }
  1792. template <typename Range,
  1793. typename Allocator,
  1794. template <typename,typename> class Sequence>
  1795. inline std::size_t ifind_all(const std::string& pattern,
  1796. const std::string& data,
  1797. Sequence<Range,Allocator>& seq)
  1798. {
  1799. return ifind_all(pattern,data,std::back_inserter(seq));
  1800. }
  1801. template <typename InputIterator>
  1802. inline bool begins_with(const InputIterator pattern_begin,
  1803. const InputIterator pattern_end,
  1804. const InputIterator begin,
  1805. const InputIterator end)
  1806. {
  1807. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1808. if (std::distance(pattern_begin,pattern_end) <= std::distance(begin,end))
  1809. {
  1810. return std::equal(pattern_begin,pattern_end,begin);
  1811. }
  1812. else
  1813. return false;
  1814. }
  1815. inline bool begins_with(const std::string& pattern, const std::string& data)
  1816. {
  1817. if (pattern.size() <= data.size())
  1818. {
  1819. return begins_with(pattern.data(),
  1820. pattern.data() + pattern.size(),
  1821. data.data(),
  1822. data.data() + data.size());
  1823. }
  1824. else
  1825. return false;
  1826. }
  1827. template <typename InputIterator>
  1828. inline bool ibegins_with(const InputIterator pattern_begin,
  1829. const InputIterator pattern_end,
  1830. const InputIterator begin,
  1831. const InputIterator end)
  1832. {
  1833. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1834. if (std::distance(pattern_begin,pattern_end) <= std::distance(begin,end))
  1835. {
  1836. return std::equal(pattern_begin,pattern_end,begin,imatch_char);
  1837. }
  1838. else
  1839. return false;
  1840. }
  1841. inline bool ibegins_with(const std::string& pattern, const std::string& data)
  1842. {
  1843. if (pattern.size() <= data.size())
  1844. {
  1845. return ibegins_with(pattern.data(),
  1846. pattern.data() + pattern.size(),
  1847. data.data(),
  1848. data.data() + data.size());
  1849. }
  1850. else
  1851. return false;
  1852. }
  1853. template <typename InputIterator>
  1854. inline bool ends_with(const InputIterator pattern_begin,
  1855. const InputIterator pattern_end,
  1856. const InputIterator begin,
  1857. const InputIterator end)
  1858. {
  1859. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1860. const std::size_t pattern_length = std::distance(pattern_begin,pattern_end);
  1861. const std::size_t data_length = std::distance(begin,end);
  1862. if (pattern_length <= data_length)
  1863. {
  1864. return std::equal(pattern_begin,
  1865. pattern_end,
  1866. begin + (data_length - pattern_length));
  1867. }
  1868. else
  1869. return false;
  1870. }
  1871. inline bool ends_with(const std::string& pattern, const std::string& data)
  1872. {
  1873. if (pattern.size() <= data.size())
  1874. {
  1875. return ends_with(pattern.data(),
  1876. pattern.data() + pattern.size(),
  1877. data.data(),
  1878. data.data() + data.size());
  1879. }
  1880. else
  1881. return false;
  1882. }
  1883. template <typename InputIterator>
  1884. inline bool iends_with(const InputIterator pattern_begin,
  1885. const InputIterator pattern_end,
  1886. const InputIterator begin,
  1887. const InputIterator end)
  1888. {
  1889. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1890. const std::size_t pattern_length = std::distance(pattern_begin,pattern_end);
  1891. const std::size_t data_length = std::distance(begin,end);
  1892. if (pattern_length <= data_length)
  1893. {
  1894. return std::equal(pattern_begin,
  1895. pattern_end,
  1896. begin + (data_length - pattern_length),
  1897. imatch_char);
  1898. }
  1899. else
  1900. return false;
  1901. }
  1902. inline bool iends_with(const std::string& pattern, const std::string& data)
  1903. {
  1904. if (pattern.size() <= data.size())
  1905. {
  1906. return iends_with(pattern.data(),
  1907. pattern.data() + pattern.size(),
  1908. data.data(),
  1909. data.data() + data.size());
  1910. }
  1911. else
  1912. return false;
  1913. }
  1914. inline std::size_t index_of(const std::string& pattern, const std::string& data)
  1915. {
  1916. if (pattern.empty())
  1917. return std::string::npos;
  1918. else if (data.empty())
  1919. return std::string::npos;
  1920. else if (pattern.size() > data.size())
  1921. return std::string::npos;
  1922. const char* itr = std::search(data.data(),
  1923. data.data() + data.size(),
  1924. pattern.data(),
  1925. pattern.data() + pattern.size());
  1926. return ((data.data() + data.size()) == itr) ? std::string::npos : std::distance(data.data(),itr);
  1927. }
  1928. namespace tokenize_options
  1929. {
  1930. typedef std::size_t type;
  1931. enum
  1932. {
  1933. default_mode = 0,
  1934. compress_delimiters = 1,
  1935. include_1st_delimiter = 2,
  1936. include_all_delimiters = 4
  1937. };
  1938. static inline bool perform_compress_delimiters(const type& split_opt)
  1939. {
  1940. return compress_delimiters == (split_opt & compress_delimiters);
  1941. }
  1942. static inline bool perform_include_1st_delimiter(const type& split_opt)
  1943. {
  1944. return include_1st_delimiter == (split_opt & include_1st_delimiter);
  1945. }
  1946. static inline bool perform_include_all_delimiters(const type& split_opt)
  1947. {
  1948. return include_all_delimiters == (split_opt & include_all_delimiters);
  1949. }
  1950. } // namespace tokenize_options
  1951. template <typename Iterator, typename DelimiterPredicate>
  1952. class tokenizer
  1953. {
  1954. private:
  1955. template <typename Iterartor,
  1956. typename Predicate,
  1957. typename T = std::pair<Iterator,Iterator> >
  1958. class tokenizer_iterator : public std::iterator<std::forward_iterator_tag,T>
  1959. {
  1960. protected:
  1961. typedef Iterator iterator;
  1962. typedef const iterator const_iterator;
  1963. typedef typename std::pair<iterator,iterator> range_type;
  1964. public:
  1965. explicit inline tokenizer_iterator(const iterator begin,
  1966. const iterator end,
  1967. const Predicate& predicate,
  1968. const tokenize_options::type tokenize_option = tokenize_options::default_mode)
  1969. : predicate_(predicate),
  1970. end_(end),
  1971. range_(begin,begin),
  1972. current_token_(end,end),
  1973. compress_delimiters_(tokenize_options::perform_compress_delimiters(tokenize_option)),
  1974. include_1st_delimiter_(tokenize_options::perform_include_1st_delimiter(tokenize_option)),
  1975. include_all_delimiters_(tokenize_options::perform_include_all_delimiters(tokenize_option)),
  1976. include_delimiters_(include_1st_delimiter_ || include_all_delimiters_),
  1977. last_token_done_(false)
  1978. {
  1979. if (end != begin)
  1980. {
  1981. this->operator++();
  1982. }
  1983. }
  1984. inline tokenizer_iterator& operator++()
  1985. {
  1986. if (last_token_done_)
  1987. {
  1988. range_.first = range_.second;
  1989. return (*this);
  1990. }
  1991. else if (end_ != range_.second)
  1992. {
  1993. range_.first = range_.second;
  1994. }
  1995. while (end_ != range_.second)
  1996. {
  1997. if (predicate_(*(range_.second)))
  1998. {
  1999. if (include_delimiters_)
  2000. {
  2001. if (include_1st_delimiter_)
  2002. ++range_.second;
  2003. else if (include_all_delimiters_)
  2004. while ((end_ != range_.second) && predicate_(*(range_.second))) ++range_.second;
  2005. current_token_ = range_;
  2006. if ((!include_all_delimiters_) && compress_delimiters_)
  2007. while ((end_ != range_.second) && predicate_(*(range_.second))) ++range_.second;
  2008. }
  2009. else
  2010. {
  2011. current_token_ = range_;
  2012. if (compress_delimiters_)
  2013. while ((end_ != (++range_.second)) && predicate_(*(range_.second))) ;
  2014. else
  2015. ++range_.second;
  2016. }
  2017. return (*this);
  2018. }
  2019. else
  2020. ++range_.second;
  2021. }
  2022. if (range_.first != range_.second)
  2023. {
  2024. current_token_.second = range_.second;
  2025. if (!last_token_done_)
  2026. {
  2027. if (predicate_(*(range_.second - 1)))
  2028. current_token_.first = range_.second;
  2029. else
  2030. current_token_.first = range_.first;
  2031. last_token_done_ = true;
  2032. }
  2033. else
  2034. range_.first = range_.second;
  2035. }
  2036. return (*this);
  2037. }
  2038. inline tokenizer_iterator operator++(int)
  2039. {
  2040. tokenizer_iterator tmp = (*this);
  2041. this->operator++();
  2042. return tmp;
  2043. }
  2044. inline tokenizer_iterator& operator+=(const int inc)
  2045. {
  2046. if (inc > 0)
  2047. {
  2048. for (int i = 0; i < inc; ++i, ++(*this)) ;
  2049. }
  2050. return (*this);
  2051. }
  2052. inline T operator*() const
  2053. {
  2054. return current_token_;
  2055. }
  2056. inline std::string as_string() const
  2057. {
  2058. return std::string(current_token_.first,current_token_.second);
  2059. }
  2060. inline bool operator==(const tokenizer_iterator& itr) const
  2061. {
  2062. return (range_ == itr.range_) && (end_ == itr.end_);
  2063. }
  2064. inline bool operator!=(const tokenizer_iterator& itr) const
  2065. {
  2066. return (range_ != itr.range_) || (end_ != itr.end_);
  2067. }
  2068. inline tokenizer_iterator& operator=(const tokenizer_iterator& itr)
  2069. {
  2070. if (this != &itr)
  2071. {
  2072. range_ = itr.range_;
  2073. current_token_ = itr.current_token_;
  2074. end_ = itr.end_;
  2075. compress_delimiters_ = itr.compress_delimiters_;
  2076. include_1st_delimiter_ = itr.include_1st_delimiter_;
  2077. include_all_delimiters_ = itr.include_all_delimiters_;
  2078. include_delimiters_ = itr.include_delimiters_;
  2079. last_token_done_ = itr.last_token_done_;
  2080. }
  2081. return (*this);
  2082. }
  2083. inline std::string remaining() const
  2084. {
  2085. return std::string(current_token_.first,end_);
  2086. }
  2087. protected:
  2088. const Predicate& predicate_;
  2089. iterator end_;
  2090. range_type range_;
  2091. range_type current_token_;
  2092. bool compress_delimiters_;
  2093. bool include_1st_delimiter_;
  2094. bool include_all_delimiters_;
  2095. bool include_delimiters_;
  2096. bool last_token_done_;
  2097. };
  2098. public:
  2099. typedef typename std::iterator_traits<Iterator>::value_type value_type;
  2100. typedef DelimiterPredicate predicate;
  2101. typedef tokenizer_iterator<Iterator,DelimiterPredicate> iterator;
  2102. typedef const iterator const_iterator;
  2103. typedef iterator& iterator_ref;
  2104. typedef const_iterator& const_iterator_ref;
  2105. inline tokenizer(const Iterator begin,
  2106. const Iterator end,
  2107. const DelimiterPredicate& predicate,
  2108. const tokenize_options::type tokenize_options = tokenize_options::default_mode)
  2109. : tokenize_options_(tokenize_options),
  2110. predicate_(predicate),
  2111. begin_(begin),
  2112. end_(end),
  2113. begin_itr_(begin_,end_,predicate_,tokenize_options_),
  2114. end_itr_(end_,end_,predicate_,tokenize_options_)
  2115. {}
  2116. inline tokenizer(const std::string& s,
  2117. const DelimiterPredicate& predicate,
  2118. const tokenize_options::type tokenize_options = tokenize_options::default_mode)
  2119. : tokenize_options_(tokenize_options),
  2120. predicate_(predicate),
  2121. begin_(s.data()),
  2122. end_(s.data() + s.size()),
  2123. begin_itr_(begin_,end_,predicate_,tokenize_options_),
  2124. end_itr_(end_,end_,predicate_,tokenize_options_)
  2125. {}
  2126. inline tokenizer& operator=(const tokenizer& t)
  2127. {
  2128. if (this != &t)
  2129. {
  2130. begin_ = t.begin_;
  2131. end_ = t.end_;
  2132. end_itr_ = t.end_itr_;
  2133. begin_itr_ = t.begin_itr_;
  2134. tokenize_options_ = t.tokenize_options_;
  2135. }
  2136. return (*this);
  2137. }
  2138. inline void assign(const std::string& s) const
  2139. {
  2140. assign(s.data(),s.data() + s.size());
  2141. }
  2142. inline void assign(const std::string& s)
  2143. {
  2144. assign(s.data(),s.data() + s.size());
  2145. }
  2146. inline void assign(const Iterator begin, const Iterator end)
  2147. {
  2148. begin_ = begin;
  2149. end_ = end;
  2150. begin_itr_ = iterator(begin_,end_,predicate_,tokenize_options_);
  2151. end_itr_ = iterator(end_,end_,predicate_,tokenize_options_);
  2152. }
  2153. inline const_iterator_ref begin() const
  2154. {
  2155. return begin_itr_;
  2156. }
  2157. inline const_iterator_ref end() const
  2158. {
  2159. return end_itr_;
  2160. }
  2161. private:
  2162. tokenize_options::type tokenize_options_;
  2163. const DelimiterPredicate& predicate_;
  2164. Iterator begin_;
  2165. Iterator end_;
  2166. iterator begin_itr_;
  2167. iterator end_itr_;
  2168. };
  2169. namespace std_string
  2170. {
  2171. template <typename DelimiterPredicate = single_delimiter_predicate<std::string::value_type> >
  2172. struct tokenizer
  2173. {
  2174. typedef DelimiterPredicate predicate_type;
  2175. typedef const std::string::value_type* string_iterator_type;
  2176. typedef strtk::tokenizer<string_iterator_type,DelimiterPredicate> type;
  2177. typedef strtk::tokenizer<string_iterator_type,multiple_char_delimiter_predicate> md_type;
  2178. typedef std::pair<string_iterator_type,string_iterator_type> iterator_type;
  2179. };
  2180. typedef tokenizer<>::iterator_type iterator_type;
  2181. typedef tokenizer<>::iterator_type range_t;
  2182. typedef std::vector<iterator_type> token_vector_type;
  2183. typedef std::deque<iterator_type> token_deque_type;
  2184. typedef std::list<iterator_type> token_list_type;
  2185. } // namespace std_string
  2186. template <typename Sequence>
  2187. class range_to_type_back_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2188. void,
  2189. void,
  2190. void,
  2191. void>
  2192. {
  2193. public:
  2194. typedef typename Sequence::value_type value_type;
  2195. explicit inline range_to_type_back_inserter_iterator(Sequence& sequence)
  2196. : sequence_(sequence)
  2197. {}
  2198. range_to_type_back_inserter_iterator(const range_to_type_back_inserter_iterator& it)
  2199. : sequence_(it.sequence_)
  2200. {}
  2201. inline range_to_type_back_inserter_iterator& operator=(const range_to_type_back_inserter_iterator& it)
  2202. {
  2203. if (this != &it)
  2204. {
  2205. this->sequence_ = it.sequence_;
  2206. }
  2207. return (*this);
  2208. }
  2209. template <typename Iterator>
  2210. inline range_to_type_back_inserter_iterator& operator=(const std::pair<Iterator,Iterator>& r)
  2211. {
  2212. value_type t = value_type();
  2213. if (string_to_type_converter(r.first,r.second,t))
  2214. sequence_.push_back(t);
  2215. return (*this);
  2216. }
  2217. inline range_to_type_back_inserter_iterator& operator=(const std::string& s)
  2218. {
  2219. value_type t = value_type();
  2220. if (string_to_type_converter(s.data(),s.data() + s.size(),t))
  2221. sequence_.push_back(t);
  2222. return (*this);
  2223. }
  2224. template <typename Iterator>
  2225. inline void operator()(const std::pair<Iterator,Iterator>& r) const
  2226. {
  2227. value_type t;
  2228. if (string_to_type_converter(r.first,r.second,t))
  2229. sequence_.push_back(t);
  2230. }
  2231. template <typename Iterator>
  2232. inline void operator()(const Iterator begin, const Iterator end)
  2233. {
  2234. sequence_.push_back(string_to_type_converter<value_type>(begin,end));
  2235. }
  2236. inline range_to_type_back_inserter_iterator& operator*()
  2237. {
  2238. return (*this);
  2239. }
  2240. inline range_to_type_back_inserter_iterator& operator++()
  2241. {
  2242. return (*this);
  2243. }
  2244. inline range_to_type_back_inserter_iterator operator++(int)
  2245. {
  2246. return (*this);
  2247. }
  2248. private:
  2249. Sequence& sequence_;
  2250. };
  2251. template <typename Sequence>
  2252. inline range_to_type_back_inserter_iterator<Sequence> range_to_type_back_inserter(Sequence& sequence)
  2253. {
  2254. return (range_to_type_back_inserter_iterator<Sequence>(sequence));
  2255. }
  2256. template <typename Set>
  2257. class range_to_type_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2258. void,
  2259. void,
  2260. void,
  2261. void>
  2262. {
  2263. public:
  2264. typedef typename Set::value_type value_type;
  2265. explicit inline range_to_type_inserter_iterator(Set& set)
  2266. : set_(set)
  2267. {}
  2268. range_to_type_inserter_iterator(const range_to_type_inserter_iterator& it)
  2269. : set_(it.set_)
  2270. {}
  2271. inline range_to_type_inserter_iterator& operator=(const range_to_type_inserter_iterator& it)
  2272. {
  2273. if (this != &it)
  2274. {
  2275. this->set_ = it.set_;
  2276. }
  2277. return (*this);
  2278. }
  2279. template <typename Iterator>
  2280. inline range_to_type_inserter_iterator& operator=(const std::pair<Iterator,Iterator>& r)
  2281. {
  2282. value_type t;
  2283. if (string_to_type_converter(r.first,r.second,t))
  2284. set_.insert(t);
  2285. return (*this);
  2286. }
  2287. template <typename Iterator>
  2288. inline void operator()(const std::pair<Iterator,Iterator>& r)
  2289. {
  2290. value_type t;
  2291. if (string_to_type_converter(r.first,r.second,t))
  2292. set_.insert(t);
  2293. }
  2294. inline range_to_type_inserter_iterator& operator*()
  2295. {
  2296. return (*this);
  2297. }
  2298. inline range_to_type_inserter_iterator& operator++()
  2299. {
  2300. return (*this);
  2301. }
  2302. inline range_to_type_inserter_iterator operator++(int)
  2303. {
  2304. return (*this);
  2305. }
  2306. private:
  2307. Set& set_;
  2308. };
  2309. template <typename Set>
  2310. inline range_to_type_inserter_iterator<Set> range_to_type_inserter(Set& set)
  2311. {
  2312. return (range_to_type_inserter_iterator<Set>(set));
  2313. }
  2314. template <typename Container>
  2315. class range_to_type_push_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2316. void,
  2317. void,
  2318. void,
  2319. void>
  2320. {
  2321. public:
  2322. typedef typename Container::value_type value_type;
  2323. explicit inline range_to_type_push_inserter_iterator(Container& container)
  2324. : container_(container)
  2325. {}
  2326. range_to_type_push_inserter_iterator(const range_to_type_push_inserter_iterator& it)
  2327. : container_(it.container_)
  2328. {}
  2329. inline range_to_type_push_inserter_iterator& operator=(const range_to_type_push_inserter_iterator& it)
  2330. {
  2331. if (this != &it)
  2332. {
  2333. this->container_ = it.container_;
  2334. }
  2335. return (*this);
  2336. }
  2337. template <typename Iterator>
  2338. inline range_to_type_push_inserter_iterator& operator=(const std::pair<Iterator,Iterator>& r)
  2339. {
  2340. value_type t;
  2341. if (string_to_type_converter(r.first,r.second,t))
  2342. container_.push(t);
  2343. return (*this);
  2344. }
  2345. template <typename Iterator>
  2346. inline void operator()(const std::pair<Iterator,Iterator>& r)
  2347. {
  2348. value_type t;
  2349. if (string_to_type_converter(r.first,r.second,t))
  2350. container_.push(t);
  2351. }
  2352. inline range_to_type_push_inserter_iterator& operator*()
  2353. {
  2354. return (*this);
  2355. }
  2356. inline range_to_type_push_inserter_iterator& operator++()
  2357. {
  2358. return (*this);
  2359. }
  2360. inline range_to_type_push_inserter_iterator operator++(int)
  2361. {
  2362. return (*this);
  2363. }
  2364. private:
  2365. Container& container_;
  2366. };
  2367. template <typename Container>
  2368. inline range_to_type_push_inserter_iterator<Container> range_to_type_push_inserter(Container& container)
  2369. {
  2370. return (range_to_type_push_inserter_iterator<Container>(container));
  2371. }
  2372. template <typename Sequence>
  2373. class back_inserter_with_valuetype_iterator : public std::iterator<std::output_iterator_tag,
  2374. typename Sequence::value_type,
  2375. void,
  2376. void,
  2377. void>
  2378. {
  2379. public:
  2380. explicit inline back_inserter_with_valuetype_iterator(Sequence& sequence)
  2381. : sequence_(sequence)
  2382. {}
  2383. back_inserter_with_valuetype_iterator(const back_inserter_with_valuetype_iterator& it)
  2384. : sequence_(it.sequence_)
  2385. {}
  2386. inline back_inserter_with_valuetype_iterator& operator=(const back_inserter_with_valuetype_iterator& it)
  2387. {
  2388. if (this != &it)
  2389. {
  2390. this->sequence_ = it.sequence_;
  2391. }
  2392. return (*this);
  2393. }
  2394. inline back_inserter_with_valuetype_iterator& operator=(const typename Sequence::value_type& v)
  2395. {
  2396. sequence_.push_back(v);
  2397. return (*this);
  2398. }
  2399. inline void operator()(const typename Sequence::value_type& v)
  2400. {
  2401. sequence_.push_back(v);
  2402. }
  2403. inline back_inserter_with_valuetype_iterator& operator*()
  2404. {
  2405. return (*this);
  2406. }
  2407. inline back_inserter_with_valuetype_iterator& operator++()
  2408. {
  2409. return (*this);
  2410. }
  2411. inline back_inserter_with_valuetype_iterator operator++(int)
  2412. {
  2413. return (*this);
  2414. }
  2415. private:
  2416. Sequence& sequence_;
  2417. };
  2418. template <typename Sequence>
  2419. inline back_inserter_with_valuetype_iterator<Sequence> back_inserter_with_valuetype(Sequence& sequence_)
  2420. {
  2421. return (back_inserter_with_valuetype_iterator<Sequence>(sequence_));
  2422. }
  2423. template <typename Set>
  2424. class inserter_with_valuetype_iterator : public std::iterator<std::output_iterator_tag,
  2425. typename Set::value_type,
  2426. void,
  2427. void,
  2428. void>
  2429. {
  2430. public:
  2431. explicit inline inserter_with_valuetype_iterator(Set& set)
  2432. : set_(set)
  2433. {}
  2434. inserter_with_valuetype_iterator(const inserter_with_valuetype_iterator& itr)
  2435. : set_(itr.set_)
  2436. {}
  2437. inline inserter_with_valuetype_iterator& operator=(const inserter_with_valuetype_iterator& itr)
  2438. {
  2439. if (this != &itr)
  2440. {
  2441. this->set_ = itr.set_;
  2442. }
  2443. return (*this);
  2444. }
  2445. inline inserter_with_valuetype_iterator& operator=(const typename Set::value_type& v)
  2446. {
  2447. set_.insert(v);
  2448. return (*this);
  2449. }
  2450. inline void operator()(const typename Set::value_type& v)
  2451. {
  2452. set_.insert(v);
  2453. }
  2454. inline inserter_with_valuetype_iterator& operator*()
  2455. {
  2456. return (*this);
  2457. }
  2458. inline inserter_with_valuetype_iterator& operator++()
  2459. {
  2460. return (*this);
  2461. }
  2462. inline inserter_with_valuetype_iterator operator++(int)
  2463. {
  2464. return (*this);
  2465. }
  2466. private:
  2467. Set& set_;
  2468. };
  2469. template <typename Set>
  2470. inline inserter_with_valuetype_iterator<Set> inserter_with_valuetype(Set& set_)
  2471. {
  2472. return (inserter_with_valuetype_iterator<Set>(set_));
  2473. }
  2474. template <typename Container>
  2475. class push_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2476. void,
  2477. void,
  2478. void,
  2479. void>
  2480. {
  2481. public:
  2482. explicit inline push_inserter_iterator(Container& container)
  2483. : container_(container)
  2484. {}
  2485. inline push_inserter_iterator& operator=(const push_inserter_iterator& itr)
  2486. {
  2487. if (this != &itr)
  2488. {
  2489. this->container_ = itr.container_;
  2490. }
  2491. return (*this);
  2492. }
  2493. inline push_inserter_iterator<Container>& operator=(typename Container::const_reference v)
  2494. {
  2495. container_.push(v);
  2496. return (*this);
  2497. }
  2498. inline push_inserter_iterator<Container>& operator*()
  2499. {
  2500. return (*this);
  2501. }
  2502. inline push_inserter_iterator<Container>& operator++()
  2503. {
  2504. return (*this);
  2505. }
  2506. inline push_inserter_iterator<Container> operator++(int)
  2507. {
  2508. return (*this);
  2509. }
  2510. private:
  2511. Container& container_;
  2512. };
  2513. template <typename Container>
  2514. inline push_inserter_iterator<Container> push_inserter(Container& c)
  2515. {
  2516. return push_inserter_iterator<Container>(c);
  2517. }
  2518. template <typename T>
  2519. class range_to_ptr_type_iterator : public std::iterator<std::output_iterator_tag,
  2520. void,
  2521. void,
  2522. void,
  2523. void>
  2524. {
  2525. public:
  2526. typedef T value_type;
  2527. explicit inline range_to_ptr_type_iterator(T* pointer, std::size_t& insert_count)
  2528. : pointer_(pointer),
  2529. insert_count_(insert_count)
  2530. {}
  2531. range_to_ptr_type_iterator(const range_to_ptr_type_iterator& it)
  2532. : pointer_(it.pointer_)
  2533. {}
  2534. inline range_to_ptr_type_iterator& operator=(const range_to_ptr_type_iterator& it)
  2535. {
  2536. if (this != &it)
  2537. {
  2538. this->pointer_ = it.pointer_;
  2539. }
  2540. return (*this);
  2541. }
  2542. template <typename Iterator>
  2543. inline range_to_ptr_type_iterator& operator=(const std::pair<Iterator,Iterator>& r)
  2544. {
  2545. value_type t = value_type();
  2546. if (string_to_type_converter(r.first,r.second,t))
  2547. {
  2548. (*pointer_) = t;
  2549. ++pointer_;
  2550. ++insert_count_;
  2551. }
  2552. return (*this);
  2553. }
  2554. inline range_to_ptr_type_iterator& operator=(const std::string& s)
  2555. {
  2556. value_type t = value_type();
  2557. if (string_to_type_converter(s.data(),s.data() + s.size(),t))
  2558. {
  2559. (*pointer_) = t;
  2560. ++pointer_;
  2561. ++insert_count_;
  2562. }
  2563. return (*this);
  2564. }
  2565. template <typename Iterator>
  2566. inline void operator()(const std::pair<Iterator,Iterator>& r) const
  2567. {
  2568. value_type t;
  2569. if (string_to_type_converter(r.first,r.second,t))
  2570. {
  2571. (*pointer_) = t;
  2572. ++pointer_;
  2573. ++insert_count_;
  2574. }
  2575. }
  2576. template <typename Iterator>
  2577. inline void operator()(const Iterator begin, const Iterator end)
  2578. {
  2579. (*pointer_) = string_to_type_converter<T>(begin,end);
  2580. ++pointer_;
  2581. ++insert_count_;
  2582. }
  2583. inline range_to_ptr_type_iterator& operator*()
  2584. {
  2585. return (*this);
  2586. }
  2587. inline range_to_ptr_type_iterator& operator++()
  2588. {
  2589. return (*this);
  2590. }
  2591. inline range_to_ptr_type_iterator operator++(int)
  2592. {
  2593. return (*this);
  2594. }
  2595. private:
  2596. T* pointer_;
  2597. std::size_t& insert_count_;
  2598. };
  2599. template <typename T>
  2600. inline range_to_ptr_type_iterator<T> range_to_ptr_type(T* pointer, std::size_t& insert_count)
  2601. {
  2602. return (range_to_ptr_type_iterator<T>(pointer,insert_count));
  2603. }
  2604. template <typename T>
  2605. inline range_to_ptr_type_iterator<T> range_to_ptr_type(T* pointer)
  2606. {
  2607. static std::size_t insert_count = 0;
  2608. return (range_to_ptr_type_iterator<T>(pointer,insert_count));
  2609. }
  2610. template <typename T>
  2611. class counting_back_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2612. T,
  2613. void,
  2614. void,
  2615. void>
  2616. {
  2617. public:
  2618. explicit inline counting_back_inserter_iterator(std::size_t& counter)
  2619. : counter_(counter)
  2620. {}
  2621. counting_back_inserter_iterator(const counting_back_inserter_iterator& itr)
  2622. : counter_(itr.counter_)
  2623. {}
  2624. inline counting_back_inserter_iterator& operator=(const counting_back_inserter_iterator& itr)
  2625. {
  2626. if (this != &itr)
  2627. {
  2628. this->counter_ = itr.counter_;
  2629. }
  2630. return (*this);
  2631. }
  2632. inline counting_back_inserter_iterator& operator=(const T&)
  2633. {
  2634. ++counter_;
  2635. return (*this);
  2636. }
  2637. inline void operator()(const T&)
  2638. {
  2639. ++counter_;
  2640. }
  2641. inline counting_back_inserter_iterator& operator*()
  2642. {
  2643. return (*this);
  2644. }
  2645. inline counting_back_inserter_iterator& operator++()
  2646. {
  2647. return (*this);
  2648. }
  2649. inline counting_back_inserter_iterator operator++(int)
  2650. {
  2651. return (*this);
  2652. }
  2653. private:
  2654. std::size_t& counter_;
  2655. };
  2656. template <typename T>
  2657. inline counting_back_inserter_iterator<T> counting_back_inserter(std::size_t& counter_)
  2658. {
  2659. return (counting_back_inserter_iterator<T>(counter_));
  2660. }
  2661. template <typename Function>
  2662. class functional_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2663. void,
  2664. void,
  2665. void,
  2666. void>
  2667. {
  2668. public:
  2669. explicit inline functional_inserter_iterator(Function function)
  2670. : function_(function)
  2671. {}
  2672. functional_inserter_iterator(const functional_inserter_iterator& it)
  2673. : function_(it.function_)
  2674. {}
  2675. inline functional_inserter_iterator& operator=(const functional_inserter_iterator& it)
  2676. {
  2677. if (this != &it)
  2678. {
  2679. this->function_ = it.function_;
  2680. }
  2681. return (*this);
  2682. }
  2683. template <typename T>
  2684. inline functional_inserter_iterator& operator=(const T& t)
  2685. {
  2686. function_(t);
  2687. return (*this);
  2688. }
  2689. template <typename T>
  2690. inline void operator()(const T& t)
  2691. {
  2692. function_(t);
  2693. }
  2694. inline functional_inserter_iterator& operator*()
  2695. {
  2696. return (*this);
  2697. }
  2698. inline functional_inserter_iterator& operator++()
  2699. {
  2700. return (*this);
  2701. }
  2702. inline functional_inserter_iterator operator++(int)
  2703. {
  2704. return (*this);
  2705. }
  2706. private:
  2707. Function function_;
  2708. };
  2709. template <typename Function>
  2710. inline functional_inserter_iterator<Function> functional_inserter(Function function)
  2711. {
  2712. return (functional_inserter_iterator<Function>(function));
  2713. }
  2714. namespace split_options
  2715. {
  2716. typedef std::size_t type;
  2717. enum
  2718. {
  2719. default_mode = 0,
  2720. compress_delimiters = 1,
  2721. include_1st_delimiter = 2,
  2722. include_all_delimiters = 4
  2723. };
  2724. static inline bool perform_compress_delimiters(const type& split_opt)
  2725. {
  2726. return compress_delimiters == (split_opt & compress_delimiters);
  2727. }
  2728. static inline bool perform_include_1st_delimiter(const type& split_opt)
  2729. {
  2730. return include_1st_delimiter == (split_opt & include_1st_delimiter);
  2731. }
  2732. static inline bool perform_include_all_delimiters(const type& split_opt)
  2733. {
  2734. return include_all_delimiters == (split_opt & include_all_delimiters);
  2735. }
  2736. } // namespace split_options
  2737. template <typename DelimiterPredicate,
  2738. typename Iterator,
  2739. typename OutputIterator>
  2740. inline std::size_t split(const DelimiterPredicate& delimiter,
  2741. const Iterator begin,
  2742. const Iterator end,
  2743. OutputIterator out,
  2744. const split_options::type split_option = split_options::default_mode)
  2745. {
  2746. if (begin == end) return 0;
  2747. std::size_t token_count = 0;
  2748. std::pair<Iterator,Iterator> range(begin,begin);
  2749. const bool compress_delimiters = split_options::perform_compress_delimiters(split_option);
  2750. const bool include_1st_delimiter = split_options::perform_include_1st_delimiter(split_option);
  2751. const bool include_all_delimiters = (!include_1st_delimiter) && split_options::perform_include_all_delimiters(split_option);
  2752. const bool include_delimiters = include_1st_delimiter || include_all_delimiters;
  2753. while (end != range.second)
  2754. {
  2755. if (delimiter(*range.second))
  2756. {
  2757. if (include_delimiters)
  2758. {
  2759. if (include_1st_delimiter)
  2760. ++range.second;
  2761. else if (include_all_delimiters)
  2762. while ((end != range.second) && delimiter(*range.second)) ++range.second;
  2763. (*out) = range;
  2764. ++out;
  2765. if ((!include_all_delimiters) && compress_delimiters)
  2766. while ((end != range.second) && delimiter(*range.second)) ++range.second;
  2767. }
  2768. else
  2769. {
  2770. (*out) = range;
  2771. ++out;
  2772. if (compress_delimiters)
  2773. while ((end != (++range.second)) && delimiter(*range.second)) ;
  2774. else
  2775. ++range.second;
  2776. }
  2777. ++token_count;
  2778. range.first = range.second;
  2779. }
  2780. else
  2781. ++range.second;
  2782. }
  2783. if ((range.first != range.second) || delimiter(*(range.second - 1)))
  2784. {
  2785. (*out) = range;
  2786. ++out;
  2787. ++token_count;
  2788. }
  2789. return token_count;
  2790. }
  2791. template <typename DelimiterPredicate,
  2792. typename Iterator,
  2793. typename OutputIterator>
  2794. inline std::size_t split(const DelimiterPredicate& delimiter,
  2795. const std::pair<Iterator,Iterator>& range,
  2796. OutputIterator out,
  2797. const split_options::type split_option = split_options::default_mode)
  2798. {
  2799. return split(delimiter,
  2800. range.first,range.second,
  2801. out,
  2802. split_option);
  2803. }
  2804. template <typename DelimiterPredicate,
  2805. typename Iterator,
  2806. typename OutputIterator>
  2807. inline std::size_t split(const char* delimiters,
  2808. const std::pair<Iterator,Iterator>& range,
  2809. OutputIterator out,
  2810. const split_options::type split_option = split_options::default_mode)
  2811. {
  2812. if (1 == details::strnlength(delimiters,256))
  2813. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2814. range.first,range.second,
  2815. out,
  2816. split_option);
  2817. else
  2818. return split(multiple_char_delimiter_predicate(delimiters),
  2819. range.first,range.second,
  2820. out,
  2821. split_option);
  2822. }
  2823. template <typename DelimiterPredicate,
  2824. typename Iterator,
  2825. typename OutputIterator>
  2826. inline std::size_t split(const std::string& delimiters,
  2827. const std::pair<Iterator,Iterator>& range,
  2828. OutputIterator out,
  2829. const split_options::type split_option = split_options::default_mode)
  2830. {
  2831. if (1 == delimiters.size())
  2832. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2833. range.first,range.second,
  2834. out,
  2835. split_option);
  2836. else
  2837. return split(multiple_char_delimiter_predicate(delimiters),
  2838. range.first,range.second,
  2839. out,
  2840. split_option);
  2841. }
  2842. template <typename OutputIterator>
  2843. inline std::size_t split(const char* delimiters,
  2844. const std::string& str,
  2845. OutputIterator out,
  2846. const split_options::type& split_option = split_options::default_mode)
  2847. {
  2848. if (1 == details::strnlength(delimiters,256))
  2849. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2850. str.data(), str.data() + str.size(),
  2851. out,
  2852. split_option);
  2853. else
  2854. return split(multiple_char_delimiter_predicate(delimiters),
  2855. str.data(), str.data() + str.size(),
  2856. out,
  2857. split_option);
  2858. }
  2859. template <typename OutputIterator>
  2860. inline std::size_t split(const std::string& delimiters,
  2861. const std::string& str,
  2862. OutputIterator out,
  2863. const split_options::type& split_option = split_options::default_mode)
  2864. {
  2865. if (1 == delimiters.size())
  2866. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2867. str.data(), str.data() + str.size(),
  2868. out,
  2869. split_option);
  2870. else
  2871. return split(multiple_char_delimiter_predicate(delimiters),
  2872. str.data(), str.data() + str.size(),
  2873. out,
  2874. split_option);
  2875. }
  2876. template <typename OutputIterator>
  2877. inline std::size_t split(const std::string::value_type delimiter,
  2878. const std::string& str,
  2879. OutputIterator out,
  2880. const split_options::type& split_option = split_options::default_mode)
  2881. {
  2882. return split(single_delimiter_predicate<std::string::value_type>(delimiter),
  2883. str.data(), str.data() + str.size(),
  2884. out,
  2885. split_option);
  2886. }
  2887. template <typename Allocator,
  2888. template <typename,typename> class Sequence>
  2889. inline std::size_t split(const char* delimiters,
  2890. const std::string& str,
  2891. Sequence<std::pair<const char*, const char*>,Allocator>& sequence,
  2892. const split_options::type& split_option = split_options::default_mode)
  2893. {
  2894. if (1 == details::strnlength(delimiters,256))
  2895. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2896. str.data(), str.data() + str.size(),
  2897. std::back_inserter(sequence),
  2898. split_option);
  2899. else
  2900. return split(multiple_char_delimiter_predicate(delimiters),
  2901. str.data(), str.data() + str.size(),
  2902. std::back_inserter(sequence),
  2903. split_option);
  2904. }
  2905. template <typename Allocator,
  2906. template <typename,typename> class Sequence>
  2907. inline std::size_t split(const std::string& delimiters,
  2908. const std::string& str,
  2909. Sequence<std::pair<const char*, const char*>,Allocator>& sequence,
  2910. const split_options::type& split_option = split_options::default_mode)
  2911. {
  2912. if (1 == delimiters.size())
  2913. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2914. str.data(), str.data() + str.size(),
  2915. std::back_inserter(sequence),
  2916. split_option);
  2917. else
  2918. return split(multiple_char_delimiter_predicate(delimiters),
  2919. str.data(), str.data() + str.size(),
  2920. std::back_inserter(sequence),
  2921. split_option);
  2922. }
  2923. template <typename DelimiterPredicate,
  2924. typename OutputIterator>
  2925. inline std::size_t split(const DelimiterPredicate& delimiter,
  2926. const std::string& str,
  2927. OutputIterator out,
  2928. const split_options::type& split_option = split_options::default_mode)
  2929. {
  2930. return split(delimiter,
  2931. str.data(), str.data() + str.size(),
  2932. out,
  2933. split_option);
  2934. }
  2935. template <typename DelimiterPredicate,
  2936. typename Iterator,
  2937. typename OutputIterator>
  2938. inline std::size_t split_n(const DelimiterPredicate& delimiter,
  2939. const Iterator begin,
  2940. const Iterator end,
  2941. const std::size_t& token_count,
  2942. OutputIterator out,
  2943. const split_options::type& split_option = split_options::default_mode)
  2944. {
  2945. if (0 == token_count) return 0;
  2946. if (begin == end) return 0;
  2947. std::size_t match_count = 0;
  2948. std::pair<Iterator,Iterator> range(begin,begin);
  2949. const bool compress_delimiters = split_options::perform_compress_delimiters(split_option);
  2950. const bool include_1st_delimiter = split_options::perform_include_1st_delimiter(split_option);
  2951. const bool include_all_delimiters = (!include_1st_delimiter) && split_options::perform_include_all_delimiters(split_option);
  2952. const bool include_delimiters = include_1st_delimiter || include_all_delimiters;
  2953. while (end != range.second)
  2954. {
  2955. if (delimiter(*range.second))
  2956. {
  2957. if (include_delimiters)
  2958. {
  2959. ++range.second;
  2960. (*out) = range;
  2961. ++out;
  2962. if (++match_count >= token_count)
  2963. return match_count;
  2964. if (compress_delimiters)
  2965. while ((end != range.second) && delimiter(*range.second)) ++range.second;
  2966. }
  2967. else
  2968. {
  2969. (*out) = range;
  2970. ++out;
  2971. if (++match_count >= token_count)
  2972. return match_count;
  2973. if (compress_delimiters)
  2974. while ((end != (++range.second)) && delimiter(*range.second)) ;
  2975. else
  2976. ++range.second;
  2977. }
  2978. range.first = range.second;
  2979. }
  2980. else
  2981. ++range.second;
  2982. }
  2983. if ((range.first != range.second) || delimiter(*(range.second - 1)))
  2984. {
  2985. (*out) = range;
  2986. ++out;
  2987. ++match_count;
  2988. }
  2989. return match_count;
  2990. }
  2991. template <typename OutputIterator>
  2992. inline std::size_t split_n(const char* delimiters,
  2993. const std::string& str,
  2994. const std::size_t& token_count,
  2995. OutputIterator out,
  2996. const split_options::type& split_option = split_options::default_mode)
  2997. {
  2998. return split_n(multiple_char_delimiter_predicate(delimiters),
  2999. str.data(), str.data() + str.size(),
  3000. token_count,
  3001. out,
  3002. split_option);
  3003. }
  3004. template <typename OutputIterator>
  3005. inline std::size_t split_n(const std::string& delimiters,
  3006. const std::string& str,
  3007. const std::size_t& token_count,
  3008. OutputIterator out,
  3009. const split_options::type& split_option = split_options::default_mode)
  3010. {
  3011. if (1 == delimiters.size())
  3012. return split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  3013. str.data(), str.data() + str.size(),
  3014. token_count,
  3015. out,
  3016. split_option);
  3017. else
  3018. return split_n(multiple_char_delimiter_predicate(delimiters),
  3019. str.data(), str.data() + str.size(),
  3020. token_count,
  3021. out,
  3022. split_option);
  3023. }
  3024. template <typename InputIterator, typename OutputIterator>
  3025. inline std::size_t split_n(const std::string& delimiters,
  3026. const InputIterator begin,
  3027. const InputIterator end,
  3028. const std::size_t& token_count,
  3029. OutputIterator out,
  3030. const split_options::type& split_option = split_options::default_mode)
  3031. {
  3032. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  3033. if (1 == delimiters.size())
  3034. return split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  3035. begin,end,
  3036. token_count,
  3037. out,
  3038. split_option);
  3039. else
  3040. return split_n(multiple_char_delimiter_predicate(delimiters),
  3041. begin,end,
  3042. token_count,
  3043. out,
  3044. split_option);
  3045. }
  3046. template <typename OutputIterator>
  3047. inline std::size_t split_n(const std::string::value_type delimiter,
  3048. const std::string& str,
  3049. const std::size_t& token_count,
  3050. OutputIterator out,
  3051. const split_options::type& split_option = split_options::default_mode)
  3052. {
  3053. return split_n(single_delimiter_predicate<std::string::value_type>(delimiter),
  3054. str.data(),str.data() + str.size(),
  3055. token_count,
  3056. out,
  3057. split_option);
  3058. }
  3059. template <typename DelimiterPredicate,
  3060. typename OutputIterator>
  3061. inline std::size_t split_n(const DelimiterPredicate& delimiter,
  3062. const std::string& str,
  3063. const std::size_t& token_count,
  3064. OutputIterator out,
  3065. const split_options::type& split_option = split_options::default_mode)
  3066. {
  3067. return split_n(delimiter,
  3068. str.data(),str.data() + str.size(),
  3069. token_count,
  3070. out,
  3071. split_option);
  3072. }
  3073. #ifdef strtk_enable_regex
  3074. 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;%$#=~\\\\]+)*/?)");
  3075. static const std::string email_expression ("([\\w\\-\\.]+)@((\\[([0-9]{1,3}\\.){3}[0-9]{1,3}\\])|(([\\w\\-]+\\.)+)([a-zA-Z]{2,4}))");
  3076. 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]+))");
  3077. static const std::string ieee754_expression ("([-+]?((\\.[0-9]+|[0-9]+\\.[0-9]+)([eE][-+][0-9]+)?|[0-9]+))");
  3078. namespace regex_match_mode
  3079. {
  3080. enum type
  3081. {
  3082. match_all = 0,
  3083. match_1 = 1,
  3084. match_2 = 2,
  3085. match_3 = 3,
  3086. match_4 = 4,
  3087. match_5 = 5,
  3088. match_6 = 6,
  3089. match_7 = 7,
  3090. match_8 = 8,
  3091. match_9 = 9
  3092. };
  3093. }
  3094. template <typename InputIterator, typename OutputIterator>
  3095. inline std::size_t split_regex(const boost::regex& delimiter_expression,
  3096. const InputIterator begin,
  3097. const InputIterator end,
  3098. OutputIterator out,
  3099. const regex_match_mode::type mode = regex_match_mode::match_all)
  3100. {
  3101. boost::regex_iterator<InputIterator> itr(begin,end,delimiter_expression);
  3102. boost::regex_iterator<InputIterator> itr_end;
  3103. std::pair<InputIterator,InputIterator> range(begin,begin);
  3104. std::size_t match_count = 0;
  3105. while (itr_end != itr)
  3106. {
  3107. range.first = (*itr)[mode].first;
  3108. range.second = (*itr)[mode].second;
  3109. (*out) = range;
  3110. ++out;
  3111. ++itr;
  3112. ++match_count;
  3113. }
  3114. return match_count;
  3115. }
  3116. template <typename InputIterator, typename OutputIterator>
  3117. inline std::size_t split_regex(const std::string& delimiter_expression,
  3118. const InputIterator begin,
  3119. const InputIterator end,
  3120. OutputIterator out,
  3121. const regex_match_mode::type mode = regex_match_mode::match_all)
  3122. {
  3123. const boost::regex regex_expression(delimiter_expression);
  3124. return split_regex(regex_expression,
  3125. begin,end,
  3126. out,
  3127. mode);
  3128. }
  3129. template <typename OutputIterator>
  3130. inline std::size_t split_regex(const std::string& delimiter_expression,
  3131. const std::string& text,
  3132. OutputIterator out,
  3133. const regex_match_mode::type mode = regex_match_mode::match_all)
  3134. {
  3135. return split_regex(delimiter_expression,
  3136. text.begin(),text.end(),
  3137. out,
  3138. mode);
  3139. }
  3140. template <typename OutputIterator>
  3141. inline std::size_t split_regex(const boost::regex& delimiter_expression,
  3142. const std::string& text,
  3143. OutputIterator out,
  3144. const regex_match_mode::type mode = regex_match_mode::match_all)
  3145. {
  3146. return split_regex(delimiter_expression,
  3147. text.begin(),text.end(),
  3148. out,
  3149. mode);
  3150. }
  3151. template <typename InputIterator, typename OutputIterator>
  3152. inline std::size_t split_regex_n(const boost::regex& delimiter_expression,
  3153. const InputIterator begin,
  3154. const InputIterator end,
  3155. const std::size_t& token_count,
  3156. OutputIterator out,
  3157. const regex_match_mode::type mode = regex_match_mode::match_all)
  3158. {
  3159. boost::sregex_iterator itr(begin,end,delimiter_expression);
  3160. const boost::sregex_iterator itr_end;
  3161. std::pair<InputIterator,InputIterator> range(begin,begin);
  3162. std::size_t match_count = 0;
  3163. while (itr_end != itr)
  3164. {
  3165. range.first = (*itr)[mode].first;
  3166. range.second = (*itr)[mode].second;
  3167. (*out) = range;
  3168. ++out;
  3169. ++itr;
  3170. if (++match_count >= token_count)
  3171. return match_count;
  3172. }
  3173. return match_count;
  3174. }
  3175. template <typename InputIterator, typename OutputIterator>
  3176. inline std::size_t split_regex_n(const std::string& delimiter_expression,
  3177. const InputIterator begin,
  3178. const InputIterator end,
  3179. const std::size_t& token_count,
  3180. OutputIterator out,
  3181. const regex_match_mode::type mode = regex_match_mode::match_all)
  3182. {
  3183. const boost::regex regex_expression(delimiter_expression);
  3184. return split_regex_n(regex_expression,
  3185. begin,end,
  3186. token_count,
  3187. out,
  3188. mode);
  3189. }
  3190. template <typename OutputIterator>
  3191. inline std::size_t split_regex_n(const std::string& delimiter_expression,
  3192. const std::string& text,
  3193. const std::size_t& token_count,
  3194. OutputIterator out,
  3195. const regex_match_mode::type mode = regex_match_mode::match_all)
  3196. {
  3197. return split_regex_n(delimiter_expression,
  3198. text.begin(),text.end(),
  3199. token_count,
  3200. out,
  3201. mode);
  3202. }
  3203. template <typename OutputIterator>
  3204. inline std::size_t split_regex_n(const boost::regex& delimiter_expression,
  3205. const std::string& text,
  3206. const std::size_t& token_count,
  3207. OutputIterator out,
  3208. const regex_match_mode::type mode = regex_match_mode::match_all)
  3209. {
  3210. return split_regex_n(delimiter_expression,
  3211. text.begin(),text.end(),
  3212. token_count,
  3213. out,
  3214. mode);
  3215. }
  3216. #endif // strtk_enable_regex
  3217. template <const std::size_t offset_list_size>
  3218. class offset_predicate
  3219. {
  3220. public:
  3221. offset_predicate(const int offset_list[], const bool rotate = false)
  3222. : rotate_(rotate),
  3223. current_index_(0)
  3224. {
  3225. std::copy(offset_list, offset_list + offset_list_size, offset_list_);
  3226. offset_list_[offset_list_size] = 0;
  3227. }
  3228. inline bool operator!() const
  3229. {
  3230. return (0 == offset_list_size);
  3231. }
  3232. inline void reset() const
  3233. {
  3234. current_index_ = 0;
  3235. }
  3236. inline std::size_t size() const
  3237. {
  3238. return offset_list_size;
  3239. }
  3240. inline int next() const
  3241. {
  3242. int result = offset_list_[current_index_++];
  3243. if (rotate_ && (current_index_ >= offset_list_size))
  3244. {
  3245. current_index_ = 0;
  3246. }
  3247. return result;
  3248. }
  3249. private:
  3250. bool rotate_;
  3251. mutable std::size_t current_index_;
  3252. int offset_list_[offset_list_size + 1];
  3253. };
  3254. inline offset_predicate<12> offsets(const int& v1, const int& v2, const int& v3,
  3255. const int& v4, const int& v5, const int& v6,
  3256. const int& v7, const int& v8, const int& v9,
  3257. const int& v10, const int& v11, const int& v12,
  3258. const bool& rotate = false)
  3259. {
  3260. const int offset_list[12] = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 };
  3261. return offset_predicate<12>(offset_list,rotate);
  3262. }
  3263. inline offset_predicate<11> offsets(const int& v1, const int& v2, const int& v3,
  3264. const int& v4, const int& v5, const int& v6,
  3265. const int& v7, const int& v8, const int& v9,
  3266. const int& v10, const int& v11,
  3267. const bool& rotate = false)
  3268. {
  3269. const int offset_list[11] = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 };
  3270. return offset_predicate<11>(offset_list,rotate);
  3271. }
  3272. inline offset_predicate<10> offsets(const int& v1, const int& v2, const int& v3,
  3273. const int& v4, const int& v5, const int& v6,
  3274. const int& v7, const int& v8, const int& v9,
  3275. const int& v10, const bool& rotate = false)
  3276. {
  3277. const int offset_list[10] = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 };
  3278. return offset_predicate<10>(offset_list,rotate);
  3279. }
  3280. inline offset_predicate<9> offsets(const int& v1, const int& v2, const int& v3,
  3281. const int& v4, const int& v5, const int& v6,
  3282. const int& v7, const int& v8, const int& v9,
  3283. const bool& rotate = false)
  3284. {
  3285. const int offset_list[9] = { v1, v2, v3, v4, v5, v6, v7, v8, v9 };
  3286. return offset_predicate<9>(offset_list,rotate);
  3287. }
  3288. inline offset_predicate<8> offsets(const int& v1, const int& v2, const int& v3,
  3289. const int& v4, const int& v5, const int& v6,
  3290. const int& v7, const int& v8, const bool& rotate = false)
  3291. {
  3292. const int offset_list[8] = { v1, v2, v3, v4, v5, v6, v7, v8 };
  3293. return offset_predicate<8>(offset_list,rotate);
  3294. }
  3295. inline offset_predicate<7> offsets(const int& v1, const int& v2, const int& v3,
  3296. const int& v4, const int& v5, const int& v6,
  3297. const int& v7, const bool& rotate = false)
  3298. {
  3299. const int offset_list[7] = { v1, v2, v3, v4, v5, v6, v7 };
  3300. return offset_predicate<7>(offset_list,rotate);
  3301. }
  3302. inline offset_predicate<6> offsets(const int& v1, const int& v2, const int& v3,
  3303. const int& v4, const int& v5, const int& v6,
  3304. const bool& rotate = false)
  3305. {
  3306. const int offset_list[6] = { v1, v2, v3, v4, v5, v6 };
  3307. return offset_predicate<6>(offset_list,rotate);
  3308. }
  3309. inline offset_predicate<5> offsets(const int& v1, const int& v2, const int& v3,
  3310. const int& v4, const int& v5, const bool& rotate = false)
  3311. {
  3312. const int offset_list[5] = { v1, v2, v3, v4, v5 };
  3313. return offset_predicate<5>(offset_list,rotate);
  3314. }
  3315. inline offset_predicate<4> offsets(const int& v1, const int& v2, const int& v3,
  3316. const int& v4, const bool& rotate = false)
  3317. {
  3318. const int offset_list[4] = { v1, v2, v3, v4 };
  3319. return offset_predicate<4>(offset_list,rotate);
  3320. }
  3321. inline offset_predicate<3> offsets(const int& v1, const int& v2, const int& v3,
  3322. const bool& rotate = false)
  3323. {
  3324. const int offset_list[3] = { v1, v2, v3 };
  3325. return offset_predicate<3>(offset_list,rotate);
  3326. }
  3327. inline offset_predicate<2> offsets(const int& v1, const int& v2, const bool& rotate = false)
  3328. {
  3329. const int offset_list[2] = { v1, v2 };
  3330. return offset_predicate<2>(offset_list,rotate);
  3331. }
  3332. inline offset_predicate<1> offsets(const int& v1,
  3333. const bool& rotate = false)
  3334. {
  3335. const int offset_list[1] = { v1 };
  3336. return offset_predicate<1>(offset_list,rotate);
  3337. }
  3338. template <typename OffsetPredicate,
  3339. typename InputIterator,
  3340. typename OutputIterator>
  3341. inline std::size_t offset_splitter(const InputIterator begin,
  3342. const InputIterator end,
  3343. const OffsetPredicate& offset,
  3344. OutputIterator out)
  3345. {
  3346. std::size_t length = 0;
  3347. if (0 == (length = std::distance(begin,end))) return 0;
  3348. std::pair<InputIterator,InputIterator> range(begin,begin);
  3349. std::size_t match_count = 0;
  3350. int offset_length = 0;
  3351. std::size_t increment_amount = 0;
  3352. while ((end != range.second) && (0 < (offset_length = offset.next())))
  3353. {
  3354. increment_amount = std::min<std::size_t>(length,offset_length);
  3355. range.first = range.second;
  3356. range.second += increment_amount;
  3357. length -= increment_amount;
  3358. (*out) = range;
  3359. ++out;
  3360. ++match_count;
  3361. }
  3362. return match_count;
  3363. }
  3364. template <typename OffsetPredicate,
  3365. typename OutputIterator>
  3366. inline std::size_t offset_splitter(const std::string& str,
  3367. const OffsetPredicate& offset,
  3368. OutputIterator out)
  3369. {
  3370. return offset_splitter(str.data(),str.data() + str.size(),offset,out);
  3371. }
  3372. template <typename InputIterator,
  3373. typename Predicate,
  3374. typename OutputPair>
  3375. inline bool split_pair(const InputIterator begin,
  3376. const InputIterator end,
  3377. const Predicate& delimiter,
  3378. OutputPair& v1,
  3379. OutputPair& v2)
  3380. {
  3381. if (0 == std::distance(begin,end)) return false;
  3382. InputIterator itr = begin;
  3383. while (end != itr)
  3384. {
  3385. if (delimiter(*itr))
  3386. {
  3387. v1 = std::make_pair(begin,itr);
  3388. ++itr;
  3389. if (0 != std::distance(itr,end))
  3390. {
  3391. v2 = std::make_pair(itr,end);
  3392. return true;
  3393. }
  3394. else
  3395. return false;
  3396. }
  3397. else
  3398. ++itr;
  3399. }
  3400. return false;
  3401. }
  3402. inline bool split_pair(const std::string::value_type delimiter,
  3403. const std::string& str,
  3404. std::pair<const char*,const char*>& v1,
  3405. std::pair<const char*,const char*>& v2)
  3406. {
  3407. return split_pair(str.data(),
  3408. str.data() + str.size(),
  3409. single_delimiter_predicate<std::string::value_type>(delimiter),
  3410. v1,
  3411. v2);
  3412. }
  3413. template <typename DelimiterPredicate>
  3414. inline bool split_pair(const DelimiterPredicate& delimiter,
  3415. const std::string& str,
  3416. std::pair<const char*,const char*>& v1,
  3417. std::pair<const char*,const char*>& v2)
  3418. {
  3419. return split_pair(str.data(),
  3420. str.data() + str.size(),
  3421. delimiter,
  3422. v1,
  3423. v2);
  3424. }
  3425. template <typename Function>
  3426. inline std::size_t for_each_token(const std::string& buffer,
  3427. const std::string& delimiters,
  3428. Function function)
  3429. {
  3430. return split(delimiters,
  3431. buffer,
  3432. strtk::functional_inserter<Function>(function));
  3433. }
  3434. template <typename Function>
  3435. inline std::size_t for_each_token(const std::string& buffer,
  3436. const char* delimiters,
  3437. Function function)
  3438. {
  3439. return split(delimiters,
  3440. buffer,
  3441. strtk::functional_inserter<Function>(function));
  3442. }
  3443. template <typename InputIterator>
  3444. inline std::size_t count_consecutive_duplicates(const InputIterator begin, const InputIterator end)
  3445. {
  3446. if (std::distance(begin,end) < 2) return 0;
  3447. InputIterator prev = begin;
  3448. InputIterator itr = begin;
  3449. std::size_t count = 0;
  3450. while (end != ++itr)
  3451. {
  3452. if ((*prev) == (*itr))
  3453. ++count;
  3454. else
  3455. prev = itr;
  3456. }
  3457. return count;
  3458. }
  3459. template <typename T,
  3460. typename Allocator,
  3461. template <typename,typename> class Sequence>
  3462. inline T min_of_cont(const Sequence<T,Allocator>& sequence)
  3463. {
  3464. return (*std::min_element(sequence.begin(),sequence.end()));
  3465. }
  3466. template <typename T,
  3467. typename Comparator,
  3468. typename Allocator>
  3469. inline T min_of_cont(const std::set<T,Comparator,Allocator>& set)
  3470. {
  3471. return (*set.begin());
  3472. }
  3473. template <typename T,
  3474. typename Comparator,
  3475. typename Allocator>
  3476. inline T min_of_cont(const std::multiset<T,Comparator,Allocator>& multiset)
  3477. {
  3478. return (*multiset.begin());
  3479. }
  3480. template <typename T,
  3481. typename Allocator,
  3482. template <typename,typename> class Sequence>
  3483. inline T max_of_cont(const Sequence<T,Allocator>& sequence)
  3484. {
  3485. return (*std::max_element(sequence.begin(),sequence.end()));
  3486. }
  3487. template <typename T,
  3488. typename Comparator,
  3489. typename Allocator>
  3490. inline T max_of_cont(const std::set<T,Comparator,Allocator>& set)
  3491. {
  3492. return (*set.rbegin());
  3493. }
  3494. template <typename T,
  3495. typename Comparator,
  3496. typename Allocator>
  3497. inline T max_of_cont(const std::multiset<T,Comparator,Allocator>& multiset)
  3498. {
  3499. return (*multiset.rbegin());
  3500. }
  3501. template <typename InputIterator>
  3502. inline void min_max_of_range(const InputIterator begin, const InputIterator end,
  3503. typename std::iterator_traits<InputIterator>::value_type& min_value,
  3504. typename std::iterator_traits<InputIterator>::value_type& max_value)
  3505. {
  3506. min_value = *begin;
  3507. max_value = *begin;
  3508. InputIterator itr = begin;
  3509. while (end != ++itr)
  3510. {
  3511. if (*itr < min_value)
  3512. min_value = (*itr);
  3513. else if (*itr > max_value)
  3514. max_value = (*itr);
  3515. }
  3516. }
  3517. template <typename T,
  3518. typename Allocator,
  3519. template <typename,typename> class Sequence>
  3520. inline void min_max_of_cont(const Sequence<T,Allocator>& sequence,
  3521. T& min_value,
  3522. T& max_value)
  3523. {
  3524. min_max_of_range(sequence.begin(),sequence.end(),
  3525. min_value,
  3526. max_value);
  3527. }
  3528. template <typename T,
  3529. typename Comparator,
  3530. typename Allocator>
  3531. inline void min_max_of_cont(const std::set<T,Comparator,Allocator>& set,
  3532. T& min_value,
  3533. T& max_value)
  3534. {
  3535. min_value = (*set.begin());
  3536. max_value = (*set.rbegin());
  3537. }
  3538. template <typename T,
  3539. typename Comparator,
  3540. typename Allocator>
  3541. inline void min_max_of_cont(const std::multiset<T,Comparator,Allocator>& multiset,
  3542. T& min_value,
  3543. T& max_value)
  3544. {
  3545. min_value = (*multiset.begin());
  3546. max_value = (*multiset.rbegin());
  3547. }
  3548. template <typename Iterator>
  3549. inline void lexicographically_canonicalize(Iterator begin, Iterator end)
  3550. {
  3551. typedef typename std::iterator_traits<Iterator>::value_type type;
  3552. typedef typename std::pair<Iterator,Iterator> iter_type;
  3553. typedef typename std::list<iter_type> itr_list_type;
  3554. itr_list_type itr_list;
  3555. type smallest = (*std::min_element(begin,end));
  3556. for (Iterator itr = begin; itr != end; ++itr)
  3557. {
  3558. if (*itr == smallest) itr_list.push_back(std::make_pair(itr,itr));
  3559. }
  3560. while (itr_list.size() > 1)
  3561. {
  3562. typename itr_list_type::iterator itr = itr_list.begin();
  3563. while (itr_list.end() != itr)
  3564. {
  3565. ++(*itr).first;
  3566. if (end == (*itr).first)
  3567. itr = itr_list.erase(itr);
  3568. else
  3569. ++itr;
  3570. }
  3571. smallest = *(*itr_list.begin()).first;
  3572. for (itr = (++itr_list.begin()); itr != itr_list.end(); ++itr)
  3573. {
  3574. if (*(*itr).first < smallest)
  3575. {
  3576. smallest = *(*itr).first;
  3577. }
  3578. }
  3579. itr = itr_list.begin();
  3580. while (itr_list.end() != itr)
  3581. {
  3582. if (*(*itr).first != smallest)
  3583. itr = itr_list.erase(itr);
  3584. else
  3585. ++itr;
  3586. }
  3587. itr = itr_list.begin();
  3588. while (itr_list.end() != itr)
  3589. {
  3590. if (end == (*itr).first)
  3591. itr = itr_list.erase(itr);
  3592. else
  3593. ++itr;
  3594. }
  3595. }
  3596. std::rotate(begin,(*itr_list.begin()).second,end);
  3597. }
  3598. inline void lexicographically_canonicalize(std::string& str)
  3599. {
  3600. lexicographically_canonicalize(const_cast<char*>(str.data()),
  3601. const_cast<char*>(str.data() + str.size()));
  3602. }
  3603. template <typename T,
  3604. typename Allocator,
  3605. template <typename,typename> class Sequence>
  3606. inline void lexicographically_canonicalize(Sequence<T,Allocator>& sequence)
  3607. {
  3608. lexicographically_canonicalize(sequence.begin(),sequence.end());
  3609. }
  3610. inline const char* first_non_repeated_char(const char* begin, const char* end)
  3611. {
  3612. static const std::size_t lut_size = 256;
  3613. unsigned long long int lut[lut_size];
  3614. std::fill_n(lut,lut_size,std::numeric_limits<unsigned long long int>::max());
  3615. static const unsigned long long int not_yet_encountered = std::numeric_limits<unsigned long long int>::max();
  3616. static const unsigned long long int repeated = not_yet_encountered - 1;
  3617. const char* itr = begin;
  3618. unsigned long long int position = 0;
  3619. while (end != itr)
  3620. {
  3621. unsigned long long int& element = lut[static_cast<unsigned int>(*itr)];
  3622. if (not_yet_encountered == element)
  3623. {
  3624. element = position;
  3625. }
  3626. else if (element < repeated)
  3627. {
  3628. element = repeated;
  3629. }
  3630. ++itr;
  3631. ++position;
  3632. }
  3633. position = repeated;
  3634. for (std::size_t i = 0; i < lut_size; ++i)
  3635. {
  3636. if (lut[i] < position)
  3637. position = lut[i];
  3638. }
  3639. return (repeated != position) ? (begin + position) : end;
  3640. }
  3641. inline const unsigned char* first_non_repeated_char(const unsigned char* begin, const unsigned char* end)
  3642. {
  3643. char * b = reinterpret_cast<char*>(const_cast<unsigned char*>(begin));
  3644. char * e = reinterpret_cast<char*>(const_cast<unsigned char*>(end));
  3645. return const_cast<const unsigned char*>(reinterpret_cast<unsigned char*>(const_cast<char*>(first_non_repeated_char(b,e))));
  3646. }
  3647. inline std::size_t first_non_repeated_char(const std::string& str)
  3648. {
  3649. if (str.empty())
  3650. return static_cast<std::size_t>(std::string::npos);
  3651. const char* itr = first_non_repeated_char(str.data(),str.data() + str.size());
  3652. if ((str.data() + str.size()) != itr)
  3653. return static_cast<std::size_t>(itr - str.data());
  3654. else
  3655. return static_cast<std::size_t>(std::string::npos);
  3656. }
  3657. inline void convert_bin_to_hex(const unsigned char* begin, const unsigned char* end, unsigned char* out)
  3658. {
  3659. static const unsigned short hex_lut[] =
  3660. {
  3661. 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730,
  3662. 0x3830, 0x3930, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530, 0x4630,
  3663. 0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731,
  3664. 0x3831, 0x3931, 0x4131, 0x4231, 0x4331, 0x4431, 0x4531, 0x4631,
  3665. 0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732,
  3666. 0x3832, 0x3932, 0x4132, 0x4232, 0x4332, 0x4432, 0x4532, 0x4632,
  3667. 0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733,
  3668. 0x3833, 0x3933, 0x4133, 0x4233, 0x4333, 0x4433, 0x4533, 0x4633,
  3669. 0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734,
  3670. 0x3834, 0x3934, 0x4134, 0x4234, 0x4334, 0x4434, 0x4534, 0x4634,
  3671. 0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735,
  3672. 0x3835, 0x3935, 0x4135, 0x4235, 0x4335, 0x4435, 0x4535, 0x4635,
  3673. 0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736,
  3674. 0x3836, 0x3936, 0x4136, 0x4236, 0x4336, 0x4436, 0x4536, 0x4636,
  3675. 0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737,
  3676. 0x3837, 0x3937, 0x4137, 0x4237, 0x4337, 0x4437, 0x4537, 0x4637,
  3677. 0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738,
  3678. 0x3838, 0x3938, 0x4138, 0x4238, 0x4338, 0x4438, 0x4538, 0x4638,
  3679. 0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739,
  3680. 0x3839, 0x3939, 0x4139, 0x4239, 0x4339, 0x4439, 0x4539, 0x4639,
  3681. 0x3041, 0x3141, 0x3241, 0x3341, 0x3441, 0x3541, 0x3641, 0x3741,
  3682. 0x3841, 0x3941, 0x4141, 0x4241, 0x4341, 0x4441, 0x4541, 0x4641,
  3683. 0x3042, 0x3142, 0x3242, 0x3342, 0x3442, 0x3542, 0x3642, 0x3742,
  3684. 0x3842, 0x3942, 0x4142, 0x4242, 0x4342, 0x4442, 0x4542, 0x4642,
  3685. 0x3043, 0x3143, 0x3243, 0x3343, 0x3443, 0x3543, 0x3643, 0x3743,
  3686. 0x3843, 0x3943, 0x4143, 0x4243, 0x4343, 0x4443, 0x4543, 0x4643,
  3687. 0x3044, 0x3144, 0x3244, 0x3344, 0x3444, 0x3544, 0x3644, 0x3744,
  3688. 0x3844, 0x3944, 0x4144, 0x4244, 0x4344, 0x4444, 0x4544, 0x4644,
  3689. 0x3045, 0x3145, 0x3245, 0x3345, 0x3445, 0x3545, 0x3645, 0x3745,
  3690. 0x3845, 0x3945, 0x4145, 0x4245, 0x4345, 0x4445, 0x4545, 0x4645,
  3691. 0x3046, 0x3146, 0x3246, 0x3346, 0x3446, 0x3546, 0x3646, 0x3746,
  3692. 0x3846, 0x3946, 0x4146, 0x4246, 0x4346, 0x4446, 0x4546, 0x4646
  3693. };
  3694. for (const unsigned char* itr = begin; end != itr; ++itr)
  3695. {
  3696. *reinterpret_cast<unsigned short*>(out) = hex_lut[(*itr)];
  3697. out += sizeof(unsigned short);
  3698. }
  3699. }
  3700. inline void convert_bin_to_hex(const char* begin, const char* end, char* out)
  3701. {
  3702. convert_bin_to_hex(reinterpret_cast<const unsigned char*>(begin),
  3703. reinterpret_cast<const unsigned char*>(end),
  3704. reinterpret_cast<unsigned char*>(out));
  3705. }
  3706. inline void convert_bin_to_hex(const std::pair<unsigned char*,unsigned char*>& r, unsigned char* out)
  3707. {
  3708. convert_bin_to_hex(r.first,r.second,out);
  3709. }
  3710. inline void convert_bin_to_hex(const std::pair<const unsigned char*,const unsigned char*>& r, unsigned char* out)
  3711. {
  3712. convert_bin_to_hex(r.first,r.second,out);
  3713. }
  3714. inline void convert_bin_to_hex(const std::pair<const char*,const char*>& r, char* out)
  3715. {
  3716. convert_bin_to_hex(r.first,r.second,out);
  3717. }
  3718. inline void convert_bin_to_hex(const std::string& binary_data, std::string& output)
  3719. {
  3720. output.resize(binary_data.size() * 2);
  3721. convert_bin_to_hex(binary_data.data(),
  3722. binary_data.data() + binary_data.size(),
  3723. const_cast<char*>(output.data()));
  3724. }
  3725. inline std::string convert_bin_to_hex(const std::string& binary_data)
  3726. {
  3727. std::string output;
  3728. convert_bin_to_hex(binary_data,output);
  3729. return output;
  3730. }
  3731. inline bool convert_hex_to_bin(const unsigned char* begin, const unsigned char* end, unsigned char* out)
  3732. {
  3733. const std::size_t length = std::distance(begin,end);
  3734. if (0 == length)
  3735. return false;
  3736. else if (1 == (length % 2))
  3737. return false;
  3738. static const unsigned char hex_to_bin[] =
  3739. {
  3740. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 - 0x07
  3741. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 - 0x0F
  3742. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 - 0x17
  3743. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 - 0x1F
  3744. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 - 0x27
  3745. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 - 0x2F
  3746. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 0x30 - 0x37
  3747. 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 - 0x3F
  3748. 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, // 0x40 - 0x47
  3749. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 - 0x4F
  3750. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 - 0x57
  3751. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 - 0x5F
  3752. 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, // 0x60 - 0x67
  3753. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 - 0x6F
  3754. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 - 0x77
  3755. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 - 0x7F
  3756. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 - 0x87
  3757. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 - 0x8F
  3758. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 - 0x97
  3759. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 - 0x9F
  3760. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 - 0xA7
  3761. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 - 0xAF
  3762. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 - 0xB7
  3763. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 - 0xBF
  3764. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 - 0xC7
  3765. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 - 0xCF
  3766. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 - 0xD7
  3767. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 - 0xDF
  3768. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 - 0xE7
  3769. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 - 0xEF
  3770. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 - 0xF7
  3771. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 0xF8 - 0xFF
  3772. };
  3773. const unsigned char* itr = begin;
  3774. while (end != itr)
  3775. {
  3776. *reinterpret_cast<unsigned char*>(out) = static_cast<unsigned char>(hex_to_bin[itr[0]] << 4 | hex_to_bin[itr[1]]);
  3777. ++out;
  3778. itr += 2;
  3779. }
  3780. return true;
  3781. }
  3782. inline bool convert_hex_to_bin(const char* begin, const char* end, char* out)
  3783. {
  3784. return convert_hex_to_bin(reinterpret_cast<const unsigned char*>(begin),
  3785. reinterpret_cast<const unsigned char*>(end),
  3786. reinterpret_cast<unsigned char*>(out));
  3787. }
  3788. inline bool convert_hex_to_bin(const std::pair<unsigned char*,unsigned char*>& r, unsigned char* out)
  3789. {
  3790. return convert_hex_to_bin(r.first,r.second,out);
  3791. }
  3792. inline bool convert_hex_to_bin(const std::pair<const unsigned char*,const unsigned char*>& r, unsigned char* out)
  3793. {
  3794. return convert_hex_to_bin(r.first,r.second,out);
  3795. }
  3796. inline bool convert_hex_to_bin(const std::pair<char*,char*>& r, char* out)
  3797. {
  3798. return convert_hex_to_bin(r.first,r.second,out);
  3799. }
  3800. inline bool convert_hex_to_bin(const std::pair<const char*,const char*>& r, char* out)
  3801. {
  3802. return convert_hex_to_bin(r.first,r.second,out);
  3803. }
  3804. inline bool convert_hex_to_bin(const std::string& hex_data, std::string& output)
  3805. {
  3806. if (hex_data.empty() || (1 == (hex_data.size() % 2)))
  3807. return false;
  3808. output.resize(hex_data.size() >> 1);
  3809. return convert_hex_to_bin(hex_data.data(),
  3810. hex_data.data() + hex_data.size(),
  3811. const_cast<char*>(output.data()));
  3812. }
  3813. inline std::size_t convert_bin_to_base64(const unsigned char* begin, const unsigned char* end, unsigned char* out)
  3814. {
  3815. static const unsigned char bin_to_base64 [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  3816. const std::size_t length = std::distance(begin,end);
  3817. std::size_t rounds = length / 3;
  3818. const unsigned char* itr = begin;
  3819. for (std::size_t i = 0; i < rounds; ++i)
  3820. {
  3821. unsigned int block = *(itr++) << 16;
  3822. block |= *(itr++) << 8;
  3823. block |= *(itr++) ;
  3824. *(out++) = bin_to_base64[( block >> 18 ) & 0x3F];
  3825. *(out++) = bin_to_base64[( block >> 12 ) & 0x3F];
  3826. *(out++) = bin_to_base64[( block >> 6 ) & 0x3F];
  3827. *(out++) = bin_to_base64[( block ) & 0x3F];
  3828. }
  3829. if ((rounds = (length % 3)) > 0)
  3830. {
  3831. switch (rounds)
  3832. {
  3833. case 1 : {
  3834. unsigned int block = (unsigned char) (*itr) << 16;
  3835. *(out++) = bin_to_base64[( block >> 18 ) & 0x3F];
  3836. *(out++) = bin_to_base64[( block >> 12 ) & 0x3F];
  3837. *(out++) = '=';
  3838. *(out++) = '=';
  3839. }
  3840. break;
  3841. case 2 : {
  3842. unsigned int block = *(itr++) << 16;
  3843. block |= *(itr++) << 8;
  3844. *(out++) = bin_to_base64[( block >> 18 ) & 0x3F];
  3845. *(out++) = bin_to_base64[( block >> 12 ) & 0x3F];
  3846. *(out++) = bin_to_base64[( block >> 6 ) & 0x3F];
  3847. *(out++) = '=';
  3848. }
  3849. break;
  3850. }
  3851. }
  3852. return static_cast<std::size_t>((length / 3) * 4) + ((length % 3) > 0 ? 4 : 0);
  3853. }
  3854. inline std::size_t convert_bin_to_base64(const char* begin, const char* end, char* out)
  3855. {
  3856. return convert_bin_to_base64(reinterpret_cast<const unsigned char*>(begin),
  3857. reinterpret_cast<const unsigned char*>(end),
  3858. reinterpret_cast<unsigned char*>(out));
  3859. }
  3860. inline void convert_bin_to_base64(const std::string& binary_data, std::string& output)
  3861. {
  3862. output.resize(std::max<std::size_t>(4,binary_data.size() << 1));
  3863. std::size_t resize = convert_bin_to_base64(binary_data.data(),
  3864. binary_data.data() + binary_data.size(),
  3865. const_cast<char*>(output.data()));
  3866. output.resize(resize);
  3867. }
  3868. inline std::size_t convert_base64_to_bin(const unsigned char* begin, const unsigned char* end, unsigned char* out)
  3869. {
  3870. static const unsigned char base64_to_bin[] =
  3871. {
  3872. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x00 - 0x07
  3873. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x08 - 0x0F
  3874. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x10 - 0x17
  3875. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x18 - 0x1F
  3876. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x20 - 0x27
  3877. 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, // 0x28 - 0x2F
  3878. 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 - 0x37
  3879. 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x38 - 0x3F
  3880. 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 - 0x47
  3881. 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 - 0x4F
  3882. 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 - 0x57
  3883. 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x58 - 0x5F
  3884. 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 - 0x67
  3885. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 - 0x6F
  3886. 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 - 0x77
  3887. 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x78 - 0x7F
  3888. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x80 - 0x87
  3889. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x88 - 0x8F
  3890. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x90 - 0x97
  3891. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x98 - 0x9F
  3892. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA0 - 0xA7
  3893. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA8 - 0xAF
  3894. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB0 - 0xB7
  3895. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB8 - 0xBF
  3896. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC0 - 0xC7
  3897. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC8 - 0xCF
  3898. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD0 - 0xD7
  3899. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD8 - 0xDF
  3900. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE0 - 0xE7
  3901. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE8 - 0xEF
  3902. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xF0 - 0xF7
  3903. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 0xF8 - 0xFF
  3904. };
  3905. const unsigned char* end_itr = end;
  3906. if ('=' == *(end - 2))
  3907. end_itr = end - 2;
  3908. else if ('=' == *(end - 1))
  3909. end_itr = end - 1;
  3910. const std::size_t length = std::distance(begin,end_itr);
  3911. const std::size_t rounds = length / 4;
  3912. const unsigned char* itr = begin;
  3913. for (std::size_t i = 0; i < rounds; ++i)
  3914. {
  3915. unsigned int block = base64_to_bin[*(itr++)] << 18;
  3916. block |= base64_to_bin[*(itr++)] << 12;
  3917. block |= base64_to_bin[*(itr++)] << 6;
  3918. block |= base64_to_bin[*(itr++)];
  3919. *(out++) = static_cast<unsigned char>(( block >> 16 ) & 0xFF);
  3920. *(out++) = static_cast<unsigned char>(( block >> 8 ) & 0xFF);
  3921. *(out++) = static_cast<unsigned char>(( block ) & 0xFF);
  3922. }
  3923. const std::size_t remainder = (length % 4);
  3924. if (remainder > 0)
  3925. {
  3926. switch (remainder)
  3927. {
  3928. case 2 : {
  3929. unsigned int block = base64_to_bin[*(itr++)] << 18;
  3930. block |= base64_to_bin[*(itr++)] << 12;
  3931. (*out) = static_cast<unsigned char>(( block >> 16 ) & 0xFF);
  3932. }
  3933. break;
  3934. case 3 : {
  3935. unsigned int block = base64_to_bin[*(itr++)] << 18;
  3936. block |= base64_to_bin[*(itr++)] << 12;
  3937. block |= base64_to_bin[*(itr++)] << 6;
  3938. *(out++) = static_cast<unsigned char>(( block >> 16 ) & 0xFF);
  3939. *(out ) = static_cast<unsigned char>(( block >> 8 ) & 0xFF);
  3940. }
  3941. break;
  3942. }
  3943. }
  3944. return static_cast<std::size_t>((3 * length) / 4);
  3945. }
  3946. inline std::size_t convert_base64_to_bin(const char* begin, const char* end, char* out)
  3947. {
  3948. return convert_base64_to_bin(reinterpret_cast<const unsigned char*>(begin),
  3949. reinterpret_cast<const unsigned char*>(end),
  3950. reinterpret_cast<unsigned char*>(out));
  3951. }
  3952. inline void convert_base64_to_bin(const std::string& binary_data, std::string& output)
  3953. {
  3954. output.resize(binary_data.size());
  3955. std::size_t resize = convert_base64_to_bin(binary_data.data(),
  3956. binary_data.data() + binary_data.size(),
  3957. const_cast<char*>(output.data()));
  3958. output.resize(resize);
  3959. }
  3960. inline void convert_to_printable_chars(unsigned char* begin, unsigned char* end)
  3961. {
  3962. static const unsigned char printable_char_table[] =
  3963. {
  3964. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x00 - 0x07
  3965. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x08 - 0x0F
  3966. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x10 - 0x17
  3967. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x18 - 0x1F
  3968. 0x2E, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, // 0x20 - 0x27
  3969. 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, // 0x28 - 0x2F
  3970. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // 0x30 - 0x37
  3971. 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // 0x38 - 0x3F
  3972. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, // 0x40 - 0x47
  3973. 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, // 0x48 - 0x4F
  3974. 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, // 0x50 - 0x57
  3975. 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, // 0x58 - 0x5F
  3976. 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, // 0x60 - 0x67
  3977. 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, // 0x68 - 0x6F
  3978. 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // 0x70 - 0x77
  3979. 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x2E, // 0x78 - 0x7F
  3980. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x80 - 0x87
  3981. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x88 - 0x8F
  3982. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x90 - 0x97
  3983. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x98 - 0x9F
  3984. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xA0 - 0xA7
  3985. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xA8 - 0xAF
  3986. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xB0 - 0xB7
  3987. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xB8 - 0xBF
  3988. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xC0 - 0xC7
  3989. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xC8 - 0xCF
  3990. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xD0 - 0xD7
  3991. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xD8 - 0xDF
  3992. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xE0 - 0xE7
  3993. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xE8 - 0xEF
  3994. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xF0 - 0xF7
  3995. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E // 0xF8 - 0xFF
  3996. };
  3997. unsigned char* itr = begin;
  3998. while (end != itr)
  3999. {
  4000. (*itr) = printable_char_table[static_cast<unsigned int>((*itr))];
  4001. ++itr;
  4002. }
  4003. }
  4004. inline void convert_to_printable_chars(char* begin, char* end)
  4005. {
  4006. convert_to_printable_chars(reinterpret_cast<unsigned char*>(begin),
  4007. reinterpret_cast<unsigned char*>(end));
  4008. }
  4009. inline void convert_to_printable_chars(std::string& str)
  4010. {
  4011. convert_to_printable_chars(reinterpret_cast<unsigned char*>(const_cast<char*>(str.data())),
  4012. reinterpret_cast<unsigned char*>(const_cast<char*>(str.data() + str.size())));
  4013. }
  4014. inline void convert_to_uppercase(unsigned char* begin, unsigned char* end)
  4015. {
  4016. std::transform(begin,end,begin,::toupper);
  4017. /*
  4018. unsigned char* itr = begin;
  4019. while (end != itr)
  4020. {
  4021. //(*itr) = std::toupper((*itr), std::locale::classic());
  4022. (*itr) = static_cast<unsigned char>(::toupper(static_cast<int>(*itr)));
  4023. ++itr;
  4024. }
  4025. */
  4026. }
  4027. inline void convert_to_uppercase(char* begin, char* end)
  4028. {
  4029. convert_to_uppercase(reinterpret_cast<unsigned char*>(begin),
  4030. reinterpret_cast<unsigned char*>(end));
  4031. }
  4032. inline void convert_to_uppercase(std::string& str)
  4033. {
  4034. convert_to_uppercase(reinterpret_cast<unsigned char*>(const_cast<char*>(str.data())),
  4035. reinterpret_cast<unsigned char*>(const_cast<char*>(str.data() + str.size())));
  4036. }
  4037. inline void convert_to_lowercase(unsigned char* begin, unsigned char* end)
  4038. {
  4039. std::transform(begin,end,begin,::tolower);
  4040. /*
  4041. unsigned char* itr = begin;
  4042. while (end != itr)
  4043. {
  4044. //(*itr) = std::tolower((*itr), std::locale::classic());
  4045. (*itr) = static_cast<unsigned char>(::tolower(static_cast<int>(*itr)));
  4046. ++itr;
  4047. }
  4048. */
  4049. }
  4050. inline void convert_to_lowercase(char* begin, char* end)
  4051. {
  4052. convert_to_lowercase(reinterpret_cast<unsigned char*>(begin),
  4053. reinterpret_cast<unsigned char*>(end));
  4054. }
  4055. inline void convert_to_lowercase(const char* begin, const char* end)
  4056. {
  4057. convert_to_lowercase(const_cast<char*>(begin),const_cast<char*>(end));
  4058. }
  4059. inline void convert_to_lowercase(std::string& str)
  4060. {
  4061. convert_to_lowercase(reinterpret_cast<unsigned char*>(const_cast<char*>(str.data())),
  4062. reinterpret_cast<unsigned char*>(const_cast<char*>(str.data() + str.size())));
  4063. }
  4064. inline std::string as_lowercase(const std::string& str)
  4065. {
  4066. std::string result = str;
  4067. convert_to_lowercase(result);
  4068. return result;
  4069. }
  4070. inline std::string as_uppercase(const std::string& str)
  4071. {
  4072. std::string result = str;
  4073. convert_to_uppercase(result);
  4074. return result;
  4075. }
  4076. inline bool twoway_bitwise_interleave(const unsigned char* begin1, const unsigned char* end1,
  4077. const unsigned char* begin2, const unsigned char* end2,
  4078. unsigned char* out)
  4079. {
  4080. if (std::distance(begin1,end1) != std::distance(begin2,end2))
  4081. {
  4082. return false;
  4083. }
  4084. static const std::size_t interleave_table_size = 256;
  4085. static const unsigned short interleave_table[interleave_table_size] =
  4086. {
  4087. 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, // 0x00 - 0x07
  4088. 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, // 0x08 - 0x0F
  4089. 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, // 0x10 - 0x17
  4090. 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, // 0x18 - 0x1F
  4091. 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, // 0x20 - 0x27
  4092. 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, // 0x28 - 0x2F
  4093. 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, // 0x30 - 0x37
  4094. 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, // 0x38 - 0x3F
  4095. 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, // 0x40 - 0x47
  4096. 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, // 0x48 - 0x4F
  4097. 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, // 0x50 - 0x57
  4098. 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, // 0x58 - 0x5F
  4099. 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, // 0x60 - 0x67
  4100. 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, // 0x68 - 0x6F
  4101. 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, // 0x70 - 0x77
  4102. 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, // 0x78 - 0x7F
  4103. 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, // 0x80 - 0x87
  4104. 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, // 0x88 - 0x8F
  4105. 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, // 0x90 - 0x97
  4106. 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, // 0x98 - 0x9F
  4107. 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, // 0xA0 - 0xA7
  4108. 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, // 0xA8 - 0xAF
  4109. 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, // 0xB0 - 0xB7
  4110. 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, // 0xB8 - 0xBF
  4111. 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, // 0xC0 - 0xC7
  4112. 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, // 0xC8 - 0xCF
  4113. 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, // 0xD0 - 0xD7
  4114. 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, // 0xD8 - 0xDF
  4115. 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, // 0xE0 - 0xE7
  4116. 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, // 0xE8 - 0xEF
  4117. 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, // 0xF0 - 0xF7
  4118. 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 // 0xF8 - 0xFF
  4119. };
  4120. const unsigned char* itr1 = begin1;
  4121. const unsigned char* itr2 = begin2;
  4122. while (end1 != itr1)
  4123. {
  4124. *(reinterpret_cast<unsigned short*>(out)) = (interleave_table[*(itr2++)] << 1);
  4125. *(reinterpret_cast<unsigned short*>(out)) |= interleave_table[*(itr1++)];
  4126. out += 2;
  4127. }
  4128. return true;
  4129. }
  4130. inline bool twoway_bitwise_interleave(const char* begin1, const char* end1,
  4131. const char* begin2, const char* end2,
  4132. char* out)
  4133. {
  4134. return twoway_bitwise_interleave(reinterpret_cast<const unsigned char*>(begin1),
  4135. reinterpret_cast<const unsigned char*>(end1),
  4136. reinterpret_cast<const unsigned char*>(begin2),
  4137. reinterpret_cast<const unsigned char*>(end2),
  4138. reinterpret_cast<unsigned char*>(out));
  4139. }
  4140. inline bool twoway_bitwise_interleave(const std::string& str1,
  4141. const std::string& str2,
  4142. std::string& out)
  4143. {
  4144. if (str1.size() != str2.size())
  4145. {
  4146. return false;
  4147. }
  4148. out.resize(str1.size());
  4149. return twoway_bitwise_interleave(str1.data(),str1.data() + str1.size(),
  4150. str2.data(),str2.data() + str2.size(),
  4151. const_cast<char*>(out.data()));
  4152. }
  4153. template <std::size_t n>
  4154. struct interleave_ary;
  4155. template<> struct interleave_ary<sizeof(unsigned short)> { typedef unsigned short type; };
  4156. template<> struct interleave_ary<sizeof(unsigned int )> { typedef unsigned int type; };
  4157. template<> struct interleave_ary<sizeof(unsigned long long int)> { typedef unsigned long long int type; };
  4158. template <std::size_t n>
  4159. inline void create_nway_interleave_table(typename interleave_ary<n>::type table[256])
  4160. {
  4161. typedef typename interleave_ary<n>::type type;
  4162. const type diff = static_cast<type>(n - 1);
  4163. for (type i = static_cast<type>(0); i < static_cast<type>(256); ++i)
  4164. {
  4165. table[i] = 0x00;
  4166. for (type j = static_cast<type>(0); j < static_cast<type>(8); ++j)
  4167. {
  4168. table[i] |= (i & (1 << j)) << (j * diff);
  4169. }
  4170. }
  4171. }
  4172. namespace bitwise_operation { enum type { eAND, eOR, eXOR }; }
  4173. inline void bitwise_transform(const bitwise_operation::type& operation,
  4174. const unsigned char* begin1, const unsigned char* end1,
  4175. const unsigned char* begin2,
  4176. unsigned char* out)
  4177. {
  4178. const unsigned char* itr1 = begin1;
  4179. const unsigned char* itr2 = begin2;
  4180. switch (operation)
  4181. {
  4182. case bitwise_operation::eAND : while (itr1 != end1) { *(out++) = *(itr1++) & *(itr2++); } return;
  4183. case bitwise_operation::eOR : while (itr1 != end1) { *(out++) = *(itr1++) | *(itr2++); } return;
  4184. case bitwise_operation::eXOR : while (itr1 != end1) { *(out++) = *(itr1++) ^ *(itr2++); } return;
  4185. }
  4186. }
  4187. inline void bitwise_transform(const bitwise_operation::type& operation,
  4188. const char* begin1, const char* end1,
  4189. const char* begin2,
  4190. char* out)
  4191. {
  4192. bitwise_transform(operation,
  4193. reinterpret_cast<const unsigned char*>(begin1),
  4194. reinterpret_cast<const unsigned char*>(end1),
  4195. reinterpret_cast<const unsigned char*>(begin2),
  4196. reinterpret_cast<unsigned char*>(out));
  4197. }
  4198. inline void bitwise_transform(const bitwise_operation::type& operation,
  4199. const std::string& str1,
  4200. const std::string& str2,
  4201. std::string& out)
  4202. {
  4203. if (str1.size() != str2.size()) return;
  4204. out.resize(str1.size());
  4205. bitwise_transform(operation,
  4206. str1.data(),str1.data() + str1.size(),
  4207. str2.data(),
  4208. const_cast<char*>(out.data()));
  4209. }
  4210. inline std::size_t high_bit_count(const unsigned char c)
  4211. {
  4212. static const std::size_t high_bits_in_char[256] =
  4213. {
  4214. 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
  4215. 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  4216. 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  4217. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4218. 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  4219. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4220. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4221. 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  4222. 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  4223. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4224. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4225. 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  4226. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4227. 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  4228. 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  4229. 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
  4230. };
  4231. return high_bits_in_char[c];
  4232. }
  4233. inline std::size_t high_bit_count(const unsigned short& s)
  4234. {
  4235. const unsigned char* ptr = reinterpret_cast<const unsigned char*>(&s);
  4236. return high_bit_count(*(ptr + 0)) + high_bit_count(*(ptr + 1));
  4237. }
  4238. inline std::size_t high_bit_count(const unsigned int& i)
  4239. {
  4240. const unsigned char* ptr = reinterpret_cast<const unsigned char*>(&i);
  4241. return high_bit_count(*(ptr + 0)) + high_bit_count(*(ptr + 1)) +
  4242. high_bit_count(*(ptr + 2)) + high_bit_count(*(ptr + 3));
  4243. }
  4244. inline std::size_t high_bit_count(const long long int& ll)
  4245. {
  4246. const unsigned char* ptr = reinterpret_cast<const unsigned char*>(&ll);
  4247. return high_bit_count(*(ptr + 0)) + high_bit_count(*(ptr + 1)) +
  4248. high_bit_count(*(ptr + 2)) + high_bit_count(*(ptr + 3)) +
  4249. high_bit_count(*(ptr + 4)) + high_bit_count(*(ptr + 5)) +
  4250. high_bit_count(*(ptr + 6)) + high_bit_count(*(ptr + 7));
  4251. }
  4252. inline std::size_t high_bit_count(const unsigned char* begin, const unsigned char* end)
  4253. {
  4254. std::size_t count = 0;
  4255. const unsigned char* itr = begin;
  4256. while (end != itr)
  4257. {
  4258. count += high_bit_count(*itr++);
  4259. }
  4260. return count;
  4261. }
  4262. inline std::size_t high_bit_count(const char* begin, const char* end)
  4263. {
  4264. return high_bit_count(reinterpret_cast<const unsigned char*>(begin),
  4265. reinterpret_cast<const unsigned char*>(end));
  4266. }
  4267. inline std::size_t high_bit_count(const std::string& str)
  4268. {
  4269. return high_bit_count(str.data(),str.data() + str.size());
  4270. }
  4271. inline bool bit_state(const std::size_t& index, const unsigned char* ptr)
  4272. {
  4273. static const unsigned char bit_mask[] =
  4274. {
  4275. 0x01, //00000001
  4276. 0x02, //00000010
  4277. 0x04, //00000100
  4278. 0x08, //00001000
  4279. 0x10, //00010000
  4280. 0x20, //00100000
  4281. 0x40, //01000000
  4282. 0x80 //10000000
  4283. };
  4284. return (0 != (ptr[(index >> 3)] & bit_mask[index & 7]));
  4285. }
  4286. inline void set_bit_high(const std::size_t& index, unsigned char* const ptr)
  4287. {
  4288. static const unsigned char bit_mask[] =
  4289. {
  4290. 0x01, //00000001
  4291. 0x02, //00000010
  4292. 0x04, //00000100
  4293. 0x08, //00001000
  4294. 0x10, //00010000
  4295. 0x20, //00100000
  4296. 0x40, //01000000
  4297. 0x80 //10000000
  4298. };
  4299. ptr[(index >> 3)] |= bit_mask[index & 7];
  4300. }
  4301. inline void set_bit_low(const std::size_t& index, unsigned char* const ptr)
  4302. {
  4303. static const unsigned char bit_mask[] =
  4304. {
  4305. 0xFE, //11111110
  4306. 0xFD, //11111101
  4307. 0xFB, //11111011
  4308. 0xF7, //11110111
  4309. 0xEF, //11101111
  4310. 0xDF, //11011111
  4311. 0xBF, //10111111
  4312. 0x7F //01111111
  4313. };
  4314. ptr[(index >> 3)] &= bit_mask[index & 7];
  4315. }
  4316. inline std::size_t hamming_distance(const unsigned char* begin1, const unsigned char* end1,
  4317. const unsigned char* begin2, const unsigned char* end2)
  4318. {
  4319. if (std::distance(begin1,end1) != std::distance(begin2,end2))
  4320. {
  4321. return std::numeric_limits<std::size_t>::max();
  4322. }
  4323. std::size_t distance = 0;
  4324. const unsigned char* itr1 = begin1;
  4325. const unsigned char* itr2 = begin2;
  4326. while (end1 != itr1)
  4327. {
  4328. distance += high_bit_count(static_cast<unsigned char>(((*itr1++) ^ (*itr2++)) & 0xFF));
  4329. }
  4330. return distance;
  4331. }
  4332. inline std::size_t hamming_distance(const char* begin1, const char* end1,
  4333. const char* begin2, const char* end2)
  4334. {
  4335. return hamming_distance(reinterpret_cast<const unsigned char*>(begin1),
  4336. reinterpret_cast<const unsigned char*>(end1),
  4337. reinterpret_cast<const unsigned char*>(begin2),
  4338. reinterpret_cast<const unsigned char*>(end2));
  4339. }
  4340. inline std::size_t hamming_distance(const std::string& str1, const std::string& str2)
  4341. {
  4342. return hamming_distance(str1.data(), str1.data() + str1.size(),
  4343. str2.data(), str2.data() + str2.size());
  4344. }
  4345. template <typename Iterator>
  4346. inline std::size_t hamming_distance_elementwise(const Iterator begin1, const Iterator end1,
  4347. const Iterator begin2, const Iterator end2)
  4348. {
  4349. if (std::distance(begin1,end1) != std::distance(begin2,end2))
  4350. {
  4351. return std::numeric_limits<std::size_t>::max();
  4352. }
  4353. std::size_t distance = 0;
  4354. Iterator itr1 = begin1;
  4355. Iterator itr2 = begin2;
  4356. while (end1 != itr1)
  4357. {
  4358. if ((*itr1) != (*itr2))
  4359. ++distance;
  4360. }
  4361. return distance;
  4362. }
  4363. inline std::size_t hamming_distance_elementwise(const std::string& str1, const std::string& str2)
  4364. {
  4365. return hamming_distance_elementwise(str1.data(), str1.data() + str1.size(),
  4366. str2.data(), str2.data() + str2.size());
  4367. }
  4368. class token_grid
  4369. {
  4370. public:
  4371. typedef const unsigned char* iterator_t;
  4372. typedef unsigned int index_t;
  4373. typedef std::pair<iterator_t,iterator_t> range_t;
  4374. typedef std::deque<range_t> token_list_t;
  4375. typedef std::pair<index_t,index_t> row_index_range_t;
  4376. typedef std::deque<row_index_range_t> row_index_t;
  4377. typedef std::pair<index_t,index_t> row_range_t;
  4378. typedef std::pair<index_t,index_t> col_range_t;
  4379. private:
  4380. struct store
  4381. {
  4382. store()
  4383. : max_column(0)
  4384. {}
  4385. token_list_t token_list;
  4386. row_index_t row_index;
  4387. std::size_t max_column;
  4388. inline void clear()
  4389. {
  4390. token_list.clear();
  4391. row_index.clear();
  4392. }
  4393. inline range_t operator()(const std::size_t& col, const std::size_t& row) const
  4394. {
  4395. if (row < row_index.size())
  4396. {
  4397. const row_index_range_t& r = row_index[row];
  4398. if (col < (r.second - r.first + 1))
  4399. return *(token_list.begin() + (r.first + col));
  4400. else
  4401. return null_range();
  4402. }
  4403. else
  4404. return null_range();
  4405. }
  4406. inline bool remove_row(const std::size_t& row)
  4407. {
  4408. if (row >= row_index.size()) return false;
  4409. row_index_range_t& r = row_index[row];
  4410. std::size_t number_of_tokens = r.second - r.first + 1;
  4411. token_list_t::iterator remove_begin = token_list.begin() + r.first;
  4412. token_list_t::iterator remove_end = token_list.begin() + r.first + number_of_tokens;
  4413. token_list.erase(remove_begin,remove_end);
  4414. row_index.erase(row_index.begin() + row);
  4415. for (std::size_t i = row; i < row_index.size(); ++i)
  4416. {
  4417. row_index_range_t& r = row_index[i];
  4418. r.first -= static_cast<unsigned int>(number_of_tokens);
  4419. r.second -= static_cast<unsigned int>(number_of_tokens);
  4420. }
  4421. return true;
  4422. }
  4423. inline std::size_t token_count(const row_index_range_t& r) const
  4424. {
  4425. return (r.second - r.first + 1);
  4426. }
  4427. inline std::size_t token_count(const std::size_t& index) const
  4428. {
  4429. return token_count(row_index[index]);
  4430. }
  4431. inline bool remove_row_range(const std::size_t& r0, const std::size_t& r1)
  4432. {
  4433. if (r0 > r1)
  4434. return false;
  4435. else if (r0 >= row_index.size())
  4436. return false;
  4437. else if (r1 >= row_index.size())
  4438. return false;
  4439. std::size_t number_of_tokens = 0;
  4440. for (std::size_t i = r0; i <= r1; ++i)
  4441. {
  4442. row_index_range_t& r = row_index[i];
  4443. number_of_tokens += token_count(r);
  4444. }
  4445. row_index_range_t rr0 = row_index[r0];
  4446. token_list_t::iterator remove_begin = token_list.begin() + rr0.first;
  4447. token_list_t::iterator remove_end = token_list.begin() + rr0.first + number_of_tokens;
  4448. token_list.erase(remove_begin,remove_end);
  4449. row_index.erase(row_index.begin() + r0,row_index.begin() + r0 + (r1 - r0 + 1));
  4450. for (std::size_t i = r0; i < row_index.size(); ++i)
  4451. {
  4452. row_index_range_t& r = row_index[i];
  4453. r.first -= static_cast<unsigned int>(number_of_tokens);
  4454. r.second -= static_cast<unsigned int>(number_of_tokens);
  4455. }
  4456. return true;
  4457. }
  4458. struct remove_column_impl
  4459. {
  4460. std::size_t column;
  4461. std::size_t counter;
  4462. std::size_t remainder;
  4463. std::size_t current_row;
  4464. inline void update(store& idx)
  4465. {
  4466. current_row++;
  4467. while (current_row < idx.row_index.size())
  4468. {
  4469. std::size_t number_of_tokens = idx.token_count(current_row);
  4470. if (number_of_tokens > column)
  4471. break;
  4472. counter += number_of_tokens;
  4473. ++current_row;
  4474. }
  4475. if (current_row < idx.row_index.size())
  4476. {
  4477. counter += column + remainder;
  4478. row_index_range_t& r = idx.row_index[current_row];
  4479. remainder = (r.second - r.first) - column;
  4480. }
  4481. else
  4482. counter = std::numeric_limits<std::size_t>::max();
  4483. }
  4484. inline void process(store& idx)
  4485. {
  4486. token_list_t::iterator itr1 = idx.token_list.begin();
  4487. token_list_t::iterator itr2 = idx.token_list.begin();
  4488. token_list_t::iterator end = idx.token_list.end();
  4489. counter = 0;
  4490. remainder = 0;
  4491. current_row = static_cast<std::size_t>(-1);
  4492. update(idx);
  4493. while (end != itr1)
  4494. {
  4495. while ((end != itr1) && (0 != counter))
  4496. {
  4497. if (itr1 != itr2)
  4498. {
  4499. (*itr2) = (*itr1);
  4500. }
  4501. ++itr1;
  4502. ++itr2;
  4503. --counter;
  4504. }
  4505. if (0 == counter)
  4506. {
  4507. update(idx);
  4508. ++itr1;
  4509. }
  4510. }
  4511. std::size_t remove_count = 0;
  4512. idx.max_column = std::numeric_limits<std::size_t>::min();
  4513. for (std::size_t i = 0; i < idx.row_index.size(); ++i)
  4514. {
  4515. row_index_range_t& r = idx.row_index[i];
  4516. std::size_t token_count = (r.second - r.first + 1);
  4517. r.first -= static_cast<unsigned int>(remove_count);
  4518. if (token_count > column)
  4519. {
  4520. ++remove_count;
  4521. }
  4522. r.second -= static_cast<unsigned int>(remove_count);
  4523. token_count = (r.second - r.first + 1);
  4524. if (token_count > idx.max_column)
  4525. idx.max_column = token_count;
  4526. }
  4527. idx.token_list.resize(idx.token_list.size() - remove_count);
  4528. }
  4529. };
  4530. inline bool remove_column(const std::size_t& column)
  4531. {
  4532. if (column >= max_column) return false;
  4533. remove_column_impl rc;
  4534. rc.column = column;
  4535. rc.process(*this);
  4536. return true;
  4537. }
  4538. inline static range_t null_range()
  4539. {
  4540. static const range_t null_range_ = range_t(reinterpret_cast<const unsigned char*>(0),
  4541. reinterpret_cast<const unsigned char*>(0));
  4542. return null_range_;
  4543. }
  4544. };
  4545. template <typename DelimiterPredicate = multiple_char_delimiter_predicate>
  4546. struct row_processor
  4547. {
  4548. row_processor(store& idx,
  4549. DelimiterPredicate& tp,
  4550. const split_options::type split_mode = split_options::compress_delimiters)
  4551. : idx_(idx),
  4552. row_start_index_(0),
  4553. row_end_index_(0),
  4554. token_predicate_(tp),
  4555. split_mode_(split_mode)
  4556. {
  4557. idx_.max_column = std::numeric_limits<std::size_t>::min();
  4558. }
  4559. inline void operator()(const range_t& range)
  4560. {
  4561. if (0 == std::distance(range.first,range.second))
  4562. return;
  4563. row_start_index_ = idx_.token_list.size();
  4564. std::size_t token_count = split(token_predicate_,
  4565. range.first,range.second,
  4566. std::back_inserter(idx_.token_list),
  4567. split_mode_);
  4568. row_end_index_ = row_start_index_ + token_count - 1;
  4569. idx_.row_index.push_back(std::make_pair(row_start_index_,row_end_index_));
  4570. if (token_count > idx_.max_column)
  4571. idx_.max_column = token_count;
  4572. }
  4573. row_processor<DelimiterPredicate> operator=(const row_processor<DelimiterPredicate>&);
  4574. store& idx_;
  4575. std::size_t row_start_index_;
  4576. std::size_t row_end_index_;
  4577. DelimiterPredicate& token_predicate_;
  4578. split_options::type split_mode_;
  4579. };
  4580. public:
  4581. inline row_range_t range(std::size_t lower_bound,
  4582. std::size_t upper_bound = std::numeric_limits<std::size_t>::max()) const
  4583. {
  4584. if (upper_bound == std::numeric_limits<std::size_t>::max())
  4585. {
  4586. upper_bound = dsv_index_.token_list.size();
  4587. }
  4588. else if (upper_bound > dsv_index_.token_list.size())
  4589. {
  4590. return row_range_t(std::numeric_limits<std::size_t>::max(),std::numeric_limits<std::size_t>::max());
  4591. }
  4592. else if (lower_bound > upper_bound)
  4593. {
  4594. return row_range_t(std::numeric_limits<std::size_t>::max(),std::numeric_limits<std::size_t>::max());
  4595. }
  4596. return row_range_t(lower_bound,upper_bound);
  4597. }
  4598. struct options
  4599. {
  4600. options()
  4601. : row_split_option(split_options::compress_delimiters),
  4602. column_split_option(split_options::compress_delimiters),
  4603. row_delimiters("\n\r"),
  4604. column_delimiters(",|;\t "),
  4605. support_dquotes(false)
  4606. {}
  4607. options(split_options::type sro,
  4608. split_options::type sco,
  4609. const std::string& rd,
  4610. const std::string& cd,
  4611. const bool support_dq = false)
  4612. : row_split_option(sro),
  4613. column_split_option(sco),
  4614. row_delimiters(rd),
  4615. column_delimiters(cd),
  4616. support_dquotes(support_dq)
  4617. {}
  4618. inline options& set_column_split_option(const split_options::type& option)
  4619. {
  4620. column_split_option = option;
  4621. return *this;
  4622. }
  4623. inline options& set_row_split_option(const split_options::type& option)
  4624. {
  4625. row_split_option = option;
  4626. return *this;
  4627. }
  4628. inline options& set_column_delimiters(const std::string& delimiters)
  4629. {
  4630. column_delimiters = delimiters;
  4631. return *this;
  4632. }
  4633. inline options& set_row_delimiters(const std::string& delimiters)
  4634. {
  4635. row_delimiters = delimiters;
  4636. return *this;
  4637. }
  4638. split_options::type row_split_option;
  4639. split_options::type column_split_option;
  4640. std::string row_delimiters;
  4641. std::string column_delimiters;
  4642. bool support_dquotes;
  4643. };
  4644. class row_type
  4645. {
  4646. private:
  4647. typedef std::pair<bool,row_type*> row_pair_type;
  4648. public:
  4649. row_type()
  4650. : index_(std::numeric_limits<std::size_t>::max()),
  4651. size_(0)
  4652. {}
  4653. row_type(const std::size_t& index,
  4654. const store& dsv_index)
  4655. : index_(index),
  4656. size_ (dsv_index.token_count(index)),
  4657. begin_(dsv_index.token_list.begin() + dsv_index.row_index[index].first)
  4658. {}
  4659. template <typename T>
  4660. inline T operator[](const std::size_t& index) const
  4661. {
  4662. const range_t& range = *(begin_ + index);
  4663. return string_to_type_converter<T>(range.first,range.second);
  4664. }
  4665. template <typename T>
  4666. inline T get(const std::size_t& index) const
  4667. {
  4668. return operator[]<T>(index);
  4669. }
  4670. inline col_range_t all_columns() const
  4671. {
  4672. return col_range_t(0,static_cast<index_t>(size()));
  4673. }
  4674. inline range_t range() const
  4675. {
  4676. return range_t((*begin_).first,(*(begin_ + (size_ - 1))).second);
  4677. }
  4678. inline range_t token(const std::size_t& index) const
  4679. {
  4680. return *(begin_ + index);
  4681. }
  4682. inline std::size_t index() const
  4683. {
  4684. return index_;
  4685. }
  4686. inline std::size_t size() const
  4687. {
  4688. return size_;
  4689. }
  4690. inline std::size_t raw_length() const
  4691. {
  4692. std::size_t result = 0;
  4693. token_list_t::const_iterator itr = begin_;
  4694. for (std::size_t i = 0; i < size_; ++i, ++itr)
  4695. {
  4696. const range_t& range = (*itr);
  4697. result += std::distance(range.first,range.second);
  4698. }
  4699. return result;
  4700. }
  4701. inline std::size_t raw_length(const std::size_t& column_index) const
  4702. {
  4703. const range_t& range = *(begin_ + column_index);
  4704. return std::distance(range.first,range.second);
  4705. }
  4706. inline std::string as_string() const
  4707. {
  4708. std::string result;
  4709. result.reserve(std::distance(begin_->first,(begin_ + (size_ - 1))->second));
  4710. token_list_t::const_iterator itr = begin_;
  4711. for (std::size_t i = 0; i < size_; ++i, ++itr)
  4712. {
  4713. const range_t& range = (*itr);
  4714. result.append(range.first,range.second);
  4715. }
  4716. return result;
  4717. }
  4718. inline void as_string(std::string& out) const
  4719. {
  4720. out = as_string();
  4721. }
  4722. template <typename T0, typename T1, typename T2, typename T3,
  4723. typename T4, typename T5, typename T6, typename T7,
  4724. typename T8, typename T9>
  4725. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4726. const std::size_t& col2, const std::size_t& col3,
  4727. const std::size_t& col4, const std::size_t& col5,
  4728. const std::size_t& col6, const std::size_t& col7,
  4729. const std::size_t& col8, const std::size_t& col9,
  4730. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  4731. T6& t6, T7& t7, T8& t8, T9& t9) const
  4732. {
  4733. if (!process(*(begin_ + col0),t0)) return false;
  4734. if (!process(*(begin_ + col1),t1)) return false;
  4735. if (!process(*(begin_ + col2),t2)) return false;
  4736. if (!process(*(begin_ + col3),t3)) return false;
  4737. if (!process(*(begin_ + col4),t4)) return false;
  4738. if (!process(*(begin_ + col5),t5)) return false;
  4739. if (!process(*(begin_ + col6),t6)) return false;
  4740. if (!process(*(begin_ + col7),t7)) return false;
  4741. if (!process(*(begin_ + col8),t8)) return false;
  4742. if (!process(*(begin_ + col9),t9)) return false;
  4743. return true;
  4744. }
  4745. template <typename T0, typename T1, typename T2, typename T3,
  4746. typename T4, typename T5, typename T6, typename T7,
  4747. typename T8>
  4748. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4749. const std::size_t& col2, const std::size_t& col3,
  4750. const std::size_t& col4, const std::size_t& col5,
  4751. const std::size_t& col6, const std::size_t& col7,
  4752. const std::size_t& col8,
  4753. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  4754. T6& t6, T7& t7, T8& t8) const
  4755. {
  4756. if (!process(*(begin_ + col0),t0)) return false;
  4757. if (!process(*(begin_ + col1),t1)) return false;
  4758. if (!process(*(begin_ + col2),t2)) return false;
  4759. if (!process(*(begin_ + col3),t3)) return false;
  4760. if (!process(*(begin_ + col4),t4)) return false;
  4761. if (!process(*(begin_ + col5),t5)) return false;
  4762. if (!process(*(begin_ + col6),t6)) return false;
  4763. if (!process(*(begin_ + col7),t7)) return false;
  4764. if (!process(*(begin_ + col8),t8)) return false;
  4765. return true;
  4766. }
  4767. template <typename T0, typename T1, typename T2, typename T3,
  4768. typename T4, typename T5, typename T6, typename T7>
  4769. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4770. const std::size_t& col2, const std::size_t& col3,
  4771. const std::size_t& col4, const std::size_t& col5,
  4772. const std::size_t& col6, const std::size_t& col7,
  4773. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  4774. T6& t6, T7& t7) const
  4775. {
  4776. if (!process(*(begin_ + col0),t0)) return false;
  4777. if (!process(*(begin_ + col1),t1)) return false;
  4778. if (!process(*(begin_ + col2),t2)) return false;
  4779. if (!process(*(begin_ + col3),t3)) return false;
  4780. if (!process(*(begin_ + col4),t4)) return false;
  4781. if (!process(*(begin_ + col5),t5)) return false;
  4782. if (!process(*(begin_ + col6),t6)) return false;
  4783. if (!process(*(begin_ + col7),t7)) return false;
  4784. return true;
  4785. }
  4786. template <typename T0, typename T1, typename T2, typename T3,
  4787. typename T4, typename T5, typename T6>
  4788. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4789. const std::size_t& col2, const std::size_t& col3,
  4790. const std::size_t& col4, const std::size_t& col5,
  4791. const std::size_t& col6,
  4792. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  4793. T6& t6) const
  4794. {
  4795. if (!process(*(begin_ + col0),t0)) return false;
  4796. if (!process(*(begin_ + col1),t1)) return false;
  4797. if (!process(*(begin_ + col2),t2)) return false;
  4798. if (!process(*(begin_ + col3),t3)) return false;
  4799. if (!process(*(begin_ + col4),t4)) return false;
  4800. if (!process(*(begin_ + col5),t5)) return false;
  4801. if (!process(*(begin_ + col6),t6)) return false;
  4802. return true;
  4803. }
  4804. template <typename T0, typename T1, typename T2, typename T3,
  4805. typename T4, typename T5>
  4806. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4807. const std::size_t& col2, const std::size_t& col3,
  4808. const std::size_t& col4, const std::size_t& col5,
  4809. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const
  4810. {
  4811. if (!process(*(begin_ + col0),t0)) return false;
  4812. if (!process(*(begin_ + col1),t1)) return false;
  4813. if (!process(*(begin_ + col2),t2)) return false;
  4814. if (!process(*(begin_ + col3),t3)) return false;
  4815. if (!process(*(begin_ + col4),t4)) return false;
  4816. if (!process(*(begin_ + col5),t5)) return false;
  4817. return true;
  4818. }
  4819. template <typename T0, typename T1, typename T2, typename T3, typename T4>
  4820. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4821. const std::size_t& col2, const std::size_t& col3,
  4822. const std::size_t& col4,
  4823. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4) const
  4824. {
  4825. if (!process(*(begin_ + col0),t0)) return false;
  4826. if (!process(*(begin_ + col1),t1)) return false;
  4827. if (!process(*(begin_ + col2),t2)) return false;
  4828. if (!process(*(begin_ + col3),t3)) return false;
  4829. if (!process(*(begin_ + col4),t4)) return false;
  4830. return true;
  4831. }
  4832. template <typename T0, typename T1, typename T2, typename T3>
  4833. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4834. const std::size_t& col2, const std::size_t& col3,
  4835. T0& t0, T1& t1, T2& t2, T3& t3) const
  4836. {
  4837. if (!process(*(begin_ + col0),t0)) return false;
  4838. if (!process(*(begin_ + col1),t1)) return false;
  4839. if (!process(*(begin_ + col2),t2)) return false;
  4840. if (!process(*(begin_ + col3),t3)) return false;
  4841. return true;
  4842. }
  4843. template <typename T0, typename T1, typename T2>
  4844. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4845. const std::size_t& col2,
  4846. T0& t0, T1& t1, T2& t2) const
  4847. {
  4848. if (!process(*(begin_ + col0),t0)) return false;
  4849. if (!process(*(begin_ + col1),t1)) return false;
  4850. if (!process(*(begin_ + col2),t2)) return false;
  4851. return true;
  4852. }
  4853. template <typename T0, typename T1>
  4854. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4855. T0& t0, T1& t1) const
  4856. {
  4857. if (!process(*(begin_ + col0),t0)) return false;
  4858. if (!process(*(begin_ + col1),t1)) return false;
  4859. return true;
  4860. }
  4861. template <typename T>
  4862. inline bool parse_with_index(const std::size_t& col, T& t) const
  4863. {
  4864. return process(*(begin_ + col),t);
  4865. }
  4866. template <typename T0, typename T1, typename T2, typename T3,
  4867. typename T4, typename T5, typename T6, typename T7,
  4868. typename T8, typename T9 >
  4869. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  4870. T4& t4, T5& t5, T6& t6, T7& t7,
  4871. T8& t8, T9& t9) const
  4872. {
  4873. if (!process(*(begin_ + 0),t0)) return false;
  4874. if (!process(*(begin_ + 1),t1)) return false;
  4875. if (!process(*(begin_ + 2),t2)) return false;
  4876. if (!process(*(begin_ + 3),t3)) return false;
  4877. if (!process(*(begin_ + 4),t4)) return false;
  4878. if (!process(*(begin_ + 5),t5)) return false;
  4879. if (!process(*(begin_ + 6),t6)) return false;
  4880. if (!process(*(begin_ + 7),t7)) return false;
  4881. if (!process(*(begin_ + 8),t8)) return false;
  4882. if (!process(*(begin_ + 9),t9)) return false;
  4883. return true;
  4884. }
  4885. template <typename T0, typename T1, typename T2, typename T3,
  4886. typename T4, typename T5, typename T6, typename T7,
  4887. typename T8>
  4888. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  4889. T4& t4, T5& t5, T6& t6, T7& t7,
  4890. T8& t8) const
  4891. {
  4892. if (!process(*(begin_ + 0),t0)) return false;
  4893. if (!process(*(begin_ + 1),t1)) return false;
  4894. if (!process(*(begin_ + 2),t2)) return false;
  4895. if (!process(*(begin_ + 3),t3)) return false;
  4896. if (!process(*(begin_ + 4),t4)) return false;
  4897. if (!process(*(begin_ + 5),t5)) return false;
  4898. if (!process(*(begin_ + 6),t6)) return false;
  4899. if (!process(*(begin_ + 7),t7)) return false;
  4900. if (!process(*(begin_ + 8),t8)) return false;
  4901. return true;
  4902. }
  4903. template <typename T0, typename T1, typename T2, typename T3,
  4904. typename T4, typename T5, typename T6, typename T7>
  4905. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  4906. T4& t4, T5& t5, T6& t6, T7& t7) const
  4907. {
  4908. if (!process(*(begin_ + 0),t0)) return false;
  4909. if (!process(*(begin_ + 1),t1)) return false;
  4910. if (!process(*(begin_ + 2),t2)) return false;
  4911. if (!process(*(begin_ + 3),t3)) return false;
  4912. if (!process(*(begin_ + 4),t4)) return false;
  4913. if (!process(*(begin_ + 5),t5)) return false;
  4914. if (!process(*(begin_ + 6),t6)) return false;
  4915. if (!process(*(begin_ + 7),t7)) return false;
  4916. return true;
  4917. }
  4918. template <typename T0, typename T1, typename T2, typename T3,
  4919. typename T4, typename T5, typename T6>
  4920. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  4921. T4& t4, T5& t5, T6& t6) const
  4922. {
  4923. if (!process(*(begin_ + 0),t0)) return false;
  4924. if (!process(*(begin_ + 1),t1)) return false;
  4925. if (!process(*(begin_ + 2),t2)) return false;
  4926. if (!process(*(begin_ + 3),t3)) return false;
  4927. if (!process(*(begin_ + 4),t4)) return false;
  4928. if (!process(*(begin_ + 5),t5)) return false;
  4929. if (!process(*(begin_ + 6),t6)) return false;
  4930. return true;
  4931. }
  4932. template <typename T0, typename T1, typename T2, typename T3,
  4933. typename T4, typename T5>
  4934. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  4935. T4& t4, T5& t5) const
  4936. {
  4937. if (!process(*(begin_ + 0),t0)) return false;
  4938. if (!process(*(begin_ + 1),t1)) return false;
  4939. if (!process(*(begin_ + 2),t2)) return false;
  4940. if (!process(*(begin_ + 3),t3)) return false;
  4941. if (!process(*(begin_ + 4),t4)) return false;
  4942. if (!process(*(begin_ + 5),t5)) return false;
  4943. return true;
  4944. }
  4945. template <typename T0, typename T1,
  4946. typename T2, typename T3,typename T4>
  4947. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3, T4& t4) const
  4948. {
  4949. if (!process(*(begin_ + 0),t0)) return false;
  4950. if (!process(*(begin_ + 1),t1)) return false;
  4951. if (!process(*(begin_ + 2),t2)) return false;
  4952. if (!process(*(begin_ + 3),t3)) return false;
  4953. if (!process(*(begin_ + 4),t4)) return false;
  4954. return true;
  4955. }
  4956. template <typename T0, typename T1,
  4957. typename T2, typename T3>
  4958. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3) const
  4959. {
  4960. if (!process(*(begin_ + 0),t0)) return false;
  4961. if (!process(*(begin_ + 1),t1)) return false;
  4962. if (!process(*(begin_ + 2),t2)) return false;
  4963. if (!process(*(begin_ + 3),t3)) return false;
  4964. return true;
  4965. }
  4966. template <typename T0, typename T1, typename T2>
  4967. inline bool parse(T0& t0, T1& t1, T2& t2) const
  4968. {
  4969. if (!process(*(begin_ + 0),t0)) return false;
  4970. if (!process(*(begin_ + 1),t1)) return false;
  4971. if (!process(*(begin_ + 2),t2)) return false;
  4972. return true;
  4973. }
  4974. template <typename T0, typename T1>
  4975. inline bool parse(T0& t0, T1& t1) const
  4976. {
  4977. if (!process(*(begin_ + 0),t0)) return false;
  4978. if (!process(*(begin_ + 1),t1)) return false;
  4979. return true;
  4980. }
  4981. template <typename T0>
  4982. inline bool parse(T0& t) const
  4983. {
  4984. return process(*begin_,t);
  4985. }
  4986. template <typename T, typename OutputIterator>
  4987. inline void parse(OutputIterator out) const
  4988. {
  4989. token_list_t::const_iterator itr = begin_;
  4990. const token_list_t::const_iterator end = begin_ + size_;
  4991. while (end != itr)
  4992. {
  4993. const range_t& range = (*itr);
  4994. *(out++) = string_to_type_converter<T>(range.first,range.second);
  4995. ++itr;
  4996. }
  4997. }
  4998. bool validate_column_range(const col_range_t& range) const
  4999. {
  5000. if ((range.first > size()) || (range.second > size()))
  5001. return false;
  5002. else if (range.first > range.second)
  5003. return false;
  5004. else
  5005. return true;
  5006. }
  5007. col_range_t range(const std::size_t& lower_bound,
  5008. const std::size_t& upper_bound = std::numeric_limits<std::size_t>::max()) const
  5009. {
  5010. if (std::numeric_limits<std::size_t>::max() != upper_bound)
  5011. return col_range_t(lower_bound,upper_bound);
  5012. else
  5013. return col_range_t(lower_bound,static_cast<index_t>(size()));
  5014. }
  5015. template <typename T,
  5016. typename Allocator,
  5017. template <typename,typename> class Sequence>
  5018. inline bool parse(const col_range_t& range,
  5019. Sequence<T,Allocator>& sequence) const
  5020. {
  5021. if (!validate_column_range(range))
  5022. return false;
  5023. token_list_t::const_iterator itr = (begin_ + range.first);
  5024. token_list_t::const_iterator end = (begin_ + range.second);
  5025. T t;
  5026. while (end != itr)
  5027. {
  5028. const range_t& range = (*itr);
  5029. if (string_to_type_converter(range.first,range.second,t))
  5030. sequence.push_back(t);
  5031. else
  5032. return false;
  5033. ++itr;
  5034. }
  5035. return true;
  5036. }
  5037. template <typename T,
  5038. typename Comparator,
  5039. typename Allocator>
  5040. inline bool parse(const col_range_t& range,
  5041. std::set<T,Comparator,Allocator>& set) const
  5042. {
  5043. if (!validate_column_range(range))
  5044. return false;
  5045. token_list_t::const_iterator itr = (begin_ + range.first);
  5046. token_list_t::const_iterator end = (begin_ + range.second);
  5047. T t;
  5048. while (end != itr)
  5049. {
  5050. const range_t& range = (*itr);
  5051. if (string_to_type_converter(range.first,range.second,t))
  5052. set.insert(t);
  5053. else
  5054. return false;
  5055. ++itr;
  5056. }
  5057. return true;
  5058. }
  5059. template <typename T,
  5060. typename Comparator,
  5061. typename Allocator>
  5062. inline bool parse(const col_range_t& range,
  5063. std::multiset<T,Comparator,Allocator>& multiset) const
  5064. {
  5065. if (!validate_column_range(range))
  5066. return false;
  5067. token_list_t::const_iterator itr = (begin_ + range.first);
  5068. token_list_t::const_iterator end = (begin_ + range.second);
  5069. T t;
  5070. while (end != itr)
  5071. {
  5072. const range_t& range = (*itr);
  5073. if (string_to_type_converter(range.first,range.second,t))
  5074. multiset.insert(t);
  5075. else
  5076. return false;
  5077. ++itr;
  5078. }
  5079. return true;
  5080. }
  5081. template <typename T, typename Container>
  5082. inline bool parse(const col_range_t& range,
  5083. std::queue<T,Container>& queue) const
  5084. {
  5085. if (!validate_column_range(range))
  5086. return false;
  5087. token_list_t::const_iterator itr = (begin_ + range.first);
  5088. token_list_t::const_iterator end = (begin_ + range.second);
  5089. T t;
  5090. while (end != itr)
  5091. {
  5092. const range_t& range = (*itr);
  5093. if (string_to_type_converter(range.first,range.second,t))
  5094. queue.push(t);
  5095. else
  5096. return false;
  5097. ++itr;
  5098. }
  5099. return true;
  5100. }
  5101. template <typename T, typename Container>
  5102. inline bool parse(const col_range_t& range,
  5103. std::stack<T,Container>& stack) const
  5104. {
  5105. if (!validate_column_range(range))
  5106. return false;
  5107. token_list_t::const_iterator itr = (begin_ + range.first);
  5108. token_list_t::const_iterator end = (begin_ + range.second);
  5109. T t;
  5110. while (end != itr)
  5111. {
  5112. const range_t& range = (*itr);
  5113. if (string_to_type_converter(range.first,range.second,t))
  5114. stack.push(t);
  5115. else
  5116. return false;
  5117. ++itr;
  5118. }
  5119. return true;
  5120. }
  5121. template <typename T,
  5122. typename Container,
  5123. typename Comparator>
  5124. inline bool parse(const col_range_t& range,
  5125. std::priority_queue<T,Container,Comparator>& priority_queue) const
  5126. {
  5127. if (!validate_column_range(range))
  5128. return false;
  5129. token_list_t::const_iterator itr = (begin_ + range.first);
  5130. token_list_t::const_iterator end = (begin_ + range.second);
  5131. T t;
  5132. while (end != itr)
  5133. {
  5134. const range_t& range = (*itr);
  5135. if (string_to_type_converter(range.first,range.second,t))
  5136. priority_queue.push(t);
  5137. else
  5138. return false;
  5139. ++itr;
  5140. }
  5141. return true;
  5142. }
  5143. template <typename T,
  5144. typename Allocator,
  5145. template <typename,typename> class Sequence>
  5146. inline bool parse(Sequence<T,Allocator>& sequence) const
  5147. {
  5148. return parse(range(0),sequence);
  5149. }
  5150. template <typename T,
  5151. typename Comparator,
  5152. typename Allocator>
  5153. inline bool parse(std::set<T,Comparator,Allocator>& set) const
  5154. {
  5155. return parse(range(0),set);
  5156. }
  5157. template <typename T,
  5158. typename Comparator,
  5159. typename Allocator>
  5160. inline bool parse(std::multiset<T,Comparator,Allocator>& multiset) const
  5161. {
  5162. return parse(range(0),multiset);
  5163. }
  5164. template <typename T, typename Container>
  5165. inline bool parse(std::queue<T,Container>& queue) const
  5166. {
  5167. return parse(range(0),queue);
  5168. }
  5169. template <typename T, typename Container>
  5170. inline bool parse(std::stack<T,Container>& stack) const
  5171. {
  5172. return parse(range(0),stack);
  5173. }
  5174. template <typename T,
  5175. typename Container,
  5176. typename Comparator>
  5177. inline bool parse(std::priority_queue<T,Container,Comparator>& priority_queue) const
  5178. {
  5179. return parse(range(0),priority_queue);
  5180. }
  5181. template <typename T,
  5182. typename Allocator,
  5183. template <typename,typename> class Sequence>
  5184. inline std::size_t parse_n(const std::size_t& n, Sequence<T,Allocator>& sequence) const
  5185. {
  5186. if (0 == n) return 0;
  5187. T t;
  5188. std::size_t count = 0;
  5189. token_list_t::const_iterator itr = begin_;
  5190. const token_list_t::const_iterator end = begin_ + size_;
  5191. while (end != itr)
  5192. {
  5193. const range_t& range = (*itr);
  5194. if (!string_to_type_converter(range.first,range.second,t))
  5195. return false;
  5196. else
  5197. sequence.push_back(t);
  5198. if (n == (++count))
  5199. break;
  5200. ++itr;
  5201. }
  5202. return count;
  5203. }
  5204. template <typename T, typename OutputIterator>
  5205. inline void parse_checked(OutputIterator out) const
  5206. {
  5207. T value;
  5208. token_list_t::const_iterator itr = begin_;
  5209. const token_list_t::const_iterator end = begin_ + size_;
  5210. while (end != itr)
  5211. {
  5212. const range_t& range = (*itr);
  5213. if (string_to_type_converter(range.first,range.second,value))
  5214. {
  5215. *(out++) = value;
  5216. }
  5217. ++itr;
  5218. }
  5219. }
  5220. template <typename T,
  5221. typename Allocator,
  5222. template <typename,typename> class Sequence>
  5223. inline void parse_checked(Sequence<T,Allocator>& sequence) const
  5224. {
  5225. parse_checked<T>(std::back_inserter(sequence));
  5226. }
  5227. template <typename T,
  5228. typename Comparator,
  5229. typename Allocator>
  5230. inline void parse_checked(std::set<T,Comparator,Allocator>& set) const
  5231. {
  5232. parse_checked<T>(std::inserter(set,set.end()));
  5233. }
  5234. template <typename T,
  5235. typename Comparator,
  5236. typename Allocator>
  5237. inline void parse_checked(std::multiset<T,Comparator,Allocator>& multiset) const
  5238. {
  5239. parse_checked<T>(std::inserter(multiset,multiset.end()));
  5240. }
  5241. template <typename T, typename Container>
  5242. inline void parse_checked(std::queue<T,Container>& queue) const
  5243. {
  5244. parse_checked<T>(push_inserter(queue));
  5245. }
  5246. template <typename T, typename Container>
  5247. inline void parse_checked(std::stack<T,Container>& stack) const
  5248. {
  5249. parse_checked<T>(push_inserter(stack));
  5250. }
  5251. template <typename T,
  5252. typename Container,
  5253. typename Comparator>
  5254. inline void parse_checked(std::priority_queue<T,Container,Comparator>& priority_queue) const
  5255. {
  5256. parse_checked<T>(push_inserter(priority_queue));
  5257. }
  5258. template <typename Function>
  5259. inline std::size_t for_each_column(const col_range_t& range, Function f) const
  5260. {
  5261. if (!validate_column_range(range))
  5262. return false;
  5263. token_list_t::const_iterator itr = begin_ + range.first;
  5264. token_list_t::const_iterator end = begin_ + range.second;
  5265. std::size_t col_count = 0;
  5266. while (end != itr)
  5267. {
  5268. const range_t& range = (*itr);
  5269. f(range);
  5270. ++itr;
  5271. ++col_count;
  5272. }
  5273. return col_count;
  5274. }
  5275. template <typename Function>
  5276. inline std::size_t for_each_column(Function f) const
  5277. {
  5278. return for_each_column(all_columns(),f);
  5279. }
  5280. private:
  5281. template <typename T>
  5282. inline bool process(const range_t& range, T& t) const
  5283. {
  5284. return string_to_type_converter(range.first,range.second,t);
  5285. }
  5286. private:
  5287. std::size_t index_;
  5288. std::size_t size_;
  5289. token_list_t::const_iterator begin_;
  5290. };
  5291. token_grid()
  5292. : file_name_(""),
  5293. buffer_(0),
  5294. buffer_size_(0),
  5295. min_column_count_(0),
  5296. max_column_count_(0),
  5297. load_from_file_(false),
  5298. state_(false)
  5299. {}
  5300. token_grid(const std::string& file_name,
  5301. const token_grid::options& options)
  5302. : file_name_(file_name),
  5303. buffer_(0),
  5304. buffer_size_(0),
  5305. min_column_count_(0),
  5306. max_column_count_(0),
  5307. options_(options),
  5308. load_from_file_(true),
  5309. state_(load())
  5310. {}
  5311. token_grid(const unsigned char* input_buffer,
  5312. const std::size_t& input_buffer_size,
  5313. const token_grid::options& options)
  5314. : file_name_(""),
  5315. buffer_(const_cast<unsigned char*>(input_buffer)),
  5316. buffer_size_(input_buffer_size),
  5317. min_column_count_(0),
  5318. max_column_count_(0),
  5319. options_(options),
  5320. load_from_file_(false),
  5321. state_(load())
  5322. {}
  5323. token_grid(const char* input_buffer,
  5324. const std::size_t& input_buffer_size,
  5325. const token_grid::options& options)
  5326. : file_name_(""),
  5327. buffer_(reinterpret_cast<unsigned char*>(const_cast<char*>(input_buffer))),
  5328. buffer_size_(input_buffer_size),
  5329. min_column_count_(0),
  5330. max_column_count_(0),
  5331. options_(options),
  5332. load_from_file_(false),
  5333. state_(load())
  5334. {}
  5335. token_grid(const std::string& input_buffer,
  5336. const std::size_t& input_buffer_size,
  5337. const token_grid::options& options)
  5338. : file_name_(""),
  5339. buffer_(reinterpret_cast<unsigned char*>(const_cast<char*>(input_buffer.data()))),
  5340. buffer_size_(input_buffer_size),
  5341. min_column_count_(0),
  5342. max_column_count_(0),
  5343. options_(options),
  5344. load_from_file_(false),
  5345. state_(load())
  5346. {}
  5347. token_grid(const std::string& file_name,
  5348. const std::string& column_delimiters = ",|;\t",
  5349. const std::string& row_delimiters = "\n\r")
  5350. : file_name_(file_name),
  5351. buffer_(0),
  5352. buffer_size_(0),
  5353. min_column_count_(0),
  5354. max_column_count_(0),
  5355. options_(split_options::compress_delimiters,
  5356. split_options::compress_delimiters,
  5357. row_delimiters,
  5358. column_delimiters),
  5359. load_from_file_(true),
  5360. state_(load())
  5361. {}
  5362. token_grid(const unsigned char* input_buffer,
  5363. const std::size_t& input_buffer_size,
  5364. const std::string& column_delimiters = ",|;\t",
  5365. const std::string& row_delimiters = "\n\r")
  5366. : file_name_(""),
  5367. buffer_(const_cast<unsigned char*>(input_buffer)),
  5368. buffer_size_(input_buffer_size),
  5369. min_column_count_(0),
  5370. max_column_count_(0),
  5371. options_(split_options::compress_delimiters,
  5372. split_options::compress_delimiters,
  5373. row_delimiters,
  5374. column_delimiters),
  5375. load_from_file_(false),
  5376. state_(load())
  5377. {}
  5378. token_grid(const char* input_buffer,
  5379. const std::size_t& input_buffer_size,
  5380. const std::string& column_delimiters = ",|;\t",
  5381. const std::string& row_delimiters = "\n\r")
  5382. : file_name_(""),
  5383. buffer_(reinterpret_cast<unsigned char*>(const_cast<char*>(input_buffer))),
  5384. buffer_size_(input_buffer_size),
  5385. min_column_count_(0),
  5386. max_column_count_(0),
  5387. options_(split_options::compress_delimiters,
  5388. split_options::compress_delimiters,
  5389. row_delimiters,
  5390. column_delimiters),
  5391. load_from_file_(false),
  5392. state_(load())
  5393. {}
  5394. token_grid(const std::string& input_buffer,
  5395. const std::size_t& input_buffer_size,
  5396. const std::string& column_delimiters = ",;|\t ",
  5397. const std::string& row_delimiters = "\n\r")
  5398. : file_name_(""),
  5399. buffer_(reinterpret_cast<unsigned char*>(const_cast<char*>(input_buffer.data()))),
  5400. buffer_size_(input_buffer_size),
  5401. min_column_count_(0),
  5402. max_column_count_(0),
  5403. options_(split_options::compress_delimiters,
  5404. split_options::compress_delimiters,
  5405. row_delimiters,
  5406. column_delimiters),
  5407. load_from_file_(false),
  5408. state_(load())
  5409. {}
  5410. ~token_grid()
  5411. {
  5412. if ((load_from_file_) && (0 != buffer_))
  5413. {
  5414. delete [] buffer_;
  5415. buffer_ = 0;
  5416. }
  5417. }
  5418. inline bool operator!() const
  5419. {
  5420. return !state_;
  5421. }
  5422. inline std::string source_file() const
  5423. {
  5424. return file_name_;
  5425. }
  5426. inline std::size_t row_count() const
  5427. {
  5428. return dsv_index_.row_index.size();
  5429. }
  5430. inline std::size_t min_column_count() const
  5431. {
  5432. return min_column_count_;
  5433. }
  5434. inline std::size_t max_column_count() const
  5435. {
  5436. return max_column_count_;
  5437. }
  5438. inline range_t token(const unsigned int& row, const std::size_t& col) const
  5439. {
  5440. return dsv_index_(col,row);
  5441. }
  5442. template <typename T>
  5443. inline T get(const unsigned int& row, const std::size_t& col)
  5444. {
  5445. range_t r = token(row,col);
  5446. return string_to_type_converter<T>(r.first,r.second);
  5447. }
  5448. inline row_type row(const unsigned int& row_index) const
  5449. {
  5450. return row_type(row_index,dsv_index_);
  5451. }
  5452. inline row_range_t all_rows() const
  5453. {
  5454. return row_range_t(0,static_cast<index_t>(dsv_index_.row_index.size()));
  5455. }
  5456. template <typename OutputIterator>
  5457. inline bool extract_column_checked(const row_range_t& row_range,
  5458. const std::size_t& index,
  5459. OutputIterator out) const
  5460. {
  5461. if (index > max_column_count_)
  5462. return false;
  5463. else if (row_range_invalid(row_range))
  5464. return false;
  5465. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5466. {
  5467. const row_index_range_t& row = dsv_index_.row_index[i];
  5468. if (index < dsv_index_.token_count(row))
  5469. {
  5470. dsv_index_.token_list.begin() + (row.first + index);
  5471. process_token_checked(*(dsv_index_.token_list.begin() + (row.first + index)),out);
  5472. }
  5473. }
  5474. return true;
  5475. }
  5476. template <typename OutputIterator>
  5477. inline bool extract_column_checked(const std::size_t& index,
  5478. OutputIterator out) const
  5479. {
  5480. return extract_column_checked(all_rows(),index,out);
  5481. }
  5482. template <typename T,
  5483. typename Allocator,
  5484. template <typename,typename> class Sequence>
  5485. inline void extract_column_checked(const std::size_t& index,
  5486. Sequence<T,Allocator>& sequence) const
  5487. {
  5488. extract_column_checked(index,back_inserter_with_valuetype(sequence));
  5489. }
  5490. template <typename T,
  5491. typename Comparator,
  5492. typename Allocator>
  5493. inline void extract_column_checked(const std::size_t& index,
  5494. std::set<T,Comparator,Allocator>& set) const
  5495. {
  5496. extract_column_checked(index,inserter_with_valuetype(set));
  5497. }
  5498. template <typename T,
  5499. typename Comparator,
  5500. typename Allocator>
  5501. inline void extract_column_checked(const std::size_t& index,
  5502. std::multiset<T,Comparator,Allocator>& multiset) const
  5503. {
  5504. extract_column_checked(index,inserter_with_valuetype(multiset));
  5505. }
  5506. template <typename OutputIterator>
  5507. inline bool extract_column(const row_range_t& row_range,
  5508. const std::size_t& index,
  5509. OutputIterator out) const
  5510. {
  5511. if (index > max_column_count_)
  5512. return false;
  5513. else if (row_range_invalid(row_range))
  5514. return false;
  5515. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5516. {
  5517. const row_index_range_t& row = dsv_index_.row_index[i];
  5518. if (index < dsv_index_.token_count(row))
  5519. {
  5520. process_token(*(dsv_index_.token_list.begin() + (row.first + index)),out);
  5521. }
  5522. }
  5523. return true;
  5524. }
  5525. template <typename OutputIterator>
  5526. inline bool extract_column(const std::size_t& index,
  5527. OutputIterator out) const
  5528. {
  5529. return extract_column(all_rows(),index,out);
  5530. }
  5531. template <typename OutputIterator0, typename OutputIterator1>
  5532. inline bool extract_column(const row_range_t& row_range,
  5533. const std::size_t& index0,
  5534. const std::size_t& index1,
  5535. OutputIterator0 out0,
  5536. OutputIterator1 out1) const
  5537. {
  5538. if ((index0 > max_column_count_) ||
  5539. (index1 > max_column_count_))
  5540. return false;
  5541. else if (row_range_invalid(row_range))
  5542. return false;
  5543. std::size_t max_index = std::max(index0,index1);
  5544. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5545. {
  5546. const row_index_range_t& row = dsv_index_.row_index[i];
  5547. if (max_index < dsv_index_.token_count(row))
  5548. {
  5549. process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0);
  5550. process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1);
  5551. }
  5552. }
  5553. return true;
  5554. }
  5555. template <typename OutputIterator0, typename OutputIterator1, typename OutputIterator2>
  5556. inline bool extract_column(const row_range_t& row_range,
  5557. const std::size_t& index0,
  5558. const std::size_t& index1,
  5559. const std::size_t& index2,
  5560. OutputIterator0 out0,
  5561. OutputIterator1 out1,
  5562. OutputIterator2 out2) const
  5563. {
  5564. if ((index0 > max_column_count_) ||
  5565. (index1 > max_column_count_) ||
  5566. (index2 > max_column_count_))
  5567. return false;
  5568. else if (row_range_invalid(row_range))
  5569. return false;
  5570. std::size_t max_index = std::max(index0,std::max(index1,index2));
  5571. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5572. {
  5573. const row_index_range_t& row = dsv_index_.row_index[i];
  5574. if (max_index < dsv_index_.token_count(row))
  5575. {
  5576. process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0);
  5577. process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1);
  5578. process_token(*(dsv_index_.token_list.begin() + (row.first + index2)),out2);
  5579. }
  5580. }
  5581. return true;
  5582. }
  5583. template <typename OutputIterator0, typename OutputIterator1,
  5584. typename OutputIterator2, typename OutputIterator3>
  5585. inline bool extract_column(const row_range_t& row_range,
  5586. const std::size_t& index0,
  5587. const std::size_t& index1,
  5588. const std::size_t& index2,
  5589. const std::size_t& index3,
  5590. OutputIterator0 out0,
  5591. OutputIterator1 out1,
  5592. OutputIterator2 out2,
  5593. OutputIterator3 out3) const
  5594. {
  5595. if ((index0 > max_column_count_) ||
  5596. (index1 > max_column_count_) ||
  5597. (index2 > max_column_count_) ||
  5598. (index3 > max_column_count_))
  5599. return false;
  5600. else if (row_range_invalid(row_range))
  5601. return false;
  5602. std::size_t max_index = std::max(std::max(index0,index1),std::max(index2,index3));
  5603. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5604. {
  5605. const row_index_range_t& row = dsv_index_.row_index[i];
  5606. if (max_index < dsv_index_.token_count(row))
  5607. {
  5608. process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0);
  5609. process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1);
  5610. process_token(*(dsv_index_.token_list.begin() + (row.first + index2)),out2);
  5611. process_token(*(dsv_index_.token_list.begin() + (row.first + index3)),out3);
  5612. }
  5613. }
  5614. return true;
  5615. }
  5616. template <typename OutputIterator0, typename OutputIterator1,
  5617. typename OutputIterator2, typename OutputIterator3,
  5618. typename OutputIterator4>
  5619. inline bool extract_column(const row_range_t& row_range,
  5620. const std::size_t& index0,
  5621. const std::size_t& index1,
  5622. const std::size_t& index2,
  5623. const std::size_t& index3,
  5624. const std::size_t& index4,
  5625. OutputIterator0 out0,
  5626. OutputIterator1 out1,
  5627. OutputIterator2 out2,
  5628. OutputIterator3 out3,
  5629. OutputIterator4 out4) const
  5630. {
  5631. if ((index0 > max_column_count_) ||
  5632. (index1 > max_column_count_) ||
  5633. (index2 > max_column_count_) ||
  5634. (index3 > max_column_count_) ||
  5635. (index4 > max_column_count_))
  5636. return false;
  5637. else if (row_range_invalid(row_range))
  5638. return false;
  5639. std::size_t max_index = std::max(index4,std::max(std::max(index0,index1),std::max(index2,index3)));
  5640. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5641. {
  5642. const row_index_range_t& row = dsv_index_.row_index[i];
  5643. if (max_index < dsv_index_.token_count(row))
  5644. {
  5645. process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0);
  5646. process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1);
  5647. process_token(*(dsv_index_.token_list.begin() + (row.first + index2)),out2);
  5648. process_token(*(dsv_index_.token_list.begin() + (row.first + index3)),out3);
  5649. process_token(*(dsv_index_.token_list.begin() + (row.first + index4)),out4);
  5650. }
  5651. }
  5652. return true;
  5653. }
  5654. inline void remove_row(const std::size_t& index)
  5655. {
  5656. if (index < dsv_index_.row_index.size())
  5657. {
  5658. dsv_index_.remove_row(index);
  5659. }
  5660. }
  5661. template <typename Predicate>
  5662. inline bool remove_row_if(const row_range_t& row_range, Predicate predicate)
  5663. {
  5664. if (row_range_invalid(row_range))
  5665. return false;
  5666. std::size_t removed_token_count = 0;
  5667. std::deque<std::size_t> remove_token_list;
  5668. std::deque<std::size_t> remove_row_list;
  5669. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5670. {
  5671. row_index_range_t& r = dsv_index_.row_index[i];
  5672. std::size_t temp_r_first = r.first - removed_token_count;
  5673. row_type row(i,dsv_index_);
  5674. if (predicate(row))
  5675. {
  5676. remove_row_list.push_back(i);
  5677. for (std::size_t j = r.first; j <= r.second; ++j)
  5678. {
  5679. remove_token_list.push_back(j);
  5680. }
  5681. removed_token_count += row.size();
  5682. }
  5683. r.first = static_cast<unsigned int>(temp_r_first);
  5684. r.second -= static_cast<unsigned int>(removed_token_count);
  5685. }
  5686. for (std::size_t i = row_range.second; i < dsv_index_.row_index.size(); ++i)
  5687. {
  5688. row_index_range_t& r = dsv_index_.row_index[i];
  5689. r.first -= static_cast<unsigned int>(removed_token_count);
  5690. r.second -= static_cast<unsigned int>(removed_token_count);
  5691. }
  5692. if (!remove_row_list.empty())
  5693. {
  5694. remove_inplace(index_remover(remove_row_list),dsv_index_.row_index);
  5695. }
  5696. if (!remove_token_list.empty())
  5697. {
  5698. remove_inplace(index_remover(remove_token_list),dsv_index_.token_list);
  5699. }
  5700. return true;
  5701. }
  5702. template <typename Predicate>
  5703. inline bool remove_row_if(Predicate predicate)
  5704. {
  5705. return remove_row_if(all_rows(),predicate);
  5706. }
  5707. template <typename Predicate>
  5708. inline std::size_t remove_token_if(const row_range_t& row_range, Predicate predicate)
  5709. {
  5710. if (row_range_invalid(row_range))
  5711. return 0;
  5712. std::size_t removed_token_count = 0;
  5713. std::deque<std::size_t> remove_token_list;
  5714. std::deque<std::size_t> remove_row_list;
  5715. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5716. {
  5717. row_index_range_t& r = dsv_index_.row_index[i];
  5718. std::size_t temp_r_first = r.first - removed_token_count;
  5719. row_type row(i,dsv_index_);
  5720. for (std::size_t j = 0; j < row.size(); ++j)
  5721. {
  5722. if (predicate(row.token(j)))
  5723. {
  5724. remove_token_list.push_back(r.first + j);
  5725. ++removed_token_count;
  5726. }
  5727. }
  5728. r.first = static_cast<unsigned int>(temp_r_first);
  5729. r.second -= static_cast<unsigned int>(removed_token_count);
  5730. if (0 == dsv_index_.token_count(r))
  5731. {
  5732. remove_row_list.push_back(i);
  5733. }
  5734. }
  5735. for (std::size_t i = row_range.second; i < dsv_index_.row_index.size(); ++i)
  5736. {
  5737. row_index_range_t& r = dsv_index_.row_index[i];
  5738. r.first -= static_cast<unsigned int>(removed_token_count);
  5739. r.second -= static_cast<unsigned int>(removed_token_count);
  5740. }
  5741. if (!remove_row_list.empty())
  5742. {
  5743. remove_inplace(index_remover(remove_row_list),dsv_index_.row_index);
  5744. }
  5745. if (!remove_token_list.empty())
  5746. {
  5747. remove_inplace(index_remover(remove_token_list),dsv_index_.token_list);
  5748. }
  5749. if (!remove_token_list.empty())
  5750. {
  5751. update_minmax_columns();
  5752. }
  5753. return remove_token_list.size();
  5754. }
  5755. inline std::size_t remove_empty_tokens(const row_range_t& range)
  5756. {
  5757. return remove_token_if(range,is_empty_token());
  5758. }
  5759. inline std::size_t remove_empty_tokens()
  5760. {
  5761. return remove_empty_tokens(all_rows());
  5762. }
  5763. inline void enforce_column_count(const row_range_t& row_range,
  5764. const std::size_t& column_count)
  5765. {
  5766. if (row_range_invalid(row_range))
  5767. return;
  5768. remove_row_if(insufficient_number_of_columns(column_count));
  5769. min_column_count_ = column_count;
  5770. max_column_count_ = column_count;
  5771. }
  5772. inline void enforce_column_count(const std::size_t& column_count)
  5773. {
  5774. enforce_column_count(all_rows(),column_count);
  5775. }
  5776. inline void enforce_min_max_column_count(const row_range_t& row_range,
  5777. const std::size_t& min_column_count,
  5778. const std::size_t& max_column_count)
  5779. {
  5780. if (row_range_invalid(row_range))
  5781. return;
  5782. remove_row_if(insufficient_number_of_minmax_columns(min_column_count,max_column_count));
  5783. min_column_count_ = min_column_count;
  5784. max_column_count_ = max_column_count;
  5785. }
  5786. inline void enforce_min_max_column_count(const std::size_t& min_column_count,
  5787. const std::size_t& max_column_count)
  5788. {
  5789. enforce_min_max_column_count(all_rows(),min_column_count,max_column_count);
  5790. }
  5791. inline void clear(const bool force_delete_buffer = false)
  5792. {
  5793. if (load_from_file_ || force_delete_buffer)
  5794. delete[] buffer_;
  5795. buffer_ = 0;
  5796. buffer_size_ = 0;
  5797. dsv_index_.clear();
  5798. min_column_count_ = 0;
  5799. max_column_count_ = 0;
  5800. state_ = false;
  5801. file_name_ = "";
  5802. }
  5803. template <typename T>
  5804. inline std::size_t accumulate_row(const std::size_t& row, T& result) const
  5805. {
  5806. if (row >= dsv_index_.row_index.size())
  5807. return 0;
  5808. const row_index_range_t& r = dsv_index_.row_index[row];
  5809. token_list_t::const_iterator itr = dsv_index_.token_list.begin() + r.first;
  5810. token_list_t::const_iterator end = dsv_index_.token_list.begin() + r.second + 1;
  5811. std::size_t process_count = 0;
  5812. T current_value = T();
  5813. while (end != itr)
  5814. {
  5815. if (string_to_type_converter((*itr).first,(*itr).second,current_value))
  5816. {
  5817. result += current_value;
  5818. ++process_count;
  5819. }
  5820. else
  5821. return 0;
  5822. ++itr;
  5823. }
  5824. return process_count;
  5825. }
  5826. template <typename T>
  5827. inline std::size_t accumulate_column(const std::size_t& col,
  5828. const row_range_t& row_range,
  5829. T& result) const
  5830. {
  5831. if (col > max_column_count_)
  5832. return 0;
  5833. else if (row_range_invalid(row_range))
  5834. return 0;
  5835. std::size_t process_count = 0;
  5836. T current_value = T();
  5837. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5838. {
  5839. const row_index_range_t& r = dsv_index_.row_index[i];
  5840. if (col < dsv_index_.token_count(r))
  5841. {
  5842. const range_t& range = *(dsv_index_.token_list.begin() + r.first + col);
  5843. if (string_to_type_converter(range.first,range.second,current_value))
  5844. result += current_value;
  5845. else
  5846. return 0;
  5847. }
  5848. ++process_count;
  5849. }
  5850. return process_count;
  5851. }
  5852. template <typename T>
  5853. inline std::size_t accumulate_column(const std::size_t& col, T& result) const
  5854. {
  5855. return accumulate_column(col,all_rows(),result);
  5856. }
  5857. template <typename T, typename Predicate>
  5858. inline std::size_t accumulate_column(const std::size_t& col,
  5859. const row_range_t& row_range,
  5860. Predicate p,
  5861. T& result) const
  5862. {
  5863. if (col > max_column_count_)
  5864. return 0;
  5865. else if (row_range_invalid(row_range))
  5866. return 0;
  5867. std::size_t process_count = 0;
  5868. T current_value = T();
  5869. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5870. {
  5871. const row_index_range_t& r = dsv_index_.row_index[i];
  5872. if (col < dsv_index_.token_count(r))
  5873. {
  5874. row_type row = row_type(i,dsv_index_);
  5875. if (p(row))
  5876. {
  5877. const range_t& range = row.token(col);
  5878. if (string_to_type_converter(range.first,range.second,current_value))
  5879. {
  5880. result += current_value;
  5881. ++process_count;
  5882. }
  5883. else
  5884. return 0;
  5885. }
  5886. }
  5887. }
  5888. return process_count;
  5889. }
  5890. template <typename T, typename Predicate>
  5891. inline std::size_t accumulate_column(const std::size_t& col,
  5892. Predicate p,
  5893. T& result) const
  5894. {
  5895. return accumulate_column(col,all_rows(),p,result);
  5896. }
  5897. inline bool join_row(const std::size_t& row,
  5898. const std::string& delimiter,
  5899. std::string& result)
  5900. {
  5901. if (row >= dsv_index_.row_index.size())
  5902. return false;
  5903. const row_index_range_t& r = dsv_index_.row_index[row];
  5904. token_list_t::const_iterator itr = dsv_index_.token_list.begin() + r.first;
  5905. token_list_t::const_iterator end = dsv_index_.token_list.begin() + r.second + (row < (dsv_index_.row_index.size() - 1) ? 1 : 0);
  5906. result.reserve(delimiter.size() * dsv_index_.token_count(r) + std::distance(itr->first,end->second));
  5907. bool appended = false;
  5908. while (end != itr)
  5909. {
  5910. if (!delimiter.empty() && appended)
  5911. result.append(delimiter);
  5912. appended = false;
  5913. if ((*itr).first != (*itr).second)
  5914. {
  5915. result.append((*itr).first,(*itr).second);
  5916. appended = true;
  5917. }
  5918. ++itr;
  5919. }
  5920. return true;
  5921. }
  5922. template <typename Predicate>
  5923. inline bool join_row(const std::size_t& row,
  5924. Predicate predicate,
  5925. const std::string& delimiter,
  5926. std::string& result)
  5927. {
  5928. if (row >= dsv_index_.row_index.size())
  5929. return false;
  5930. const row_index_range_t& r = dsv_index_.row_index[row];
  5931. token_list_t::const_iterator itr = (dsv_index_.token_list.begin() + r.first);
  5932. token_list_t::const_iterator end = dsv_index_.token_list.begin() + r.second + (row < (dsv_index_.row_index.size() - 1) ? 1 : 0);
  5933. result.reserve(delimiter.size() * dsv_index_.token_count(r) + std::distance(itr->first,end->second));
  5934. bool appended = false;
  5935. while (end != itr)
  5936. {
  5937. if (!delimiter.empty() && appended)
  5938. result.append(delimiter);
  5939. appended = false;
  5940. if ((*itr).first != (*itr).second)
  5941. {
  5942. if (predicate(*itr))
  5943. {
  5944. result.append((*itr).first,(*itr).second);
  5945. appended = true;
  5946. }
  5947. }
  5948. ++itr;
  5949. }
  5950. return true;
  5951. }
  5952. template <typename Predicate>
  5953. inline bool join_row(const std::size_t& row,
  5954. Predicate predicate,
  5955. const char* delimiter,
  5956. std::string& result)
  5957. {
  5958. return join_row(row,predicate,std::string(delimiter),result);
  5959. }
  5960. inline bool join_column(const std::size_t& col,
  5961. const row_range_t& row_range,
  5962. const std::string& delimiter,
  5963. std::string& result) const
  5964. {
  5965. if (col > max_column_count_)
  5966. return false;
  5967. else if (row_range_invalid(row_range))
  5968. return false;
  5969. bool appended = false;
  5970. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5971. {
  5972. const row_index_range_t& r = dsv_index_.row_index[i];
  5973. if (col < dsv_index_.token_count(r))
  5974. {
  5975. row_type row = row_type(i,dsv_index_);
  5976. const range_t& range = row.token(col);
  5977. if (!delimiter.empty() && appended)
  5978. result.append(delimiter);
  5979. appended = false;
  5980. if (range.first != range.second)
  5981. {
  5982. result.append(range.first,range.second);
  5983. appended = true;
  5984. }
  5985. }
  5986. }
  5987. return true;
  5988. }
  5989. inline bool join_column(const std::size_t& col,
  5990. const std::string& delimiter,
  5991. std::string& result) const
  5992. {
  5993. return join_column(col,all_rows(),delimiter,result);
  5994. }
  5995. template <typename Predicate>
  5996. inline bool join_column(const std::size_t& col,
  5997. const row_range_t& row_range,
  5998. Predicate predicate,
  5999. const std::string& delimiter,
  6000. std::string& result) const
  6001. {
  6002. if (col > max_column_count_)
  6003. return false;
  6004. else if (row_range_invalid(row_range))
  6005. return false;
  6006. bool appended = false;
  6007. const std::size_t pre_end_index = row_range.second - 1;
  6008. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  6009. {
  6010. const row_index_range_t& r = dsv_index_.row_index[i];
  6011. if (col < dsv_index_.token_count(r))
  6012. {
  6013. row_type row = row_type(i,dsv_index_);
  6014. const range_t& range = row.token(col);
  6015. if (!delimiter.empty() && appended && (pre_end_index != i))
  6016. result.append(delimiter);
  6017. appended = false;
  6018. if (range.first != range.second)
  6019. {
  6020. if (predicate(row))
  6021. {
  6022. result.append(range.first,range.second);
  6023. appended = true;
  6024. }
  6025. }
  6026. }
  6027. }
  6028. return true;
  6029. }
  6030. template <typename Predicate>
  6031. inline bool join_column(const std::size_t& col,
  6032. Predicate p,
  6033. const std::string& delimiter,
  6034. std::string& result) const
  6035. {
  6036. return join_column(col,all_rows(),p,delimiter,result);
  6037. }
  6038. template <typename TransitionPredicate, typename Function>
  6039. inline bool sequential_partition(const row_range_t& row_range,
  6040. TransitionPredicate p,
  6041. Function f)
  6042. {
  6043. if (row_range_invalid(row_range))
  6044. return false;
  6045. row_range_t r(row_range.first,row_range.first);
  6046. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  6047. {
  6048. if (p(row_type(i,dsv_index_)))
  6049. {
  6050. if (r.first != r.second)
  6051. {
  6052. r.second = i;
  6053. if (!f(*this,r))
  6054. return false;
  6055. }
  6056. r.first = r.second;
  6057. }
  6058. else
  6059. r.second = i;
  6060. }
  6061. if (r.first != row_range.second)
  6062. {
  6063. r.second = row_range.second;
  6064. if (!f(*this,r))
  6065. return false;
  6066. }
  6067. return true;
  6068. }
  6069. template <typename TransitionPredicate, typename Function>
  6070. inline bool sequential_partition(TransitionPredicate p, Function f)
  6071. {
  6072. return sequential_partition(all_rows(),p,f);
  6073. }
  6074. static inline token_grid::options default_options()
  6075. {
  6076. return options();
  6077. }
  6078. template <typename Function>
  6079. inline std::size_t for_each_row(const row_range_t& row_range, Function f) const
  6080. {
  6081. if (row_range_invalid(row_range))
  6082. return 0;
  6083. std::size_t row_count = 0;
  6084. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  6085. {
  6086. f(row_type(i,dsv_index_));
  6087. ++row_count;
  6088. }
  6089. return row_count;
  6090. }
  6091. template <typename Function>
  6092. inline std::size_t for_each_row(Function f) const
  6093. {
  6094. return for_each_row(all_rows(),f);
  6095. }
  6096. bool load(const std::string& file_name,
  6097. const token_grid::options& options)
  6098. {
  6099. file_name_ = file_name;
  6100. if ((load_from_file_) && (0 != buffer_))
  6101. {
  6102. delete [] buffer_;
  6103. buffer_ = 0;
  6104. }
  6105. buffer_size_ = 0;
  6106. min_column_count_ = 0;
  6107. max_column_count_ = 0;
  6108. options_ = options;
  6109. load_from_file_ = true;
  6110. state_ = load();
  6111. if (state_)
  6112. return true;
  6113. else
  6114. {
  6115. file_name_ = "";
  6116. if ((load_from_file_) && (0 != buffer_))
  6117. {
  6118. delete [] buffer_;
  6119. buffer_ = 0;
  6120. }
  6121. return false;
  6122. }
  6123. }
  6124. bool load(unsigned char* buffer,
  6125. const std::size_t buffer_size,
  6126. const token_grid::options& options)
  6127. {
  6128. file_name_ = "";
  6129. if ((load_from_file_) && (0 != buffer_))
  6130. {
  6131. delete [] buffer_;
  6132. buffer_ = 0;
  6133. }
  6134. min_column_count_ = 0;
  6135. max_column_count_ = 0;
  6136. options_ = options;
  6137. load_from_file_ = false;
  6138. buffer_ = buffer;
  6139. buffer_size_ = buffer_size;
  6140. state_ = load();
  6141. if (state_)
  6142. return true;
  6143. else
  6144. {
  6145. file_name_ = "";
  6146. if ((load_from_file_) && (0 != buffer_))
  6147. {
  6148. delete [] buffer_;
  6149. buffer_ = 0;
  6150. }
  6151. return false;
  6152. }
  6153. }
  6154. private:
  6155. token_grid(const token_grid& tg);
  6156. token_grid& operator=(const token_grid& tg);
  6157. struct is_empty_token
  6158. {
  6159. inline bool operator()(const range_t& r) const
  6160. {
  6161. return r.first == r.second;
  6162. }
  6163. };
  6164. struct insufficient_number_of_columns
  6165. {
  6166. insufficient_number_of_columns(const std::size_t& noc)
  6167. : num_of_cols(noc)
  6168. {}
  6169. inline bool operator()(const row_type& row) const
  6170. {
  6171. return (num_of_cols != row.size());
  6172. }
  6173. std::size_t num_of_cols;
  6174. };
  6175. struct insufficient_number_of_minmax_columns
  6176. {
  6177. insufficient_number_of_minmax_columns(const std::size_t& min_col, const std::size_t& max_col)
  6178. : min_column_count(min_col),
  6179. max_column_count(max_col)
  6180. {}
  6181. inline bool operator()(const row_type& row) const
  6182. {
  6183. return (row.size() < min_column_count) || (max_column_count < row.size());
  6184. }
  6185. std::size_t min_column_count;
  6186. std::size_t max_column_count;
  6187. };
  6188. class double_quotes_predicate
  6189. {
  6190. public:
  6191. double_quotes_predicate(const std::string& delimiters)
  6192. : in_bracket_range_(false),
  6193. mdp_(delimiters)
  6194. {}
  6195. inline bool operator()(const unsigned char c) const
  6196. {
  6197. if ('"' == c)
  6198. {
  6199. in_bracket_range_ = !in_bracket_range_;
  6200. return true;
  6201. }
  6202. else if (in_bracket_range_)
  6203. return false;
  6204. else
  6205. return mdp_(c);
  6206. }
  6207. inline void reset()
  6208. {
  6209. in_bracket_range_ = false;
  6210. }
  6211. private:
  6212. mutable bool in_bracket_range_;
  6213. mutable strtk::multiple_char_delimiter_predicate mdp_;
  6214. };
  6215. inline bool load()
  6216. {
  6217. if (load_from_file_ && !load_buffer_from_file())
  6218. return false;
  6219. dsv_index_.token_list.clear();
  6220. dsv_index_.row_index.clear();
  6221. multiple_char_delimiter_predicate text_newline_predicate(options_.row_delimiters);
  6222. if (!options_.support_dquotes)
  6223. {
  6224. multiple_char_delimiter_predicate token_predicate(options_.column_delimiters);
  6225. strtk::split(text_newline_predicate,
  6226. buffer_, buffer_ + buffer_size_,
  6227. strtk::functional_inserter(
  6228. row_processor<multiple_char_delimiter_predicate>(dsv_index_,token_predicate,options_.column_split_option)),
  6229. strtk::split_options::compress_delimiters);
  6230. }
  6231. else
  6232. {
  6233. double_quotes_predicate token_predicate_dblq(options_.column_delimiters);
  6234. strtk::split(text_newline_predicate,
  6235. buffer_, buffer_ + buffer_size_,
  6236. strtk::functional_inserter(
  6237. row_processor<double_quotes_predicate>(dsv_index_,token_predicate_dblq,options_.column_split_option)),
  6238. strtk::split_options::compress_delimiters);
  6239. }
  6240. update_minmax_columns();
  6241. return true;
  6242. }
  6243. inline bool load_buffer_from_file()
  6244. {
  6245. std::ifstream stream(file_name_.c_str(),std::ios::binary);
  6246. if (!stream)
  6247. return false;
  6248. stream.seekg (0,std::ios::end);
  6249. buffer_size_ = static_cast<std::size_t>(stream.tellg());
  6250. if (0 == buffer_size_)
  6251. return false;
  6252. stream.seekg (0,std::ios::beg);
  6253. buffer_ = new unsigned char[buffer_size_];
  6254. stream.read(reinterpret_cast<char*>(buffer_),static_cast<std::streamsize>(buffer_size_));
  6255. stream.close();
  6256. return true;
  6257. }
  6258. template <typename OutputIterator>
  6259. inline void process_token(const range_t& range, OutputIterator out) const
  6260. {
  6261. typedef typename std::iterator_traits<OutputIterator>::value_type output_type;
  6262. (*out) = string_to_type_converter<output_type>(range.first,range.second);
  6263. ++out;
  6264. }
  6265. template <typename OutputIterator>
  6266. inline void process_token_checked(const range_t& range, OutputIterator out) const
  6267. {
  6268. typedef typename std::iterator_traits<OutputIterator>::value_type output_type;
  6269. output_type value;
  6270. if (string_to_type_converter(range.first,range.second,value))
  6271. {
  6272. (*out) = value;
  6273. ++out;
  6274. }
  6275. }
  6276. inline bool row_range_invalid(const row_range_t& row_range) const
  6277. {
  6278. if (row_range.first > dsv_index_.row_index.size())
  6279. return true;
  6280. else if (row_range.second > dsv_index_.row_index.size())
  6281. return true;
  6282. else if (row_range.first > row_range.second)
  6283. return true;
  6284. else
  6285. return false;
  6286. }
  6287. inline void update_minmax_columns()
  6288. {
  6289. min_column_count_ = std::numeric_limits<std::size_t>::max();
  6290. max_column_count_ = std::numeric_limits<std::size_t>::min();
  6291. for (std::size_t i = 0; i < dsv_index_.row_index.size(); ++i)
  6292. {
  6293. const row_index_range_t& r = dsv_index_.row_index[i];
  6294. const std::size_t number_of_tokens = dsv_index_.token_count(r);
  6295. if (number_of_tokens > max_column_count_)
  6296. max_column_count_ = number_of_tokens;
  6297. if (number_of_tokens < min_column_count_)
  6298. min_column_count_ = number_of_tokens;
  6299. }
  6300. }
  6301. private:
  6302. store dsv_index_;
  6303. std::string file_name_;
  6304. unsigned char* buffer_;
  6305. std::size_t buffer_size_;
  6306. std::size_t min_column_count_;
  6307. std::size_t max_column_count_;
  6308. options options_;
  6309. bool load_from_file_;
  6310. bool state_;
  6311. };
  6312. template <typename T>
  6313. inline bool convert_string_range(const std::pair<std::string::const_iterator,std::string::const_iterator>& range, T& t)
  6314. {
  6315. if (range.first == range.second) return false;
  6316. t = string_to_type_converter<T>(std::string(range.first,range.second));
  6317. return true;
  6318. }
  6319. struct empty_range
  6320. {
  6321. public:
  6322. template <typename InputIterator>
  6323. inline bool operator()(const InputIterator begin, const InputIterator end)
  6324. {
  6325. return (0 == std::distance(begin,end));
  6326. }
  6327. };
  6328. struct nonempty_range
  6329. {
  6330. public:
  6331. template <typename InputIterator>
  6332. inline bool operator()(const InputIterator begin, const InputIterator end)
  6333. {
  6334. return (0 != std::distance(begin,end));
  6335. }
  6336. };
  6337. template <typename OutputIterator>
  6338. struct filter_non_empty_range
  6339. {
  6340. public:
  6341. filter_non_empty_range(OutputIterator out)
  6342. : out_(out)
  6343. {}
  6344. template <typename Iterator>
  6345. inline void operator() (const std::pair<Iterator,Iterator>& range)
  6346. {
  6347. if (range.first != range.second)
  6348. {
  6349. *out_++ = range;
  6350. }
  6351. }
  6352. private:
  6353. OutputIterator out_;
  6354. };
  6355. template <typename OutputPredicate>
  6356. struct filter_on_wildcard_match
  6357. {
  6358. public:
  6359. filter_on_wildcard_match(const std::string& match_pattern,
  6360. OutputPredicate& predicate,
  6361. bool allow_through_on_match = true)
  6362. : allow_through_on_match_(allow_through_on_match),
  6363. match_pattern_(match_pattern),
  6364. predicate_(predicate)
  6365. {}
  6366. template <typename Iterator>
  6367. inline void operator() (const std::pair<Iterator,Iterator>& range) const
  6368. {
  6369. if (match(match_pattern_.begin(),match_pattern_.end(),range.first,range.second,'*','?') ^ allow_through_on_match_)
  6370. {
  6371. predicate_(range);
  6372. }
  6373. }
  6374. inline void operator() (const std::string& s) const
  6375. {
  6376. if (match(match_pattern_,s) ^ allow_through_on_match_)
  6377. {
  6378. predicate_(s);
  6379. }
  6380. }
  6381. private:
  6382. filter_on_wildcard_match(const filter_on_wildcard_match& fom);
  6383. filter_on_wildcard_match& operator=(const filter_on_wildcard_match& fom);
  6384. bool allow_through_on_match_;
  6385. std::string match_pattern_;
  6386. OutputPredicate& predicate_;
  6387. };
  6388. template <typename OutputPredicate>
  6389. struct filter_on_match
  6390. {
  6391. public:
  6392. filter_on_match(const std::string* begin, const std::string* end,
  6393. OutputPredicate predicate,
  6394. bool case_insensitive,
  6395. bool allow_through_on_match = true)
  6396. : case_insensitive_(case_insensitive),
  6397. allow_through_on_match_(allow_through_on_match),
  6398. begin_(begin),
  6399. end_(end),
  6400. predicate_(predicate)
  6401. {}
  6402. template <typename Iterator>
  6403. inline void operator() (const std::pair<Iterator,Iterator>& range) const
  6404. {
  6405. for (const std::string* itr = begin_; end_ != itr; ++itr)
  6406. {
  6407. if ((case_insensitive_ &&
  6408. (imatch((*itr).data(),(*itr).data() + (*itr).size(),range.first,range.second))) ||
  6409. (!case_insensitive_ && std::equal((*itr).begin(),(*itr).end(),range.first)))
  6410. {
  6411. if (allow_through_on_match_)
  6412. {
  6413. predicate_(range);
  6414. }
  6415. return;
  6416. }
  6417. }
  6418. if (!allow_through_on_match_)
  6419. {
  6420. predicate_(range);
  6421. return;
  6422. }
  6423. }
  6424. inline void operator() (const std::string& s) const
  6425. {
  6426. for (const std::string* itr = begin_; end_ != itr; ++itr)
  6427. {
  6428. if ((case_insensitive_ &&
  6429. (imatch((*itr).begin(),(*itr).end(),s.begin(),s.end()))) ||
  6430. (!case_insensitive_ && std::equal((*itr).begin(),(*itr).end(),s.begin())))
  6431. {
  6432. if (allow_through_on_match_)
  6433. {
  6434. predicate_(s);
  6435. return;
  6436. }
  6437. }
  6438. }
  6439. if (!allow_through_on_match_)
  6440. {
  6441. predicate_(s);
  6442. return;
  6443. }
  6444. }
  6445. private:
  6446. filter_on_match& operator=(const filter_on_match& fom);
  6447. private:
  6448. bool case_insensitive_;
  6449. bool allow_through_on_match_;
  6450. const std::string* begin_;
  6451. const std::string* end_;
  6452. OutputPredicate predicate_;
  6453. };
  6454. template <typename Iterator, typename MatchPredicate>
  6455. inline void skip_while_matching(Iterator& itr,
  6456. const Iterator& end,
  6457. const MatchPredicate& predicate)
  6458. {
  6459. while (end != itr)
  6460. {
  6461. if (predicate(*itr))
  6462. ++itr;
  6463. else
  6464. break;
  6465. }
  6466. }
  6467. template <std::size_t length>
  6468. struct size_equal_to
  6469. {
  6470. template <typename Iterator>
  6471. inline bool operator()(const Iterator begin, const Iterator end) const
  6472. {
  6473. return length == std::distance(begin,end);
  6474. }
  6475. template <typename Iterator>
  6476. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6477. {
  6478. return length == std::distance(range.first,range.second);
  6479. }
  6480. template <typename T,
  6481. typename Allocator,
  6482. template <typename,typename> class Sequence>
  6483. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6484. {
  6485. return length == sequence.size();
  6486. }
  6487. template <typename T,
  6488. typename Comparator,
  6489. typename Allocator>
  6490. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6491. {
  6492. return length == set.size();
  6493. }
  6494. template <typename T,
  6495. typename Comparator,
  6496. typename Allocator>
  6497. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6498. {
  6499. return length == multiset.size();
  6500. }
  6501. inline bool operator()(const std::string& str) const
  6502. {
  6503. return length == str.size();
  6504. }
  6505. };
  6506. template <std::size_t length>
  6507. struct size_less_than
  6508. {
  6509. template <typename Iterator>
  6510. inline bool operator()(const Iterator begin, const Iterator end) const
  6511. {
  6512. return std::distance(begin,end) < static_cast<typename std::iterator_traits<Iterator>::difference_type>(length);
  6513. }
  6514. template <typename Iterator>
  6515. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6516. {
  6517. return std::distance(range.first,range.second) < static_cast<typename std::iterator_traits<Iterator>::difference_type>(length);
  6518. }
  6519. template <typename T,
  6520. typename Allocator,
  6521. template <typename,typename> class Sequence>
  6522. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6523. {
  6524. return sequence.size() < length;
  6525. }
  6526. template <typename T,
  6527. typename Comparator,
  6528. typename Allocator>
  6529. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6530. {
  6531. return set.size() < length;
  6532. }
  6533. template <typename T,
  6534. typename Comparator,
  6535. typename Allocator>
  6536. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6537. {
  6538. return multiset.size() < length;
  6539. }
  6540. inline bool operator()(const std::string& str) const
  6541. {
  6542. return str.size() < length;
  6543. }
  6544. };
  6545. template <std::size_t length>
  6546. struct size_greater_than
  6547. {
  6548. template <typename Iterator>
  6549. inline bool operator()(const Iterator begin, const Iterator end) const
  6550. {
  6551. return std::distance(begin,end) > static_cast<typename std::iterator_traits<Iterator>::difference_type>(length);
  6552. }
  6553. template <typename Iterator>
  6554. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6555. {
  6556. return std::distance(range.first,range.second) > static_cast<typename std::iterator_traits<Iterator>::difference_type>(length);
  6557. }
  6558. template <typename T,
  6559. typename Allocator,
  6560. template <typename,typename> class Sequence>
  6561. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6562. {
  6563. return sequence.size() > length;
  6564. }
  6565. template <typename T,
  6566. typename Comparator,
  6567. typename Allocator>
  6568. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6569. {
  6570. return set.size() > length;
  6571. }
  6572. template <typename T,
  6573. typename Comparator,
  6574. typename Allocator>
  6575. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6576. {
  6577. return multiset.size() > length;
  6578. }
  6579. inline bool operator()(const std::string& str) const
  6580. {
  6581. return str.size() > length;
  6582. }
  6583. };
  6584. struct size_is_even
  6585. {
  6586. template <typename Iterator>
  6587. inline bool operator()(const Iterator begin, const Iterator end) const
  6588. {
  6589. return 0 == (std::distance(begin,end) % 2);
  6590. }
  6591. template <typename Iterator>
  6592. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6593. {
  6594. return 0 == (std::distance(range.first,range.second) % 2);
  6595. }
  6596. template <typename T,
  6597. typename Allocator,
  6598. template <typename,typename> class Sequence>
  6599. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6600. {
  6601. return 0 == (sequence.size() % 2);
  6602. }
  6603. template <typename T,
  6604. typename Comparator,
  6605. typename Allocator>
  6606. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6607. {
  6608. return 0 == (set.size() % 2);
  6609. }
  6610. template <typename T,
  6611. typename Comparator,
  6612. typename Allocator>
  6613. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6614. {
  6615. return 0 == (multiset.size() % 2);
  6616. }
  6617. inline bool operator()(const std::string& str) const
  6618. {
  6619. return 0 == (str.size() % 2);
  6620. }
  6621. };
  6622. struct size_is_odd
  6623. {
  6624. template <typename Iterator>
  6625. inline bool operator()(const Iterator begin, const Iterator end) const
  6626. {
  6627. return 0 != (std::distance(begin,end) % 2);
  6628. }
  6629. template <typename Iterator>
  6630. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6631. {
  6632. return 0 != (std::distance(range.first,range.second) % 2);
  6633. }
  6634. template <typename T,
  6635. typename Allocator,
  6636. template <typename,typename> class Sequence>
  6637. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6638. {
  6639. return 0 != (sequence.size() % 2);
  6640. }
  6641. template <typename T,
  6642. typename Comparator,
  6643. typename Allocator>
  6644. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6645. {
  6646. return 0 != (set.size() % 2);
  6647. }
  6648. template <typename T,
  6649. typename Comparator,
  6650. typename Allocator>
  6651. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6652. {
  6653. return 0 != (multiset.size() % 2);
  6654. }
  6655. inline bool operator()(const std::string& str) const
  6656. {
  6657. return 0 != (str.size() % 2);
  6658. }
  6659. };
  6660. template <typename InputIterator,
  6661. typename T1, typename T2, typename T3, typename T4,
  6662. typename T5, typename T6, typename T7, typename T8,
  6663. typename T9, typename T10, typename T11, typename T12>
  6664. inline bool parse(const InputIterator begin,
  6665. const InputIterator end,
  6666. const std::string& delimiters,
  6667. T1& t1, T2& t2, T3& t3, T4& t4,
  6668. T5& t5, T6& t6, T7& t7, T8& t8,
  6669. T9& t9, T10& t10, T11& t11, T12& t12)
  6670. {
  6671. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6672. static const std::size_t token_count = 12;
  6673. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6674. typedef iterator_type* iterator_type_ptr;
  6675. iterator_type token_list[token_count];
  6676. const std::size_t parsed_token_count = split_n(delimiters,
  6677. begin,end,
  6678. token_count,
  6679. token_list,
  6680. split_options::compress_delimiters);
  6681. if (token_count > parsed_token_count)
  6682. return false;
  6683. iterator_type_ptr itr = token_list;
  6684. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  6685. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  6686. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  6687. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  6688. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  6689. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  6690. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  6691. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  6692. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  6693. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr;
  6694. if (!string_to_type_converter((*itr).first,(*itr).second,t11)) return false; ++itr;
  6695. if (!string_to_type_converter((*itr).first,(*itr).second,t12)) return false;
  6696. return true;
  6697. }
  6698. template <typename InputIterator,
  6699. typename T1, typename T2, typename T3, typename T4,
  6700. typename T5, typename T6, typename T7, typename T8,
  6701. typename T9, typename T10, typename T11>
  6702. inline bool parse(const InputIterator begin,
  6703. const InputIterator end,
  6704. const std::string& delimiters,
  6705. T1& t1, T2& t2, T3& t3, T4& t4,
  6706. T5& t5, T6& t6, T7& t7, T8& t8,
  6707. T9& t9, T10& t10, T11& t11)
  6708. {
  6709. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6710. static const std::size_t token_count = 11;
  6711. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6712. typedef iterator_type* iterator_type_ptr;
  6713. iterator_type token_list[token_count];
  6714. const std::size_t parsed_token_count = split_n(delimiters,
  6715. begin,end,
  6716. token_count,
  6717. token_list,
  6718. split_options::compress_delimiters);
  6719. if (token_count > parsed_token_count)
  6720. return false;
  6721. iterator_type_ptr itr = token_list;
  6722. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  6723. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  6724. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  6725. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  6726. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  6727. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  6728. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  6729. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  6730. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  6731. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr;
  6732. if (!string_to_type_converter((*itr).first,(*itr).second,t11)) return false;
  6733. return true;
  6734. }
  6735. template <typename InputIterator,
  6736. typename T1, typename T2, typename T3, typename T4,
  6737. typename T5, typename T6, typename T7, typename T8,
  6738. typename T9, typename T10>
  6739. inline bool parse(const InputIterator begin,
  6740. const InputIterator end,
  6741. const std::string& delimiters,
  6742. T1& t1, T2& t2, T3& t3, T4& t4,
  6743. T5& t5, T6& t6, T7& t7, T8& t8,
  6744. T9& t9, T10& t10)
  6745. {
  6746. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6747. static const std::size_t token_count = 10;
  6748. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6749. typedef iterator_type* iterator_type_ptr;
  6750. iterator_type token_list[token_count];
  6751. const std::size_t parsed_token_count = split_n(delimiters,
  6752. begin,end,
  6753. token_count,
  6754. token_list,
  6755. split_options::compress_delimiters);
  6756. if (token_count > parsed_token_count)
  6757. return false;
  6758. iterator_type_ptr itr = token_list;
  6759. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  6760. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  6761. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  6762. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  6763. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  6764. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  6765. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  6766. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  6767. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  6768. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false;
  6769. return true;
  6770. }
  6771. template <typename InputIterator,
  6772. typename T1, typename T2, typename T3, typename T4,
  6773. typename T5, typename T6, typename T7, typename T8,
  6774. typename T9>
  6775. inline bool parse(const InputIterator begin,
  6776. const InputIterator end,
  6777. const std::string& delimiters,
  6778. T1& t1, T2& t2, T3& t3, T4& t4,
  6779. T5& t5, T6& t6, T7& t7, T8& t8,
  6780. T9& t9)
  6781. {
  6782. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6783. static const std::size_t token_count = 9;
  6784. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6785. typedef iterator_type* iterator_type_ptr;
  6786. iterator_type token_list[token_count];
  6787. const std::size_t parsed_token_count = split_n(delimiters,
  6788. begin,end,
  6789. token_count,
  6790. token_list,
  6791. split_options::compress_delimiters);
  6792. if (token_count > parsed_token_count)
  6793. return false;
  6794. iterator_type_ptr itr = token_list;
  6795. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6796. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  6797. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  6798. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  6799. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  6800. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  6801. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  6802. if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false; ++itr;
  6803. if (!string_to_type_converter((*itr).first,(*itr).second,t9)) return false;
  6804. return true;
  6805. }
  6806. template <typename InputIterator,
  6807. typename T1, typename T2, typename T3, typename T4,
  6808. typename T5, typename T6, typename T7, typename T8>
  6809. inline bool parse(const InputIterator begin,
  6810. const InputIterator end,
  6811. const std::string& delimiters,
  6812. T1& t1, T2& t2, T3& t3, T4& t4,
  6813. T5& t5, T6& t6, T7& t7, T8& t8)
  6814. {
  6815. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6816. static const std::size_t token_count = 8;
  6817. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6818. typedef iterator_type* iterator_type_ptr;
  6819. iterator_type token_list[token_count];
  6820. const std::size_t parsed_token_count = split_n(delimiters,
  6821. begin,end,
  6822. token_count,
  6823. token_list,
  6824. split_options::compress_delimiters);
  6825. if (token_count > parsed_token_count)
  6826. return false;
  6827. iterator_type_ptr itr = token_list;
  6828. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6829. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  6830. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  6831. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  6832. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  6833. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  6834. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  6835. if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false;
  6836. return true;
  6837. }
  6838. template <typename InputIterator,
  6839. typename T1, typename T2, typename T3, typename T4,
  6840. typename T5, typename T6, typename T7>
  6841. inline bool parse(const InputIterator begin,
  6842. const InputIterator end,
  6843. const std::string& delimiters,
  6844. T1& t1, T2& t2, T3& t3, T4& t4,
  6845. T5& t5, T6& t6, T7& t7)
  6846. {
  6847. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6848. static const std::size_t token_count = 7;
  6849. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6850. typedef iterator_type* iterator_type_ptr;
  6851. iterator_type token_list[token_count];
  6852. const std::size_t parsed_token_count = split_n(delimiters,
  6853. begin,end,
  6854. token_count,
  6855. token_list,
  6856. split_options::compress_delimiters);
  6857. if (token_count > parsed_token_count)
  6858. return false;
  6859. iterator_type_ptr itr = token_list;
  6860. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6861. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  6862. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  6863. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  6864. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  6865. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  6866. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false;
  6867. return true;
  6868. }
  6869. template <typename InputIterator,
  6870. typename T1, typename T2, typename T3, typename T4,
  6871. typename T5, typename T6>
  6872. inline bool parse(const InputIterator begin,
  6873. const InputIterator end,
  6874. const std::string& delimiters,
  6875. T1& t1, T2& t2, T3& t3, T4& t4,
  6876. T5& t5, T6& t6)
  6877. {
  6878. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6879. static const std::size_t token_count = 6;
  6880. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6881. typedef iterator_type* iterator_type_ptr;
  6882. iterator_type token_list[token_count];
  6883. const std::size_t parsed_token_count = split_n(delimiters,
  6884. begin,end,
  6885. token_count,
  6886. token_list,
  6887. split_options::compress_delimiters);
  6888. if (token_count > parsed_token_count)
  6889. return false;
  6890. iterator_type_ptr itr = token_list;
  6891. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6892. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  6893. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  6894. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  6895. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  6896. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false;
  6897. return true;
  6898. }
  6899. template <typename InputIterator,
  6900. typename T1, typename T2, typename T3, typename T4,
  6901. typename T5>
  6902. inline bool parse(const InputIterator begin,
  6903. const InputIterator end,
  6904. const std::string& delimiters,
  6905. T1& t1, T2& t2, T3& t3, T4& t4,
  6906. T5& t5)
  6907. {
  6908. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6909. static const std::size_t token_count = 5;
  6910. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6911. typedef iterator_type* iterator_type_ptr;
  6912. iterator_type token_list[token_count];
  6913. const std::size_t parsed_token_count = split_n(delimiters,
  6914. begin,end,
  6915. token_count,
  6916. token_list,
  6917. split_options::compress_delimiters);
  6918. if (token_count > parsed_token_count)
  6919. return false;
  6920. iterator_type_ptr itr = token_list;
  6921. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6922. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  6923. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  6924. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  6925. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false;
  6926. return true;
  6927. }
  6928. template <typename InputIterator,
  6929. typename T1, typename T2, typename T3, typename T4>
  6930. inline bool parse(const InputIterator begin,
  6931. const InputIterator end,
  6932. const std::string& delimiters,
  6933. T1& t1, T2& t2, T3& t3, T4& t4)
  6934. {
  6935. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6936. static const std::size_t token_count = 4;
  6937. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6938. typedef iterator_type* iterator_type_ptr;
  6939. iterator_type token_list[token_count];
  6940. const std::size_t parsed_token_count = split_n(delimiters,
  6941. begin,end,
  6942. token_count,
  6943. token_list,
  6944. split_options::compress_delimiters);
  6945. if (token_count > parsed_token_count)
  6946. return false;
  6947. iterator_type_ptr itr = token_list;
  6948. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6949. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  6950. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  6951. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false;
  6952. return true;
  6953. }
  6954. template <typename InputIterator,
  6955. typename T1, typename T2, typename T3>
  6956. inline bool parse(const InputIterator begin,
  6957. const InputIterator end,
  6958. const std::string& delimiters,
  6959. T1& t1, T2& t2, T3& t3)
  6960. {
  6961. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6962. static const std::size_t token_count = 3;
  6963. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6964. typedef iterator_type* iterator_type_ptr;
  6965. iterator_type token_list[token_count];
  6966. const std::size_t parsed_token_count = split_n(delimiters,
  6967. begin,end,
  6968. token_count,
  6969. token_list,
  6970. split_options::compress_delimiters);
  6971. if (token_count > parsed_token_count)
  6972. return false;
  6973. iterator_type_ptr itr = token_list;
  6974. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6975. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  6976. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false;
  6977. return true;
  6978. }
  6979. template <typename InputIterator, typename T1, typename T2>
  6980. inline bool parse(const InputIterator begin,
  6981. const InputIterator end,
  6982. const std::string& delimiters,
  6983. T1& t1, T2& t2)
  6984. {
  6985. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6986. static const std::size_t token_count = 2;
  6987. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6988. typedef iterator_type* iterator_type_ptr;
  6989. iterator_type token_list[token_count];
  6990. const std::size_t parsed_token_count = split_n(delimiters,
  6991. begin,end,
  6992. token_count,
  6993. token_list,
  6994. split_options::compress_delimiters);
  6995. if (token_count > parsed_token_count)
  6996. return false;
  6997. iterator_type_ptr itr = token_list;
  6998. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6999. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false;
  7000. return true;
  7001. }
  7002. template <typename InputIterator, typename T>
  7003. inline bool parse(const InputIterator begin,
  7004. const InputIterator end,
  7005. const std::string& delimiters,
  7006. T& t)
  7007. {
  7008. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7009. static const std::size_t token_count = 1;
  7010. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7011. typedef iterator_type* iterator_type_ptr;
  7012. iterator_type token_list[token_count];
  7013. const std::size_t parsed_token_count = split_n(delimiters,
  7014. begin,end,
  7015. token_count,
  7016. token_list,
  7017. split_options::compress_delimiters);
  7018. if (token_count > parsed_token_count)
  7019. return false;
  7020. iterator_type_ptr itr = token_list;
  7021. return string_to_type_converter((*itr).first,(*itr).second,t);
  7022. }
  7023. template <typename InputIterator,
  7024. typename T,
  7025. typename Allocator,
  7026. template <typename,typename> class Sequence>
  7027. inline std::size_t parse(const InputIterator begin,
  7028. const InputIterator end,
  7029. const std::string& delimiters,
  7030. Sequence<T,Allocator>& sequence,
  7031. const split_options::type& split_option = split_options::compress_delimiters)
  7032. {
  7033. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7034. if (1 == delimiters.size())
  7035. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7036. begin,end,
  7037. range_to_type_back_inserter(sequence),
  7038. split_option);
  7039. else
  7040. return split(multiple_char_delimiter_predicate(delimiters),
  7041. begin, end,
  7042. range_to_type_back_inserter(sequence),
  7043. split_option);
  7044. }
  7045. template <typename InputIterator,
  7046. typename T,
  7047. typename Comparator,
  7048. typename Allocator>
  7049. inline std::size_t parse(const InputIterator begin,
  7050. const InputIterator end,
  7051. const std::string& delimiters,
  7052. std::set<T,Comparator,Allocator>& set,
  7053. const split_options::type& split_option = split_options::compress_delimiters)
  7054. {
  7055. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7056. if (1 == delimiters.size())
  7057. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7058. begin,end,
  7059. range_to_type_inserter(set),
  7060. split_option);
  7061. else
  7062. return split(multiple_char_delimiter_predicate(delimiters),
  7063. begin,end,
  7064. range_to_type_inserter(set),
  7065. split_option);
  7066. }
  7067. template <typename InputIterator,
  7068. typename T,
  7069. typename Comparator,
  7070. typename Allocator>
  7071. inline std::size_t parse(const InputIterator begin,
  7072. const InputIterator end,
  7073. const std::string& delimiters,
  7074. std::multiset<T,Comparator,Allocator>& multiset,
  7075. const split_options::type& split_option = split_options::compress_delimiters)
  7076. {
  7077. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7078. if (1 == delimiters.size())
  7079. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7080. begin,end,
  7081. range_to_type_inserter(multiset),
  7082. split_option);
  7083. else
  7084. return split(multiple_char_delimiter_predicate(delimiters),
  7085. begin,end,
  7086. range_to_type_inserter(multiset),
  7087. split_option);
  7088. }
  7089. template <typename InputIterator,
  7090. typename T,
  7091. typename Container>
  7092. inline std::size_t parse(const InputIterator begin,
  7093. const InputIterator end,
  7094. const std::string& delimiters,
  7095. std::queue<T,Container>& queue,
  7096. const split_options::type& split_option = split_options::compress_delimiters)
  7097. {
  7098. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7099. if (1 == delimiters.size())
  7100. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7101. begin,end,
  7102. range_to_type_push_inserter(queue),
  7103. split_option);
  7104. else
  7105. return split(multiple_char_delimiter_predicate(delimiters),
  7106. begin,end,
  7107. range_to_type_push_inserter(queue),
  7108. split_option);
  7109. }
  7110. template <typename InputIterator,
  7111. typename T,
  7112. typename Container>
  7113. inline std::size_t parse(const InputIterator begin,
  7114. const InputIterator end,
  7115. const std::string& delimiters,
  7116. std::stack<T,Container>& stack,
  7117. const split_options::type& split_option = split_options::compress_delimiters)
  7118. {
  7119. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7120. if (1 == delimiters.size())
  7121. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7122. begin,end,
  7123. range_to_type_push_inserter(stack),
  7124. split_option);
  7125. else
  7126. return split(multiple_char_delimiter_predicate(delimiters),
  7127. begin, end,
  7128. range_to_type_push_inserter(stack),
  7129. split_option);
  7130. }
  7131. template <typename InputIterator,
  7132. typename T,
  7133. typename Container,
  7134. typename Comparator>
  7135. inline std::size_t parse(const InputIterator begin,
  7136. const InputIterator end,
  7137. const std::string& delimiters,
  7138. std::priority_queue<T,Container,Comparator>& priority_queue,
  7139. const split_options::type& split_option = split_options::compress_delimiters)
  7140. {
  7141. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7142. if (1 == delimiters.size())
  7143. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7144. begin,end,
  7145. range_to_type_push_inserter(priority_queue),
  7146. split_option);
  7147. else
  7148. return split(multiple_char_delimiter_predicate(delimiters),
  7149. begin,end,
  7150. range_to_type_push_inserter(priority_queue),
  7151. split_option);
  7152. }
  7153. template <typename InputIterator,
  7154. typename T,
  7155. typename Allocator,
  7156. template <typename,typename> class Sequence>
  7157. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7158. const std::string& delimiters,
  7159. Sequence<T,Allocator>& sequence,
  7160. const split_options::type& split_option = split_options::compress_delimiters)
  7161. {
  7162. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7163. if (1 == delimiters.size())
  7164. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7165. range.first,range.second,
  7166. range_to_type_back_inserter(sequence),
  7167. split_option);
  7168. else
  7169. return split(multiple_char_delimiter_predicate(delimiters),
  7170. range.first,range.second,
  7171. range_to_type_back_inserter(sequence),
  7172. split_option);
  7173. }
  7174. template <typename InputIterator,
  7175. typename T,
  7176. typename Comparator,
  7177. typename Allocator>
  7178. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7179. const std::string& delimiters,
  7180. std::set<T,Comparator,Allocator>& set,
  7181. const split_options::type& split_option = split_options::compress_delimiters)
  7182. {
  7183. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7184. if (1 == delimiters.size())
  7185. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7186. range.first,range.second,
  7187. range_to_type_inserter(set),
  7188. split_option);
  7189. else
  7190. return split(multiple_char_delimiter_predicate(delimiters),
  7191. range.first,range.second,
  7192. range_to_type_inserter(set),
  7193. split_option);
  7194. }
  7195. template <typename InputIterator,
  7196. typename T,
  7197. typename Comparator,
  7198. typename Allocator>
  7199. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7200. const std::string& delimiters,
  7201. std::multiset<T,Comparator,Allocator>& multiset,
  7202. const split_options::type& split_option = split_options::compress_delimiters)
  7203. {
  7204. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7205. if (1 == delimiters.size())
  7206. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7207. range.first,range.second,
  7208. range_to_type_inserter(multiset),
  7209. split_option);
  7210. else
  7211. return split(multiple_char_delimiter_predicate(delimiters),
  7212. range.first,range.second,
  7213. range_to_type_inserter(multiset),
  7214. split_option);
  7215. }
  7216. template <typename InputIterator,
  7217. typename T,
  7218. typename Container>
  7219. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7220. const std::string& delimiters,
  7221. std::queue<T,Container>& queue,
  7222. const split_options::type& split_option = split_options::compress_delimiters)
  7223. {
  7224. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7225. if (1 == delimiters.size())
  7226. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7227. range.first,range.second,
  7228. range_to_type_push_inserter(queue),
  7229. split_option);
  7230. else
  7231. return split(multiple_char_delimiter_predicate(delimiters),
  7232. range.first,range.second,
  7233. range_to_type_push_inserter(queue),
  7234. split_option);
  7235. }
  7236. template <typename InputIterator,
  7237. typename T,
  7238. typename Container>
  7239. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7240. const std::string& delimiters,
  7241. std::stack<T,Container>& stack,
  7242. const split_options::type& split_option = split_options::compress_delimiters)
  7243. {
  7244. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7245. if (1 == delimiters.size())
  7246. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7247. range.first,range.second,
  7248. range_to_type_push_inserter(stack),
  7249. split_option);
  7250. else
  7251. return split(multiple_char_delimiter_predicate(delimiters),
  7252. range.first,range.second,
  7253. range_to_type_push_inserter(stack),
  7254. split_option);
  7255. }
  7256. template <typename InputIterator,
  7257. typename T,
  7258. typename Container,
  7259. typename Comparator>
  7260. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7261. const std::string& delimiters,
  7262. std::priority_queue<T,Container,Comparator>& priority_queue,
  7263. const split_options::type& split_option = split_options::compress_delimiters)
  7264. {
  7265. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7266. if (1 == delimiters.size())
  7267. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7268. range.first,range.second,
  7269. range_to_type_push_inserter(priority_queue),
  7270. split_option);
  7271. else
  7272. return split(multiple_char_delimiter_predicate(delimiters),
  7273. range.first,range.second,
  7274. range_to_type_push_inserter(priority_queue),
  7275. split_option);
  7276. }
  7277. namespace details
  7278. {
  7279. class container_adder
  7280. {
  7281. private:
  7282. class container_adder_base
  7283. {
  7284. public:
  7285. typedef const char* itr_type;
  7286. virtual ~container_adder_base(){}
  7287. template <typename InputIterator>
  7288. inline bool add(const InputIterator begin, const InputIterator end) const
  7289. {
  7290. return add_impl(begin,end);
  7291. }
  7292. template <typename InputIterator>
  7293. inline bool add(const std::pair<InputIterator,InputIterator>& range) const
  7294. {
  7295. return add(range.first,range.second);
  7296. }
  7297. protected:
  7298. virtual bool add_impl(const itr_type begin, const itr_type end) const = 0;
  7299. };
  7300. template <typename T,
  7301. typename Allocator,
  7302. template <typename,typename> class Sequence>
  7303. class sequence_adder_impl : public container_adder_base
  7304. {
  7305. public:
  7306. typedef Sequence<T,Allocator> sequence_t;
  7307. sequence_adder_impl(sequence_t& seq)
  7308. : sequence_(seq)
  7309. {}
  7310. protected:
  7311. bool add_impl(const itr_type begin, const itr_type end) const
  7312. {
  7313. T t;
  7314. if (!string_to_type_converter(begin,end,t)) return false;
  7315. sequence_.push_back(t);
  7316. return true;
  7317. }
  7318. private:
  7319. sequence_adder_impl operator=(const sequence_adder_impl&);
  7320. sequence_t& sequence_;
  7321. };
  7322. template <typename T,
  7323. typename Comparator,
  7324. typename Allocator,
  7325. template <typename,typename,typename> class Set>
  7326. class set_adder_impl : public container_adder_base
  7327. {
  7328. public:
  7329. set_adder_impl(Set<T,Comparator,Allocator>& set)
  7330. : set_(set)
  7331. {}
  7332. bool add_impl(const itr_type begin, const itr_type end) const
  7333. {
  7334. T t;
  7335. if (!string_to_type_converter(begin,end,t)) return false;
  7336. set_.insert(t);
  7337. return true;
  7338. }
  7339. private:
  7340. set_adder_impl operator=(const set_adder_impl&);
  7341. Set<T,Comparator,Allocator>& set_;
  7342. };
  7343. template <typename T,
  7344. typename Container,
  7345. typename Comparator>
  7346. class pq_adder_impl : public container_adder_base
  7347. {
  7348. public:
  7349. pq_adder_impl(std::priority_queue<T,Container,Comparator>& pq)
  7350. : pq_(pq)
  7351. {}
  7352. bool add_impl(const itr_type begin, const itr_type end) const
  7353. {
  7354. T t;
  7355. if (!string_to_type_converter(begin,end,t)) return false;
  7356. pq_.push(t);
  7357. return true;
  7358. }
  7359. private:
  7360. pq_adder_impl operator=(const pq_adder_impl&);
  7361. std::priority_queue<T,Container,Comparator>& pq_;
  7362. };
  7363. template <typename T,
  7364. typename Container,
  7365. template <typename,typename> class SContainer>
  7366. class stack_queue_adder_impl : public container_adder_base
  7367. {
  7368. public:
  7369. stack_queue_adder_impl(SContainer<T,Container>& container)
  7370. : container_(container)
  7371. {}
  7372. bool add_impl(const itr_type begin, const itr_type end) const
  7373. {
  7374. T t;
  7375. if (!string_to_type_converter(begin,end,t)) return false;
  7376. container_.push(t);
  7377. return true;
  7378. }
  7379. private:
  7380. stack_queue_adder_impl operator=(const stack_queue_adder_impl&);
  7381. SContainer<T,Container>& container_;
  7382. };
  7383. public:
  7384. template <typename T, typename Allocator>
  7385. container_adder(std::vector<T,Allocator>& vec)
  7386. : container_adder_base_(new(buffer)sequence_adder_impl<T,Allocator,std::vector>(vec))
  7387. {}
  7388. template <typename T, typename Allocator>
  7389. container_adder(std::deque<T,Allocator>& deq)
  7390. : container_adder_base_(new(buffer)sequence_adder_impl<T,Allocator,std::deque>(deq))
  7391. {}
  7392. template <typename T, typename Allocator>
  7393. container_adder(std::list<T,Allocator>& list)
  7394. : container_adder_base_(new(buffer)sequence_adder_impl<T,Allocator,std::list>(list))
  7395. {}
  7396. template <typename T, typename Comparator, typename Allocator>
  7397. container_adder(std::set<T,Comparator,Allocator>& set)
  7398. : container_adder_base_(new(buffer)set_adder_impl<T,Comparator,Allocator,std::set>(set))
  7399. {}
  7400. template <typename T, typename Comparator, typename Allocator>
  7401. container_adder(std::multiset<T,Comparator,Allocator>& multiset)
  7402. : container_adder_base_(new(buffer)set_adder_impl<T,Comparator,Allocator,std::multiset>(multiset))
  7403. {}
  7404. template <typename T, typename Container, typename Comparator>
  7405. container_adder(std::priority_queue<T,Container,Comparator>& pq)
  7406. : container_adder_base_(new(buffer)pq_adder_impl<T,Container,Comparator>(pq))
  7407. {}
  7408. template <typename T, typename Container>
  7409. container_adder(std::queue<T,Container>& queue)
  7410. : container_adder_base_(new(buffer)stack_queue_adder_impl<T,Container,std::queue>(queue))
  7411. {}
  7412. template <typename T, typename Container>
  7413. container_adder(std::stack<T,Container>& stack)
  7414. : container_adder_base_(new(buffer)stack_queue_adder_impl<T,Container,std::stack>(stack))
  7415. {}
  7416. template <typename InputIterator>
  7417. inline bool add(InputIterator begin, InputIterator end) const
  7418. {
  7419. return container_adder_base_->add(begin,end);
  7420. }
  7421. template <typename InputIterator>
  7422. inline bool add(std::pair<InputIterator,InputIterator>& range) const
  7423. {
  7424. return add(range.first,range.second);
  7425. }
  7426. template <typename InputIterator>
  7427. inline bool operator()(const InputIterator begin, const InputIterator end)
  7428. {
  7429. InputIterator itr = begin;
  7430. while (end != itr)
  7431. {
  7432. if (!add(*itr)) return false;
  7433. ++itr;
  7434. }
  7435. return true;
  7436. }
  7437. private:
  7438. mutable container_adder_base* container_adder_base_;
  7439. unsigned char buffer[64];
  7440. };
  7441. template <typename T,typename is_stl_container_result>
  7442. struct ca_type { typedef T& type; };
  7443. template <typename T>
  7444. struct ca_type <T,details::yes_t> { typedef details::container_adder type; };
  7445. }
  7446. template <typename InputIterator,
  7447. typename T1, typename T2, typename T3,
  7448. typename T4, typename T5, typename T6,
  7449. typename T7, typename T8, typename T9,
  7450. typename T10, typename T11>
  7451. inline bool parse(const InputIterator begin, const InputIterator end,
  7452. const std::string& delimiters,
  7453. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7,
  7454. T8& t8, T9& t9, T10& t10, T11& t11,
  7455. details::container_adder ca)
  7456. {
  7457. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7458. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7459. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7460. std::deque<iterator_type> token_list;
  7461. if (1 == delimiters.size())
  7462. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7463. begin,end,
  7464. std::back_inserter(token_list),
  7465. split_options::compress_delimiters);
  7466. else
  7467. split(multiple_char_delimiter_predicate(delimiters),
  7468. begin,end,
  7469. std::back_inserter(token_list),
  7470. split_options::compress_delimiters);
  7471. if (token_list.size() < 12) return false;
  7472. iterator_type_ptr itr = token_list.begin();
  7473. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  7474. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  7475. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  7476. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  7477. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  7478. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  7479. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  7480. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  7481. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  7482. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr;
  7483. if (!string_to_type_converter((*itr).first,(*itr).second,t11)) return false; ++itr;
  7484. return ca(itr,token_list.end());
  7485. }
  7486. template <typename InputIterator,
  7487. typename T1, typename T2, typename T3,
  7488. typename T4, typename T5, typename T6,
  7489. typename T7, typename T8, typename T9,
  7490. typename T10>
  7491. inline bool parse(const InputIterator begin, const InputIterator end,
  7492. const std::string& delimiters,
  7493. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9, T10& t10,
  7494. details::container_adder ca)
  7495. {
  7496. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7497. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7498. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7499. std::deque<iterator_type> token_list;
  7500. if (1 == delimiters.size())
  7501. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7502. begin,end,
  7503. std::back_inserter(token_list),
  7504. split_options::compress_delimiters);
  7505. else
  7506. split(multiple_char_delimiter_predicate(delimiters),
  7507. begin,end,
  7508. std::back_inserter(token_list),
  7509. split_options::compress_delimiters);
  7510. if (token_list.size() < 11) return false;
  7511. iterator_type_ptr itr = token_list.begin();
  7512. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  7513. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  7514. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  7515. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  7516. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  7517. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  7518. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  7519. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  7520. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  7521. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr;
  7522. return ca(itr,token_list.end());
  7523. }
  7524. template <typename InputIterator,
  7525. typename T1, typename T2, typename T3,
  7526. typename T4, typename T5, typename T6,
  7527. typename T7, typename T8, typename T9>
  7528. inline bool parse(const InputIterator begin, const InputIterator end,
  7529. const std::string& delimiters,
  7530. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9,
  7531. details::container_adder ca)
  7532. {
  7533. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7534. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7535. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7536. std::deque<iterator_type> token_list;
  7537. if (1 == delimiters.size())
  7538. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7539. begin,end,
  7540. std::back_inserter(token_list),
  7541. split_options::compress_delimiters);
  7542. else
  7543. split(multiple_char_delimiter_predicate(delimiters),
  7544. begin,end,
  7545. std::back_inserter(token_list),
  7546. split_options::compress_delimiters);
  7547. if (token_list.size() < 10) return false;
  7548. iterator_type_ptr itr = token_list.begin();
  7549. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7550. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7551. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7552. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7553. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7554. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7555. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  7556. if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false; ++itr;
  7557. if (!string_to_type_converter((*itr).first,(*itr).second,t9)) return false; ++itr;
  7558. return ca(itr,token_list.end());
  7559. }
  7560. template <typename InputIterator,
  7561. typename T1, typename T2, typename T3,
  7562. typename T4, typename T5, typename T6,
  7563. typename T7, typename T8>
  7564. inline bool parse(const InputIterator begin, const InputIterator end,
  7565. const std::string& delimiters,
  7566. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8,
  7567. details::container_adder ca)
  7568. {
  7569. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7570. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7571. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7572. std::deque<iterator_type> token_list;
  7573. if (1 == delimiters.size())
  7574. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7575. begin,end,
  7576. std::back_inserter(token_list),
  7577. split_options::compress_delimiters);
  7578. else
  7579. split(multiple_char_delimiter_predicate(delimiters),
  7580. begin,end,
  7581. std::back_inserter(token_list),
  7582. split_options::compress_delimiters);
  7583. if (token_list.size() < 9) return false;
  7584. iterator_type_ptr itr = token_list.begin();
  7585. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7586. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7587. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7588. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7589. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7590. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7591. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  7592. if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false; ++itr;
  7593. return ca(itr,token_list.end());
  7594. }
  7595. template <typename InputIterator,
  7596. typename T1, typename T2, typename T3,
  7597. typename T4, typename T5, typename T6, typename T7>
  7598. inline bool parse(const InputIterator begin, const InputIterator end,
  7599. const std::string& delimiters,
  7600. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7,
  7601. details::container_adder ca)
  7602. {
  7603. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7604. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7605. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7606. std::deque<iterator_type> token_list;
  7607. if (1 == delimiters.size())
  7608. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7609. begin,end,
  7610. std::back_inserter(token_list),
  7611. split_options::compress_delimiters);
  7612. else
  7613. split(multiple_char_delimiter_predicate(delimiters),
  7614. begin,end,
  7615. std::back_inserter(token_list),
  7616. split_options::compress_delimiters);
  7617. if (token_list.size() < 8) return false;
  7618. iterator_type_ptr itr = token_list.begin();
  7619. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7620. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7621. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7622. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7623. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7624. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7625. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  7626. return ca(itr,token_list.end());
  7627. }
  7628. template <typename InputIterator,
  7629. typename T1, typename T2, typename T3,
  7630. typename T4, typename T5, typename T6>
  7631. inline bool parse(const InputIterator begin, const InputIterator end,
  7632. const std::string& delimiters,
  7633. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  7634. details::container_adder ca)
  7635. {
  7636. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7637. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7638. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7639. std::deque<iterator_type> token_list;
  7640. if (1 == delimiters.size())
  7641. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7642. begin,end,
  7643. std::back_inserter(token_list),
  7644. split_options::compress_delimiters);
  7645. else
  7646. split(multiple_char_delimiter_predicate(delimiters),
  7647. begin,end,
  7648. std::back_inserter(token_list),
  7649. split_options::compress_delimiters);
  7650. if (token_list.size() < 7) return false;
  7651. iterator_type_ptr itr = token_list.begin();
  7652. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7653. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7654. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7655. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7656. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7657. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7658. return ca(itr,token_list.end());
  7659. }
  7660. template <typename InputIterator,
  7661. typename T1, typename T2, typename T3,
  7662. typename T4, typename T5>
  7663. inline bool parse(const InputIterator begin, const InputIterator end,
  7664. const std::string& delimiters,
  7665. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  7666. details::container_adder ca)
  7667. {
  7668. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7669. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7670. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7671. std::deque<iterator_type> token_list;
  7672. if (1 == delimiters.size())
  7673. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7674. begin,end,
  7675. std::back_inserter(token_list),
  7676. split_options::compress_delimiters);
  7677. else
  7678. split(multiple_char_delimiter_predicate(delimiters),
  7679. begin,end,
  7680. std::back_inserter(token_list),
  7681. split_options::compress_delimiters);
  7682. if (token_list.size() < 6) return false;
  7683. iterator_type_ptr itr = token_list.begin();
  7684. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7685. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7686. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7687. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7688. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7689. return ca(itr,token_list.end());
  7690. }
  7691. template <typename InputIterator,
  7692. typename T1, typename T2, typename T3, typename T4>
  7693. inline bool parse(const InputIterator begin, const InputIterator end,
  7694. const std::string& delimiters,
  7695. T1& t1, T2& t2, T3& t3, T4& t4,
  7696. details::container_adder ca)
  7697. {
  7698. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7699. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7700. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7701. std::deque<iterator_type> token_list;
  7702. if (1 == delimiters.size())
  7703. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7704. begin,end,
  7705. std::back_inserter(token_list),
  7706. split_options::compress_delimiters);
  7707. else
  7708. split(multiple_char_delimiter_predicate(delimiters),
  7709. begin,end,
  7710. std::back_inserter(token_list),
  7711. split_options::compress_delimiters);
  7712. if (token_list.size() < 5) return false;
  7713. iterator_type_ptr itr = token_list.begin();
  7714. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7715. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7716. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7717. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7718. return ca(itr,token_list.end());
  7719. }
  7720. template <typename InputIterator,
  7721. typename T1, typename T2, typename T3>
  7722. inline bool parse(const InputIterator begin, const InputIterator end,
  7723. const std::string& delimiters,
  7724. T1& t1, T2& t2, T3& t3,
  7725. details::container_adder ca)
  7726. {
  7727. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7728. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7729. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7730. std::deque<iterator_type> token_list;
  7731. if (1 == delimiters.size())
  7732. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7733. begin,end,
  7734. std::back_inserter(token_list),
  7735. split_options::compress_delimiters);
  7736. else
  7737. split(multiple_char_delimiter_predicate(delimiters),
  7738. begin,end,
  7739. std::back_inserter(token_list),
  7740. split_options::compress_delimiters);
  7741. if (token_list.size() < 4) return false;
  7742. iterator_type_ptr itr = token_list.begin();
  7743. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7744. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7745. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7746. return ca(itr,token_list.end());
  7747. }
  7748. template <typename InputIterator,
  7749. typename T1, typename T2>
  7750. inline bool parse(const InputIterator begin, const InputIterator end,
  7751. const std::string& delimiters,
  7752. T1& t1, T2& t2,
  7753. details::container_adder ca)
  7754. {
  7755. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7756. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7757. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7758. std::deque<iterator_type> token_list;
  7759. if (1 == delimiters.size())
  7760. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7761. begin,end,
  7762. std::back_inserter(token_list),
  7763. split_options::compress_delimiters);
  7764. else
  7765. split(multiple_char_delimiter_predicate(delimiters),
  7766. begin,end,
  7767. std::back_inserter(token_list),
  7768. split_options::compress_delimiters);
  7769. if (token_list.size() < 3) return false;
  7770. iterator_type_ptr itr = token_list.begin();
  7771. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7772. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7773. return ca(itr,token_list.end());
  7774. }
  7775. template <typename InputIterator, typename T1>
  7776. inline bool parse(const InputIterator begin, const InputIterator end,
  7777. const std::string& delimiters,
  7778. T1& t1,
  7779. details::container_adder ca)
  7780. {
  7781. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7782. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7783. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7784. std::deque<iterator_type> token_list;
  7785. if (1 == delimiters.size())
  7786. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7787. begin,end,
  7788. std::back_inserter(token_list),
  7789. split_options::compress_delimiters);
  7790. else
  7791. split(multiple_char_delimiter_predicate(delimiters),
  7792. begin,end,
  7793. std::back_inserter(token_list),
  7794. split_options::compress_delimiters);
  7795. if (token_list.size() < 2) return false;
  7796. iterator_type_ptr itr = token_list.begin();
  7797. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7798. return ca(itr,token_list.end());
  7799. }
  7800. template <typename InputIterator,
  7801. typename T,
  7802. typename Allocator,
  7803. template <typename,typename> class Sequence>
  7804. inline std::size_t parse_n(const InputIterator begin,
  7805. const InputIterator end,
  7806. const std::string& delimiters,
  7807. const std::size_t& n,
  7808. Sequence<T,Allocator>& sequence,
  7809. const split_options::type& split_option = split_options::compress_delimiters)
  7810. {
  7811. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7812. const std::size_t original_size = sequence.size();
  7813. if (1 == delimiters.size())
  7814. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7815. begin,end,
  7816. n,
  7817. range_to_type_back_inserter(sequence),
  7818. split_option);
  7819. else
  7820. split_n(multiple_char_delimiter_predicate(delimiters),
  7821. begin,end,
  7822. n,
  7823. range_to_type_back_inserter(sequence),
  7824. split_option);
  7825. return sequence.size() - original_size;
  7826. }
  7827. template <typename InputIterator,
  7828. typename T,
  7829. typename Comparator,
  7830. typename Allocator>
  7831. inline std::size_t parse_n(const InputIterator begin,
  7832. const InputIterator end,
  7833. const std::string& delimiters,
  7834. const std::size_t& n,
  7835. std::set<T,Comparator,Allocator>& set,
  7836. const split_options::type& split_option = split_options::compress_delimiters)
  7837. {
  7838. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7839. const std::size_t original_size = set.size();
  7840. if (1 == delimiters.size())
  7841. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7842. begin,end,
  7843. n,
  7844. range_to_type_inserter(set),
  7845. split_option);
  7846. else
  7847. split_n(multiple_char_delimiter_predicate(delimiters),
  7848. begin,end,
  7849. n,
  7850. range_to_type_inserter(set),
  7851. split_option);
  7852. return set.size() - original_size;
  7853. }
  7854. template <typename InputIterator,
  7855. typename T,
  7856. typename Comparator,
  7857. typename Allocator>
  7858. inline std::size_t parse_n(const InputIterator begin,
  7859. const InputIterator end,
  7860. const std::string& delimiters,
  7861. const std::size_t& n,
  7862. std::multiset<T,Comparator,Allocator>& multiset,
  7863. const split_options::type& split_option = split_options::compress_delimiters)
  7864. {
  7865. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7866. const std::size_t original_size = multiset.size();
  7867. if (1 == delimiters.size())
  7868. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7869. begin,end,
  7870. n,
  7871. range_to_type_inserter(multiset),
  7872. split_option);
  7873. else
  7874. split_n(multiple_char_delimiter_predicate(delimiters),
  7875. begin,end,
  7876. n,
  7877. range_to_type_inserter(multiset),
  7878. split_option);
  7879. return multiset.size() - original_size;
  7880. }
  7881. template <typename InputIterator,
  7882. typename T,
  7883. typename Container>
  7884. inline std::size_t parse_n(const InputIterator begin,
  7885. const InputIterator end,
  7886. const std::string& delimiters,
  7887. const std::size_t& n,
  7888. std::queue<T,Container>& queue,
  7889. const split_options::type& split_option = split_options::compress_delimiters)
  7890. {
  7891. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7892. const std::size_t original_size = queue.size();
  7893. if (1 == delimiters.size())
  7894. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7895. begin,end,
  7896. n,
  7897. range_to_type_push_inserter(queue),
  7898. split_option);
  7899. else
  7900. split_n(multiple_char_delimiter_predicate(delimiters),
  7901. begin,end,
  7902. n,
  7903. range_to_type_push_inserter(queue),
  7904. split_option);
  7905. return queue.size() - original_size;
  7906. }
  7907. template <typename InputIterator,
  7908. typename T,
  7909. typename Container>
  7910. inline std::size_t parse_n(const InputIterator begin,
  7911. const InputIterator end,
  7912. const std::string& delimiters,
  7913. const std::size_t& n,
  7914. std::stack<T,Container>& stack,
  7915. const split_options::type& split_option = split_options::compress_delimiters)
  7916. {
  7917. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7918. const std::size_t original_size = stack.size();
  7919. if (1 == delimiters.size())
  7920. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7921. begin,end,
  7922. n,
  7923. range_to_type_push_inserter(stack),
  7924. split_option);
  7925. else
  7926. split_n(multiple_char_delimiter_predicate(delimiters),
  7927. begin,end,
  7928. n,
  7929. range_to_type_push_inserter(stack),
  7930. split_option);
  7931. return stack.size() - original_size;
  7932. }
  7933. template <typename InputIterator,
  7934. typename T,
  7935. typename Container,
  7936. typename Comparator>
  7937. inline std::size_t parse_n(const InputIterator begin,
  7938. const InputIterator end,
  7939. const std::string& delimiters,
  7940. const std::size_t& n,
  7941. std::priority_queue<T,Container,Comparator>& priority_queue,
  7942. const split_options::type& split_option = split_options::compress_delimiters)
  7943. {
  7944. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7945. const std::size_t original_size = priority_queue.size();
  7946. if (1 == delimiters.size())
  7947. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7948. begin,end,
  7949. n,
  7950. range_to_type_push_inserter(priority_queue),
  7951. split_option);
  7952. else
  7953. split_n(multiple_char_delimiter_predicate(delimiters),
  7954. begin,end,
  7955. n,
  7956. range_to_type_push_inserter(priority_queue),
  7957. split_option);
  7958. return priority_queue.size() - original_size;
  7959. }
  7960. template <typename InputIterator, typename T>
  7961. inline std::size_t parse_n(const InputIterator begin,
  7962. const InputIterator end,
  7963. const std::string& delimiters,
  7964. const std::size_t& n,
  7965. T* out,
  7966. const split_options::type& split_option = split_options::compress_delimiters)
  7967. {
  7968. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7969. std::size_t insert_count = 0;
  7970. if (1 == delimiters.size())
  7971. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7972. begin,end,
  7973. n,
  7974. range_to_ptr_type(out,insert_count),
  7975. split_option);
  7976. else
  7977. split_n(multiple_char_delimiter_predicate(delimiters),
  7978. begin,end,
  7979. n,
  7980. range_to_ptr_type(out,insert_count),
  7981. split_option);
  7982. return insert_count;
  7983. }
  7984. template <typename InputIterator,
  7985. typename T,
  7986. typename Allocator,
  7987. template <typename,typename> class Sequence>
  7988. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  7989. const std::string& delimiters,
  7990. const std::size_t& n,
  7991. Sequence<T,Allocator>& sequence,
  7992. const split_options::type& split_option = split_options::compress_delimiters)
  7993. {
  7994. return parse(range.first,range.second,delimiters,n,sequence,split_option);
  7995. }
  7996. template <typename InputIterator,
  7997. typename T,
  7998. typename Comparator,
  7999. typename Allocator>
  8000. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8001. const std::string& delimiters,
  8002. const std::size_t& n,
  8003. std::set<T,Comparator,Allocator>& set,
  8004. const split_options::type& split_option = split_options::compress_delimiters)
  8005. {
  8006. return parse(range.first,range.second,delimiters,n,set,split_option);
  8007. }
  8008. template <typename InputIterator,
  8009. typename T,
  8010. typename Comparator,
  8011. typename Allocator>
  8012. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8013. const std::string& delimiters,
  8014. const std::size_t& n,
  8015. std::multiset<T,Comparator,Allocator>& multiset,
  8016. const split_options::type& split_option = split_options::compress_delimiters)
  8017. {
  8018. return parse(range.first,range.second,delimiters,n,multiset,split_option);
  8019. }
  8020. template <typename InputIterator,
  8021. typename T,
  8022. typename Container>
  8023. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8024. const std::string& delimiters,
  8025. const std::size_t& n,
  8026. std::queue<T,Container>& queue,
  8027. const split_options::type& split_option = split_options::compress_delimiters)
  8028. {
  8029. return parse(range.first,range.second,delimiters,n,queue,split_option);
  8030. }
  8031. template <typename InputIterator,
  8032. typename T,
  8033. typename Container>
  8034. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8035. const std::string& delimiters,
  8036. const std::size_t& n,
  8037. std::stack<T,Container>& stack,
  8038. const split_options::type& split_option = split_options::compress_delimiters)
  8039. {
  8040. return parse(range.first,range.second,delimiters,n,stack,split_option);
  8041. }
  8042. template <typename InputIterator,
  8043. typename T,
  8044. typename Container,
  8045. typename Comparator>
  8046. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8047. const std::string& delimiters,
  8048. const std::size_t& n,
  8049. std::priority_queue<T,Container,Comparator>& priority_queue,
  8050. const split_options::type& split_option = split_options::compress_delimiters)
  8051. {
  8052. return parse(range.first,range.second,delimiters,n,priority_queue,split_option);
  8053. }
  8054. template <typename T1, typename T2, typename T3, typename T4,
  8055. typename T5, typename T6, typename T7, typename T8,
  8056. typename T9, typename T10, typename T11, typename T12>
  8057. inline bool parse(const std::string& data,
  8058. const std::string& delimiters,
  8059. T1& t1, T2& t2, T3& t3, T4& t4,
  8060. T5& t5, T6& t6, T7& t7, T8& t8,
  8061. T9& t9, T10& t10, T11& t11, T12& t12)
  8062. {
  8063. return parse(data.data(),
  8064. data.data() + data.size(),
  8065. delimiters,
  8066. t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,
  8067. typename details::ca_type<T12, typename details::is_stl_container<T12>::result_t>::type(t12));
  8068. }
  8069. template <typename T1, typename T2, typename T3, typename T4,
  8070. typename T5, typename T6, typename T7, typename T8,
  8071. typename T9, typename T10, typename T11>
  8072. inline bool parse(const std::string& data,
  8073. const std::string& delimiters,
  8074. T1& t1, T2& t2, T3& t3, T4& t4,
  8075. T5& t5, T6& t6, T7& t7, T8& t8,
  8076. T9& t9, T10& t10, T11& t11)
  8077. {
  8078. return parse(data.data(),
  8079. data.data() + data.size(),
  8080. delimiters,
  8081. t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,
  8082. typename details::ca_type<T11, typename details::is_stl_container<T11>::result_t>::type(t11));
  8083. }
  8084. template <typename T1, typename T2, typename T3, typename T4,
  8085. typename T5, typename T6, typename T7, typename T8,
  8086. typename T9, typename T10>
  8087. inline bool parse(const std::string& data,
  8088. const std::string& delimiters,
  8089. T1& t1, T2& t2, T3& t3, T4& t4,
  8090. T5& t5, T6& t6, T7& t7, T8& t8,
  8091. T9& t9, T10& t10)
  8092. {
  8093. return parse(data.data(),
  8094. data.data() + data.size(),
  8095. delimiters,
  8096. t1,t2,t3,t4,t5,t6,t7,t8,t9,
  8097. typename details::ca_type<T10, typename details::is_stl_container<T10>::result_t>::type(t10));
  8098. }
  8099. template <typename T1, typename T2, typename T3, typename T4,
  8100. typename T5, typename T6, typename T7, typename T8,
  8101. typename T9>
  8102. inline bool parse(const std::string& data,
  8103. const std::string& delimiters,
  8104. T1& t1, T2& t2, T3& t3, T4& t4,
  8105. T5& t5, T6& t6, T7& t7, T8& t8,
  8106. T9& t9)
  8107. {
  8108. return parse(data.data(),
  8109. data.data() + data.size(),
  8110. delimiters,
  8111. t1,t2,t3,t4,t5,t6,t7,t8,
  8112. typename details::ca_type<T9, typename details::is_stl_container<T9>::result_t>::type(t9));
  8113. }
  8114. template <typename T1, typename T2, typename T3, typename T4,
  8115. typename T5, typename T6, typename T7, typename T8>
  8116. inline bool parse(const std::string& data,
  8117. const std::string& delimiters,
  8118. T1& t1, T2& t2, T3& t3, T4& t4,
  8119. T5& t5, T6& t6, T7& t7, T8& t8)
  8120. {
  8121. return parse(data.data(),
  8122. data.data() + data.size(),
  8123. delimiters,
  8124. t1,t2,t3,t4,t5,t6,t7,
  8125. typename details::ca_type<T8, typename details::is_stl_container<T8>::result_t>::type(t8));
  8126. }
  8127. template <typename T1, typename T2, typename T3, typename T4,
  8128. typename T5, typename T6, typename T7>
  8129. inline bool parse(const std::string& data,
  8130. const std::string& delimiters,
  8131. T1& t1, T2& t2, T3& t3, T4& t4,
  8132. T5& t5, T6& t6, T7& t7)
  8133. {
  8134. return parse(data.data(),
  8135. data.data() + data.size(),
  8136. delimiters,
  8137. t1,t2,t3,t4,t5,t6,
  8138. typename details::ca_type<T7, typename details::is_stl_container<T7>::result_t>::type(t7));
  8139. }
  8140. template <typename T1, typename T2, typename T3, typename T4,
  8141. typename T5, typename T6>
  8142. inline bool parse(const std::string& data,
  8143. const std::string& delimiters,
  8144. T1& t1, T2& t2, T3& t3, T4& t4,
  8145. T5& t5, T6& t6)
  8146. {
  8147. return parse(data.data(),
  8148. data.data() + data.size(),
  8149. delimiters,
  8150. t1,t2,t3,t4,t5,
  8151. typename details::ca_type<T6,typename details::is_stl_container<T6>::result_t>::type(t6));
  8152. }
  8153. template <typename T1, typename T2, typename T3, typename T4,
  8154. typename T5>
  8155. inline bool parse(const std::string& data,
  8156. const std::string& delimiters,
  8157. T1& t1, T2& t2, T3& t3, T4& t4,
  8158. T5& t5)
  8159. {
  8160. return parse(data.data(),
  8161. data.data() + data.size(),
  8162. delimiters,
  8163. t1,t2,t3,t4,
  8164. typename details::ca_type<T5, typename details::is_stl_container<T5>::result_t>::type(t5));
  8165. }
  8166. template <typename T1, typename T2, typename T3, typename T4>
  8167. inline bool parse(const std::string& data,
  8168. const std::string& delimiters,
  8169. T1& t1, T2& t2, T3& t3, T4& t4)
  8170. {
  8171. return parse(data.data(),
  8172. data.data() + data.size(),
  8173. delimiters,
  8174. t1,t2,t3,
  8175. typename details::ca_type<T4, typename details::is_stl_container<T4>::result_t>::type(t4));
  8176. }
  8177. template <typename T1, typename T2, typename T3>
  8178. inline bool parse(const std::string& data,
  8179. const std::string& delimiters,
  8180. T1& t1, T2& t2, T3& t3)
  8181. {
  8182. return parse(data.data(),
  8183. data.data() + data.size(),
  8184. delimiters,
  8185. t1,t2,
  8186. typename details::ca_type<T3, typename details::is_stl_container<T3>::result_t>::type(t3));
  8187. }
  8188. template <typename T1, typename T2>
  8189. inline bool parse(const std::string& data,
  8190. const std::string& delimiters,
  8191. T1& t1, T2& t2)
  8192. {
  8193. return parse(data.data(),
  8194. data.data() + data.size(),
  8195. delimiters,
  8196. t1,
  8197. typename details::ca_type<T2, typename details::is_stl_container<T2>::result_t>::type(t2));
  8198. }
  8199. template <typename T>
  8200. inline bool parse(const std::string& data,
  8201. const std::string& delimiters,
  8202. T& t)
  8203. {
  8204. return parse(data.data(),
  8205. data.data() + data.size(),
  8206. delimiters,
  8207. typename details::ca_type<T,typename details::is_stl_container<T>::result_t>::type(t));
  8208. }
  8209. template <typename T,
  8210. typename Allocator,
  8211. template <typename,typename> class Sequence>
  8212. inline std::size_t parse(const std::string& data,
  8213. const std::string& delimiters,
  8214. Sequence<T,Allocator>& sequence,
  8215. const split_options::type& split_option = split_options::compress_delimiters)
  8216. {
  8217. return parse(data.data(),
  8218. data.data() + data.size(),
  8219. delimiters,
  8220. sequence,
  8221. split_option);
  8222. }
  8223. template <typename T,
  8224. typename Comparator,
  8225. typename Allocator>
  8226. inline std::size_t parse(const std::string& data,
  8227. const std::string& delimiters,
  8228. std::set<T,Comparator,Allocator>& set,
  8229. const split_options::type& split_option = split_options::compress_delimiters)
  8230. {
  8231. return parse(data.data(),
  8232. data.data() + data.size(),
  8233. delimiters,
  8234. set,
  8235. split_option);
  8236. }
  8237. template <typename T,
  8238. typename Comparator,
  8239. typename Allocator>
  8240. inline std::size_t parse(const std::string& data,
  8241. const std::string& delimiters,
  8242. std::multiset<T,Comparator,Allocator>& multiset,
  8243. const split_options::type& split_option = split_options::compress_delimiters)
  8244. {
  8245. return parse(data.data(),
  8246. data.data() + data.size(),
  8247. delimiters,
  8248. multiset,
  8249. split_option);
  8250. }
  8251. template <typename T,
  8252. typename Container>
  8253. inline std::size_t parse(const std::string& data,
  8254. const std::string& delimiters,
  8255. std::queue<T,Container>& queue,
  8256. const split_options::type& split_option = split_options::compress_delimiters)
  8257. {
  8258. return parse(data.data(),
  8259. data.data() + data.size(),
  8260. delimiters,
  8261. queue,
  8262. split_option);
  8263. }
  8264. template <typename T,
  8265. typename Container>
  8266. inline std::size_t parse(const std::string& data,
  8267. const std::string& delimiters,
  8268. std::stack<T,Container>& stack,
  8269. const split_options::type& split_option = split_options::compress_delimiters)
  8270. {
  8271. return parse(data.data(),
  8272. data.data() + data.size(),
  8273. delimiters,
  8274. stack,
  8275. split_option);
  8276. }
  8277. template <typename T,
  8278. typename Container,
  8279. typename Comparator>
  8280. inline std::size_t parse(const std::string& data,
  8281. const std::string& delimiters,
  8282. std::priority_queue<T,Container,Comparator>& priority_queue,
  8283. const split_options::type& split_option = split_options::compress_delimiters)
  8284. {
  8285. return parse(data.data(),
  8286. data.data() + data.size(),
  8287. delimiters,
  8288. priority_queue,
  8289. split_option);
  8290. }
  8291. template <typename T,
  8292. typename Allocator,
  8293. template <typename,typename> class Sequence>
  8294. inline std::size_t parse(const int& argc, char* argv[],
  8295. Sequence<T,Allocator>& sequence,
  8296. const bool break_on_fail = true)
  8297. {
  8298. T tmp;
  8299. for (int i = 0; i < argc; ++i)
  8300. {
  8301. if (!string_to_type_converter(std::string(argv[i]),tmp))
  8302. {
  8303. if (break_on_fail)
  8304. return i;
  8305. else
  8306. continue;
  8307. }
  8308. sequence.push_back(tmp);
  8309. }
  8310. return argc;
  8311. }
  8312. template <typename T1, typename T2, typename T3, typename T4,
  8313. typename T5, typename T6, typename T7, typename T8,
  8314. typename T9>
  8315. inline std::size_t parse(const int& argc, char* argv[],
  8316. T1& t1, T2& t2, T3& t3, T4& t4,
  8317. T5& t5, T6& t6, T7& t7, T8& t8,
  8318. T9& t9)
  8319. {
  8320. if (9 != argc) return 0;
  8321. std::size_t result = 0;
  8322. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8323. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8324. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8325. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8326. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8327. if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result;
  8328. if (!string_to_type_converter(std::string(argv[6]),t7)) return result; ++result;
  8329. if (!string_to_type_converter(std::string(argv[7]),t8)) return result; ++result;
  8330. if (!string_to_type_converter(std::string(argv[8]),t9)) return result; ++result;
  8331. return result;
  8332. }
  8333. template <typename T1, typename T2, typename T3, typename T4,
  8334. typename T5, typename T6, typename T7, typename T8>
  8335. inline std::size_t parse(const int& argc, char* argv[],
  8336. T1& t1, T2& t2, T3& t3, T4& t4,
  8337. T5& t5, T6& t6, T7& t7, T8& t8)
  8338. {
  8339. if (8 != argc) return 0;
  8340. std::size_t result = 0;
  8341. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8342. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8343. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8344. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8345. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8346. if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result;
  8347. if (!string_to_type_converter(std::string(argv[6]),t7)) return result; ++result;
  8348. if (!string_to_type_converter(std::string(argv[7]),t8)) return result; ++result;
  8349. return result;
  8350. }
  8351. template <typename T1, typename T2, typename T3, typename T4,
  8352. typename T5, typename T6, typename T7>
  8353. inline std::size_t parse(const int& argc, char* argv[],
  8354. T1& t1, T2& t2, T3& t3, T4& t4,
  8355. T5& t5, T6& t6, T7& t7)
  8356. {
  8357. if (7 != argc) return 0;
  8358. std::size_t result = 0;
  8359. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8360. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8361. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8362. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8363. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8364. if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result;
  8365. if (!string_to_type_converter(std::string(argv[6]),t7)) return result; ++result;
  8366. return result;
  8367. }
  8368. template <typename T1, typename T2, typename T3, typename T4,
  8369. typename T5, typename T6>
  8370. inline std::size_t parse(const int& argc, char* argv[],
  8371. T1& t1, T2& t2, T3& t3, T4& t4,
  8372. T5& t5, T6& t6)
  8373. {
  8374. if (6 != argc) return 0;
  8375. std::size_t result = 0;
  8376. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8377. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8378. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8379. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8380. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8381. if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result;
  8382. return result;
  8383. }
  8384. template <typename T1, typename T2, typename T3, typename T4, typename T5>
  8385. inline std::size_t parse(const int& argc, char* argv[],
  8386. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5)
  8387. {
  8388. if (5 != argc) return 0;
  8389. std::size_t result = 0;
  8390. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8391. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8392. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8393. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8394. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8395. return result;
  8396. }
  8397. template <typename T1, typename T2, typename T3, typename T4>
  8398. inline std::size_t parse(const int& argc, char* argv[],
  8399. T1& t1, T2& t2, T3& t3, T4& t4)
  8400. {
  8401. if (4 != argc) return 0;
  8402. std::size_t result = 0;
  8403. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8404. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8405. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8406. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8407. return result;
  8408. }
  8409. template <typename T1, typename T2, typename T3>
  8410. inline std::size_t parse(const int& argc, char* argv[],
  8411. T1& t1, T2& t2, T3& t3)
  8412. {
  8413. if (3 != argc) return 0;
  8414. std::size_t result = 0;
  8415. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8416. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8417. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8418. return result;
  8419. }
  8420. template <typename T1, typename T2>
  8421. inline std::size_t parse(const int& argc, char* argv[],
  8422. T1& t1, T2& t2)
  8423. {
  8424. if (2 != argc) return 0;
  8425. std::size_t result = 0;
  8426. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8427. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8428. return result;
  8429. }
  8430. template <typename T1>
  8431. inline std::size_t parse(const int& argc, char* argv[],
  8432. T1& t1)
  8433. {
  8434. if (1 != argc) return 0;
  8435. std::size_t result = 0;
  8436. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8437. return result;
  8438. }
  8439. #define strtk_parse_begin(Type)\
  8440. namespace strtk {\
  8441. bool parse(const std::string& data, const std::string& delimiters, Type& t)\
  8442. { return parse(data,delimiters
  8443. #define strtk_parse_type(T)\
  8444. ,t.T
  8445. #define strtk_parse_hex_type(T)\
  8446. ,t.T
  8447. #define strtk_parse_ignore_token()\
  8448. ,ignore_token()
  8449. #define strtk_parse_end()\
  8450. );}}
  8451. template <typename T,
  8452. typename Allocator,
  8453. template <typename,typename> class Sequence>
  8454. inline std::size_t parse_n(const std::string& data,
  8455. const std::string& delimiters,
  8456. const std::size_t& n,
  8457. Sequence<T,Allocator>& sequence,
  8458. const split_options::type& split_option = split_options::compress_delimiters)
  8459. {
  8460. return parse_n(data.data(),
  8461. data.data() + data.size(),
  8462. delimiters,
  8463. n,
  8464. sequence,
  8465. split_option);
  8466. }
  8467. template <typename T,
  8468. typename Comparator,
  8469. typename Allocator>
  8470. inline std::size_t parse_n(const std::string& data,
  8471. const std::string& delimiters,
  8472. const std::size_t& n,
  8473. std::set<T,Comparator,Allocator>& set,
  8474. const split_options::type& split_option = split_options::compress_delimiters)
  8475. {
  8476. return parse_n(data.data(),
  8477. data.data() + data.size(),
  8478. delimiters,
  8479. n,
  8480. set,
  8481. split_option);
  8482. }
  8483. template <typename T,
  8484. typename Comparator,
  8485. typename Allocator>
  8486. inline std::size_t parse_n(const std::string& data,
  8487. const std::string& delimiters,
  8488. const std::size_t& n,
  8489. std::multiset<T,Comparator,Allocator>& multiset,
  8490. const split_options::type& split_option = split_options::compress_delimiters)
  8491. {
  8492. return parse_n(data.data(),
  8493. data.data() + data.size(),
  8494. delimiters,
  8495. n,
  8496. multiset,
  8497. split_option);
  8498. }
  8499. template <typename T,
  8500. typename Container>
  8501. inline std::size_t parse_n(const std::string& data,
  8502. const std::string& delimiters,
  8503. const std::size_t& n,
  8504. std::queue<T,Container>& queue,
  8505. const split_options::type& split_option = split_options::compress_delimiters)
  8506. {
  8507. return parse_n(data.data(),
  8508. data.data() + data.size(),
  8509. delimiters,
  8510. n,
  8511. queue,
  8512. split_option);
  8513. }
  8514. template <typename T,
  8515. typename Container>
  8516. inline std::size_t parse_n(const std::string& data,
  8517. const std::string& delimiters,
  8518. const std::size_t& n,
  8519. std::stack<T,Container>& stack,
  8520. const split_options::type& split_option = split_options::compress_delimiters)
  8521. {
  8522. return parse_n(data.data(),
  8523. data.data() + data.size(),
  8524. delimiters,
  8525. n,
  8526. stack,
  8527. split_option);
  8528. }
  8529. template <typename T,
  8530. typename Container,
  8531. typename Comparator>
  8532. inline std::size_t parse_n(const std::string& data,
  8533. const std::string& delimiters,
  8534. const std::size_t& n,
  8535. std::priority_queue<T,Container,Comparator>& priority_queue,
  8536. const split_options::type& split_option = split_options::compress_delimiters)
  8537. {
  8538. return parse_n(data.data(),
  8539. data.data() + data.size(),
  8540. delimiters,
  8541. n,
  8542. priority_queue,
  8543. split_option);
  8544. }
  8545. template <typename T>
  8546. inline std::size_t parse_n(const std::string& data,
  8547. const std::string& delimiters,
  8548. const std::size_t& n,
  8549. T* out,
  8550. const split_options::type& split_option = split_options::compress_delimiters)
  8551. {
  8552. return parse_n(data.data(),
  8553. data.data() + data.size(),
  8554. delimiters,
  8555. n,
  8556. out,
  8557. split_option);
  8558. }
  8559. template <typename T1, typename T2, typename T3, typename T4,
  8560. typename T5, typename T6, typename T7, typename T8,
  8561. typename T9, typename T10, typename T11, typename T12>
  8562. inline bool parse_line(std::ifstream& stream,
  8563. const std::string& delimiters,
  8564. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8565. T7& t7, T8& t8, T9& t9, T10& t10, T11& t11, T12& t12)
  8566. {
  8567. if (!stream)
  8568. return false;
  8569. std::string data;
  8570. data.reserve(strtk::one_kilobyte);
  8571. if (!std::getline(stream,data))
  8572. return false;
  8573. if (data.empty() || delimiters.empty())
  8574. return false;
  8575. return strtk::parse(data.data(),
  8576. data.data() + data.size(),
  8577. delimiters,
  8578. t1,t2,t3,t4,t5,t6,
  8579. t7,t8,t9,t10,t11,t12);
  8580. }
  8581. template <typename T1, typename T2, typename T3, typename T4,
  8582. typename T5, typename T6, typename T7, typename T8,
  8583. typename T9, typename T10, typename T11>
  8584. inline bool parse_line(std::ifstream& stream,
  8585. const std::string& delimiters,
  8586. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8587. T7& t7, T8& t8, T9& t9, T10& t10, T11& t11)
  8588. {
  8589. if (!stream)
  8590. return false;
  8591. std::string data;
  8592. data.reserve(strtk::one_kilobyte);
  8593. if (!std::getline(stream,data))
  8594. return false;
  8595. if (data.empty() || delimiters.empty())
  8596. return false;
  8597. return strtk::parse(data.data(),
  8598. data.data() + data.size(),
  8599. delimiters,
  8600. t1,t2,t3,t4,t5,t6,
  8601. t7,t8,t9,t10,t11);
  8602. }
  8603. template <typename T1, typename T2, typename T3, typename T4,
  8604. typename T5, typename T6, typename T7, typename T8,
  8605. typename T9, typename T10>
  8606. inline bool parse_line(std::ifstream& stream,
  8607. const std::string& delimiters,
  8608. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8609. T7& t7, T8& t8, T9& t9, T10& t10)
  8610. {
  8611. if (!stream)
  8612. return false;
  8613. std::string data;
  8614. data.reserve(strtk::one_kilobyte);
  8615. if (!std::getline(stream,data))
  8616. return false;
  8617. if (data.empty() || delimiters.empty())
  8618. return false;
  8619. return strtk::parse(data.data(),
  8620. data.data() + data.size(),
  8621. delimiters,
  8622. t1,t2,t3,t4,t5,t6,
  8623. t7,t8,t9,t10);
  8624. }
  8625. template <typename T1, typename T2, typename T3, typename T4,
  8626. typename T5, typename T6, typename T7, typename T8,
  8627. typename T9>
  8628. inline bool parse_line(std::ifstream& stream,
  8629. const std::string& delimiters,
  8630. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8631. T7& t7, T8& t8, T9& t9)
  8632. {
  8633. if (!stream)
  8634. return false;
  8635. std::string data;
  8636. data.reserve(strtk::one_kilobyte);
  8637. if (!std::getline(stream,data))
  8638. return false;
  8639. if (data.empty() || delimiters.empty())
  8640. return false;
  8641. return strtk::parse(data.data(),
  8642. data.data() + data.size(),
  8643. delimiters,
  8644. t1,t2,t3,t4,t5,t6,
  8645. t7,t8,t9);
  8646. }
  8647. template <typename T1, typename T2, typename T3, typename T4,
  8648. typename T5, typename T6, typename T7, typename T8>
  8649. inline bool parse_line(std::ifstream& stream,
  8650. const std::string& delimiters,
  8651. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8652. T7& t7, T8& t8)
  8653. {
  8654. if (!stream)
  8655. return false;
  8656. std::string data;
  8657. data.reserve(strtk::one_kilobyte);
  8658. if (!std::getline(stream,data))
  8659. return false;
  8660. if (data.empty() || delimiters.empty())
  8661. return false;
  8662. return strtk::parse(data.data(),
  8663. data.data() + data.size(),
  8664. delimiters,
  8665. t1,t2,t3,t4,t5,t6,
  8666. t7,t8);
  8667. }
  8668. template <typename T1, typename T2, typename T3, typename T4,
  8669. typename T5, typename T6, typename T7>
  8670. inline bool parse_line(std::ifstream& stream,
  8671. const std::string& delimiters,
  8672. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8673. T7& t7)
  8674. {
  8675. if (!stream)
  8676. return false;
  8677. std::string data;
  8678. data.reserve(strtk::one_kilobyte);
  8679. if (!std::getline(stream,data))
  8680. return false;
  8681. if (data.empty() || delimiters.empty())
  8682. return false;
  8683. return strtk::parse(data.data(),
  8684. data.data() + data.size(),
  8685. delimiters,
  8686. t1,t2,t3,t4,t5,t6,t7);
  8687. }
  8688. template <typename T1, typename T2, typename T3, typename T4,
  8689. typename T5, typename T6>
  8690. inline bool parse_line(std::ifstream& stream,
  8691. const std::string& delimiters,
  8692. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6)
  8693. {
  8694. if (!stream)
  8695. return false;
  8696. std::string data;
  8697. data.reserve(strtk::one_kilobyte);
  8698. if (!std::getline(stream,data))
  8699. return false;
  8700. if (data.empty() || delimiters.empty())
  8701. return false;
  8702. return strtk::parse(data.data(),
  8703. data.data() + data.size(),
  8704. delimiters,
  8705. t1,t2,t3,t4,t5,t6);
  8706. }
  8707. template <typename T1, typename T2, typename T3, typename T4,
  8708. typename T5>
  8709. inline bool parse_line(std::ifstream& stream,
  8710. const std::string& delimiters,
  8711. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5)
  8712. {
  8713. if (!stream)
  8714. return false;
  8715. std::string data;
  8716. data.reserve(strtk::one_kilobyte);
  8717. if (!std::getline(stream,data))
  8718. return false;
  8719. if (data.empty() || delimiters.empty())
  8720. return false;
  8721. return strtk::parse(data.data(),
  8722. data.data() + data.size(),
  8723. delimiters,
  8724. t1,t2,t3,t4,t5);
  8725. }
  8726. template <typename T1, typename T2, typename T3, typename T4>
  8727. inline bool parse_line(std::ifstream& stream,
  8728. const std::string& delimiters,
  8729. T1& t1, T2& t2, T3& t3, T4& t4)
  8730. {
  8731. if (!stream)
  8732. return false;
  8733. std::string data;
  8734. data.reserve(strtk::one_kilobyte);
  8735. if (!std::getline(stream,data))
  8736. return false;
  8737. if (data.empty() || delimiters.empty())
  8738. return false;
  8739. return strtk::parse(data.data(),
  8740. data.data() + data.size(),
  8741. delimiters,
  8742. t1,t2,t3,t4);
  8743. }
  8744. template <typename T1, typename T2, typename T3>
  8745. inline bool parse_line(std::ifstream& stream,
  8746. const std::string& delimiters,
  8747. T1& t1, T2& t2, T3& t3)
  8748. {
  8749. if (!stream)
  8750. return false;
  8751. std::string data;
  8752. data.reserve(strtk::one_kilobyte);
  8753. if (!std::getline(stream,data))
  8754. return false;
  8755. if (data.empty() || delimiters.empty())
  8756. return false;
  8757. return strtk::parse(data.data(),
  8758. data.data() + data.size(),
  8759. delimiters,
  8760. t1,t2,t3);
  8761. }
  8762. template <typename T1, typename T2>
  8763. inline bool parse_line(std::ifstream& stream,
  8764. const std::string& delimiters,
  8765. T1& t1, T2& t2)
  8766. {
  8767. if (!stream)
  8768. return false;
  8769. std::string data;
  8770. data.reserve(strtk::one_kilobyte);
  8771. if (!std::getline(stream,data))
  8772. return false;
  8773. if (data.empty() || delimiters.empty())
  8774. return false;
  8775. return strtk::parse(data.data(),
  8776. data.data() + data.size(),
  8777. delimiters,
  8778. t1,t2);
  8779. }
  8780. template <typename T1>
  8781. inline bool parse_line(std::ifstream& stream,
  8782. const std::string& delimiters,
  8783. T1& t1)
  8784. {
  8785. if (!stream)
  8786. return false;
  8787. std::string data;
  8788. data.reserve(strtk::one_kilobyte);
  8789. if (!std::getline(stream,data))
  8790. return false;
  8791. if (data.empty() || delimiters.empty())
  8792. return false;
  8793. return strtk::parse(data.data(),
  8794. data.data() + data.size(),
  8795. delimiters,
  8796. t1);
  8797. }
  8798. template <typename T,
  8799. typename Allocator,
  8800. template <typename,typename> class Sequence>
  8801. inline std::size_t parse_line(std::ifstream& stream,
  8802. const std::string& delimiters,
  8803. Sequence<T,Allocator>& sequence,
  8804. const split_options::type& split_option = split_options::compress_delimiters)
  8805. {
  8806. if (!stream)
  8807. return 0;
  8808. std::string data;
  8809. data.reserve(strtk::one_kilobyte);
  8810. if (!std::getline(stream,data))
  8811. return 0;
  8812. if (data.empty() || delimiters.empty())
  8813. return false;
  8814. return strtk::parse(data.data(),
  8815. data.data() + data.size(),
  8816. delimiters,
  8817. sequence,
  8818. split_option);
  8819. }
  8820. template <typename T,
  8821. typename Comparator,
  8822. typename Allocator>
  8823. inline std::size_t parse_line(std::ifstream& stream,
  8824. const std::string& delimiters,
  8825. std::set<T,Comparator,Allocator>& set,
  8826. const split_options::type& split_option = split_options::compress_delimiters)
  8827. {
  8828. if (!stream)
  8829. return 0;
  8830. std::string data;
  8831. data.reserve(strtk::one_kilobyte);
  8832. if (!std::getline(stream,data))
  8833. return 0;
  8834. if (data.empty() || delimiters.empty())
  8835. return false;
  8836. return strtk::parse(data.data(),
  8837. data.data() + data.size(),
  8838. delimiters,
  8839. set,
  8840. split_option);
  8841. }
  8842. template <typename T,
  8843. typename Comparator,
  8844. typename Allocator>
  8845. inline std::size_t parse_line(std::ifstream& stream,
  8846. const std::string& delimiters,
  8847. std::multiset<T,Comparator,Allocator>& multiset,
  8848. const split_options::type& split_option = split_options::compress_delimiters)
  8849. {
  8850. if (!stream)
  8851. return 0;
  8852. std::string data;
  8853. data.reserve(strtk::one_kilobyte);
  8854. if (!std::getline(stream,data))
  8855. return 0;
  8856. if (data.empty() || delimiters.empty())
  8857. return false;
  8858. return strtk::parse(data.data(),
  8859. data.data() + data.size(),
  8860. delimiters,
  8861. multiset,
  8862. split_option);
  8863. }
  8864. template <typename T,
  8865. typename Container>
  8866. inline std::size_t parse_line(std::ifstream& stream,
  8867. const std::string& delimiters,
  8868. std::queue<T,Container>& queue,
  8869. const split_options::type& split_option = split_options::compress_delimiters)
  8870. {
  8871. if (!stream)
  8872. return 0;
  8873. std::string data;
  8874. data.reserve(strtk::one_kilobyte);
  8875. if (!std::getline(stream,data))
  8876. return 0;
  8877. if (data.empty() || delimiters.empty())
  8878. return false;
  8879. return strtk::parse(data.data(),
  8880. data.data() + data.size(),
  8881. delimiters,
  8882. queue,
  8883. split_option);
  8884. }
  8885. template <typename T,
  8886. typename Container>
  8887. inline std::size_t parse_line(std::ifstream& stream,
  8888. const std::string& delimiters,
  8889. std::stack<T,Container>& stack,
  8890. const split_options::type& split_option = split_options::compress_delimiters)
  8891. {
  8892. if (!stream)
  8893. return 0;
  8894. std::string data;
  8895. data.reserve(strtk::one_kilobyte);
  8896. if (!std::getline(stream,data))
  8897. return 0;
  8898. if (data.empty() || delimiters.empty())
  8899. return false;
  8900. return strtk::parse(data.data(),
  8901. data.data() + data.size(),
  8902. delimiters,
  8903. stack,
  8904. split_option);
  8905. }
  8906. template <typename T,
  8907. typename Container,
  8908. typename Comparator>
  8909. inline std::size_t parse_line(std::ifstream& stream,
  8910. const std::string& delimiters,
  8911. std::priority_queue<T,Container,Comparator>& priority_queue,
  8912. const split_options::type& split_option = split_options::compress_delimiters)
  8913. {
  8914. if (!stream)
  8915. return 0;
  8916. std::string data;
  8917. data.reserve(strtk::one_kilobyte);
  8918. if (!std::getline(stream,data))
  8919. return 0;
  8920. if (data.empty() || delimiters.empty())
  8921. return false;
  8922. return strtk::parse(data.data(),
  8923. data.data() + data.size(),
  8924. delimiters,
  8925. priority_queue,
  8926. split_option);
  8927. }
  8928. template <typename T,
  8929. typename Allocator,
  8930. template <typename,typename> class Sequence>
  8931. inline std::size_t parse_line_n(std::ifstream& stream,
  8932. const std::string& delimiters,
  8933. const std::size_t& n,
  8934. Sequence<T,Allocator>& sequence,
  8935. const split_options::type& split_option = split_options::compress_delimiters)
  8936. {
  8937. if (!stream)
  8938. return 0;
  8939. std::string data;
  8940. data.reserve(strtk::one_kilobyte);
  8941. if (!std::getline(stream,data))
  8942. return 0;
  8943. if (data.empty() || delimiters.empty())
  8944. return 0;
  8945. return strtk::parse_n(data.data(),
  8946. data.data() + data.size(),
  8947. delimiters,
  8948. n,
  8949. sequence,
  8950. split_option);
  8951. }
  8952. template <typename T,
  8953. typename Comparator,
  8954. typename Allocator>
  8955. inline std::size_t parse_line_n(std::ifstream& stream,
  8956. const std::string& delimiters,
  8957. const std::size_t& n,
  8958. std::set<T,Comparator,Allocator>& set,
  8959. const split_options::type& split_option = split_options::compress_delimiters)
  8960. {
  8961. if (!stream)
  8962. return 0;
  8963. std::string data;
  8964. data.reserve(strtk::one_kilobyte);
  8965. if (!std::getline(stream,data))
  8966. return 0;
  8967. if (data.empty() || delimiters.empty())
  8968. return 0;
  8969. return strtk::parse_n(data.data(),
  8970. data.data() + data.size(),
  8971. delimiters,
  8972. n,
  8973. set,
  8974. split_option);
  8975. }
  8976. template <typename T,
  8977. typename Comparator,
  8978. typename Allocator>
  8979. inline std::size_t parse_line_n(std::ifstream& stream,
  8980. const std::string& delimiters,
  8981. const std::size_t& n,
  8982. std::multiset<T,Comparator,Allocator>& multiset,
  8983. const split_options::type& split_option = split_options::compress_delimiters)
  8984. {
  8985. if (!stream)
  8986. return 0;
  8987. std::string data;
  8988. data.reserve(strtk::one_kilobyte);
  8989. if (!std::getline(stream,data))
  8990. return 0;
  8991. if (data.empty() || delimiters.empty())
  8992. return 0;
  8993. return strtk::parse_n(data.data(),
  8994. data.data() + data.size(),
  8995. delimiters,
  8996. n,
  8997. multiset,
  8998. split_option);
  8999. }
  9000. template <typename T,
  9001. typename Container>
  9002. inline std::size_t parse_line_n(std::ifstream& stream,
  9003. const std::string& delimiters,
  9004. const std::size_t& n,
  9005. std::queue<T,Container>& queue,
  9006. const split_options::type& split_option = split_options::compress_delimiters)
  9007. {
  9008. if (!stream)
  9009. return 0;
  9010. std::string data;
  9011. data.reserve(strtk::one_kilobyte);
  9012. if (!std::getline(stream,data))
  9013. return 0;
  9014. if (data.empty() || delimiters.empty())
  9015. return 0;
  9016. return strtk::parse_n(data.data(),
  9017. data.data() + data.size(),
  9018. delimiters,
  9019. n,
  9020. queue,
  9021. split_option);
  9022. }
  9023. template <typename T,
  9024. typename Container>
  9025. inline std::size_t parse_line_n(std::ifstream& stream,
  9026. const std::string& delimiters,
  9027. const std::size_t& n,
  9028. std::stack<T,Container>& stack,
  9029. const split_options::type& split_option = split_options::compress_delimiters)
  9030. {
  9031. if (!stream)
  9032. return 0;
  9033. std::string data;
  9034. data.reserve(strtk::one_kilobyte);
  9035. if (!std::getline(stream,data))
  9036. return 0;
  9037. if (data.empty() || delimiters.empty())
  9038. return 0;
  9039. return strtk::parse_n(data.data(),
  9040. data.data() + data.size(),
  9041. delimiters,
  9042. n,
  9043. stack,
  9044. split_option);
  9045. }
  9046. template <typename T,
  9047. typename Container,
  9048. typename Comparator>
  9049. inline std::size_t parse_line_n(std::ifstream& stream,
  9050. const std::string& delimiters,
  9051. const std::size_t& n,
  9052. std::priority_queue<T,Container,Comparator>& priority_queue,
  9053. const split_options::type& split_option = split_options::compress_delimiters)
  9054. {
  9055. if (!stream)
  9056. return 0;
  9057. std::string data;
  9058. data.reserve(strtk::one_kilobyte);
  9059. if (!std::getline(stream,data))
  9060. return 0;
  9061. if (data.empty() || delimiters.empty())
  9062. return 0;
  9063. return strtk::parse_n(data.data(),
  9064. data.data() + data.size(),
  9065. delimiters,
  9066. n,
  9067. priority_queue,
  9068. split_option);
  9069. }
  9070. template <typename T1, typename T2, typename T3, typename T4,
  9071. typename T5, typename T6, typename T7, typename T8,
  9072. typename T9, typename T10, typename T11, typename T12>
  9073. inline void construct(std::string& output,
  9074. const std::string& delimiter,
  9075. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9076. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  9077. const T9& t9, const T10& t10, const T11& t11, const T12& t12)
  9078. {
  9079. output += type_to_string( t1); output += delimiter;
  9080. output += type_to_string( t2); output += delimiter;
  9081. output += type_to_string( t3); output += delimiter;
  9082. output += type_to_string( t4); output += delimiter;
  9083. output += type_to_string( t5); output += delimiter;
  9084. output += type_to_string( t6); output += delimiter;
  9085. output += type_to_string( t7); output += delimiter;
  9086. output += type_to_string( t8); output += delimiter;
  9087. output += type_to_string( t9); output += delimiter;
  9088. output += type_to_string(t10); output += delimiter;
  9089. output += type_to_string(t11); output += delimiter;
  9090. output += type_to_string(t12);
  9091. }
  9092. template <typename T1, typename T2, typename T3, typename T4,
  9093. typename T5, typename T6, typename T7, typename T8,
  9094. typename T9, typename T10, typename T11>
  9095. inline void construct(std::string& output,
  9096. const std::string& delimiter,
  9097. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9098. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  9099. const T9& t9, const T10& t10, const T11& t11)
  9100. {
  9101. output += type_to_string( t1); output += delimiter;
  9102. output += type_to_string( t2); output += delimiter;
  9103. output += type_to_string( t3); output += delimiter;
  9104. output += type_to_string( t4); output += delimiter;
  9105. output += type_to_string( t5); output += delimiter;
  9106. output += type_to_string( t6); output += delimiter;
  9107. output += type_to_string( t7); output += delimiter;
  9108. output += type_to_string( t8); output += delimiter;
  9109. output += type_to_string( t9); output += delimiter;
  9110. output += type_to_string(t10); output += delimiter;
  9111. output += type_to_string(t11);
  9112. }
  9113. template <typename T1, typename T2, typename T3, typename T4,
  9114. typename T5, typename T6, typename T7, typename T8,
  9115. typename T9, typename T10>
  9116. inline void construct(std::string& output,
  9117. const std::string& delimiter,
  9118. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9119. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  9120. const T9& t9, const T10& t10)
  9121. {
  9122. output += type_to_string(t1); output += delimiter;
  9123. output += type_to_string(t2); output += delimiter;
  9124. output += type_to_string(t3); output += delimiter;
  9125. output += type_to_string(t4); output += delimiter;
  9126. output += type_to_string(t5); output += delimiter;
  9127. output += type_to_string(t6); output += delimiter;
  9128. output += type_to_string(t7); output += delimiter;
  9129. output += type_to_string(t8); output += delimiter;
  9130. output += type_to_string(t9); output += delimiter;
  9131. output += type_to_string(t10);
  9132. }
  9133. template <typename T1, typename T2, typename T3, typename T4,
  9134. typename T5, typename T6, typename T7, typename T8,
  9135. typename T9>
  9136. inline void construct(std::string& output,
  9137. const std::string& delimiter,
  9138. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9139. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  9140. const T9& t9)
  9141. {
  9142. output += type_to_string(t1); output += delimiter;
  9143. output += type_to_string(t2); output += delimiter;
  9144. output += type_to_string(t3); output += delimiter;
  9145. output += type_to_string(t4); output += delimiter;
  9146. output += type_to_string(t5); output += delimiter;
  9147. output += type_to_string(t6); output += delimiter;
  9148. output += type_to_string(t7); output += delimiter;
  9149. output += type_to_string(t8); output += delimiter;
  9150. output += type_to_string(t9);
  9151. }
  9152. template <typename T1, typename T2, typename T3, typename T4,
  9153. typename T5, typename T6, typename T7, typename T8>
  9154. inline void construct(std::string& output,
  9155. const std::string& delimiter,
  9156. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9157. const T5& t5, const T6& t6, const T7& t7, const T8& t8)
  9158. {
  9159. output += type_to_string(t1); output += delimiter;
  9160. output += type_to_string(t2); output += delimiter;
  9161. output += type_to_string(t3); output += delimiter;
  9162. output += type_to_string(t4); output += delimiter;
  9163. output += type_to_string(t5); output += delimiter;
  9164. output += type_to_string(t6); output += delimiter;
  9165. output += type_to_string(t7); output += delimiter;
  9166. output += type_to_string(t8);
  9167. }
  9168. template <typename T1, typename T2, typename T3, typename T4,
  9169. typename T5, typename T6, typename T7>
  9170. inline void construct(std::string& output,
  9171. const std::string& delimiter,
  9172. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9173. const T5& t5, const T6& t6, const T7& t7)
  9174. {
  9175. output += type_to_string(t1); output += delimiter;
  9176. output += type_to_string(t2); output += delimiter;
  9177. output += type_to_string(t3); output += delimiter;
  9178. output += type_to_string(t4); output += delimiter;
  9179. output += type_to_string(t5); output += delimiter;
  9180. output += type_to_string(t6); output += delimiter;
  9181. output += type_to_string(t7);
  9182. }
  9183. template <typename T1, typename T2, typename T3, typename T4,
  9184. typename T5,typename T6>
  9185. inline void construct(std::string& output,
  9186. const std::string& delimiter,
  9187. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9188. const T5& t5, const T6& t6)
  9189. {
  9190. output += type_to_string(t1); output += delimiter;
  9191. output += type_to_string(t2); output += delimiter;
  9192. output += type_to_string(t3); output += delimiter;
  9193. output += type_to_string(t4); output += delimiter;
  9194. output += type_to_string(t5); output += delimiter;
  9195. output += type_to_string(t6);
  9196. }
  9197. template <typename T1, typename T2, typename T3, typename T4,
  9198. typename T5>
  9199. inline void construct(std::string& output,
  9200. const std::string& delimiter,
  9201. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9202. const T5& t5)
  9203. {
  9204. output += type_to_string(t1); output += delimiter;
  9205. output += type_to_string(t2); output += delimiter;
  9206. output += type_to_string(t3); output += delimiter;
  9207. output += type_to_string(t4); output += delimiter;
  9208. output += type_to_string(t5);
  9209. }
  9210. template <typename T1, typename T2, typename T3, typename T4>
  9211. inline void construct(std::string& output,
  9212. const std::string& delimiter,
  9213. const T1& t1, const T2& t2, const T3& t3, const T4& t4)
  9214. {
  9215. output += type_to_string(t1); output += delimiter;
  9216. output += type_to_string(t2); output += delimiter;
  9217. output += type_to_string(t3); output += delimiter;
  9218. output += type_to_string(t4);
  9219. }
  9220. template <typename T1, typename T2, typename T3>
  9221. inline void construct(std::string& output,
  9222. const std::string& delimiter,
  9223. const T1& t1, const T2& t2, const T3& t3)
  9224. {
  9225. output += type_to_string(t1); output += delimiter;
  9226. output += type_to_string(t2); output += delimiter;
  9227. output += type_to_string(t3);
  9228. }
  9229. template <typename T1, typename T2>
  9230. inline void construct(std::string& output,
  9231. const std::string& delimiter,
  9232. const T1& t1, const T2& t2)
  9233. {
  9234. output += type_to_string(t1); output += delimiter;
  9235. output += type_to_string(t2);
  9236. }
  9237. template <typename InputIterator>
  9238. inline void join(std::string& output,
  9239. const std::string& delimiter,
  9240. const InputIterator begin,
  9241. const InputIterator end)
  9242. {
  9243. InputIterator itr = begin;
  9244. while (end != itr)
  9245. {
  9246. output += type_to_string(*itr);
  9247. if (end == (++itr))
  9248. break;
  9249. else
  9250. output += delimiter;
  9251. }
  9252. }
  9253. template <typename InputIterator>
  9254. inline void join(std::string& output,
  9255. const std::string& delimiter,
  9256. const std::pair<InputIterator,InputIterator>& range)
  9257. {
  9258. InputIterator itr = range.first;
  9259. while (range.second != itr)
  9260. {
  9261. output += type_to_string(*itr);
  9262. if (range.second == (++itr))
  9263. break;
  9264. else
  9265. output += delimiter;
  9266. }
  9267. }
  9268. template <typename T,
  9269. typename Allocator,
  9270. template <typename,typename> class Sequence>
  9271. inline void join(std::string& output,
  9272. const std::string& delimiter,
  9273. const Sequence<T,Allocator>& sequence)
  9274. {
  9275. join(output,delimiter,sequence.begin(),sequence.end());
  9276. }
  9277. template <typename T,
  9278. typename Comparator,
  9279. typename Allocator>
  9280. inline void join(std::string& output,
  9281. const std::string& delimiter,
  9282. const std::set<T,Comparator,Allocator>& set)
  9283. {
  9284. join(output,delimiter,set.begin(),set.end());
  9285. }
  9286. template <typename T,
  9287. typename Comparator,
  9288. typename Allocator>
  9289. inline void join(std::string& output,
  9290. const std::string& delimiter,
  9291. const std::multiset<T,Comparator,Allocator>& multiset)
  9292. {
  9293. join(output,delimiter,multiset.begin(),multiset.end());
  9294. }
  9295. inline void join(std::string& output,
  9296. const std::string& delimiter,
  9297. int argc, char* argv[])
  9298. {
  9299. for (int i = 0; i < argc; ++i)
  9300. {
  9301. output += argv[i];
  9302. if (i < (argc - 1))
  9303. output += delimiter;
  9304. }
  9305. }
  9306. template <typename InputIterator>
  9307. inline std::string join(const std::string& delimiter,
  9308. const InputIterator begin,
  9309. const InputIterator end)
  9310. {
  9311. std::string output;
  9312. output.reserve(one_kilobyte);
  9313. join(output,delimiter,begin,end);
  9314. return output;
  9315. }
  9316. template <typename InputIterator>
  9317. inline std::string join(const std::string& delimiter,
  9318. const std::pair<InputIterator,InputIterator>& range)
  9319. {
  9320. std::string output;
  9321. output.reserve(one_kilobyte);
  9322. join(output,delimiter,range.first,range.second);
  9323. return output;
  9324. }
  9325. template <typename T,
  9326. typename Allocator,
  9327. template <typename,typename> class Sequence>
  9328. inline std::string join(const std::string& delimiter,
  9329. const Sequence<T,Allocator>& sequence)
  9330. {
  9331. if (sequence.empty())
  9332. return "";
  9333. else
  9334. return join(delimiter,sequence.begin(),sequence.end());
  9335. }
  9336. template <typename T,
  9337. typename Comparator,
  9338. typename Allocator>
  9339. inline std::string join(const std::string& delimiter,
  9340. const std::set<T,Comparator,Allocator>& set)
  9341. {
  9342. if (set.empty())
  9343. return "";
  9344. else
  9345. return join(delimiter,set.begin(),set.end());
  9346. }
  9347. template <typename T,
  9348. typename Comparator,
  9349. typename Allocator>
  9350. inline std::string join(const std::string& delimiter,
  9351. const std::multiset<T,Comparator,Allocator>& multiset)
  9352. {
  9353. if (multiset.empty())
  9354. return "";
  9355. else
  9356. return join(delimiter,multiset.begin(),multiset.end());
  9357. }
  9358. inline std::string join(const std::string& delimiter, int argc, char* argv[])
  9359. {
  9360. std::string result;
  9361. result.reserve(one_kilobyte);
  9362. join(result,delimiter,argc,argv);
  9363. return result;
  9364. }
  9365. template <typename InputIterator, typename Predicate>
  9366. inline void join_if(std::string& output,
  9367. const std::string& delimiter,
  9368. Predicate predicate,
  9369. const InputIterator begin,
  9370. const InputIterator end)
  9371. {
  9372. InputIterator itr = begin;
  9373. bool first_time = true;
  9374. while (end != itr)
  9375. {
  9376. if (predicate(*itr))
  9377. {
  9378. if (!first_time)
  9379. output += delimiter;
  9380. else
  9381. first_time = false;
  9382. output += type_to_string(*itr);
  9383. }
  9384. if (end == (++itr))
  9385. break;
  9386. }
  9387. }
  9388. template <typename InputIterator, typename Predicate>
  9389. inline void join_if(std::string& output,
  9390. const std::string& delimiter,
  9391. Predicate predicate,
  9392. const std::pair<InputIterator,InputIterator>& range)
  9393. {
  9394. InputIterator itr = range.first;
  9395. bool first_time = true;
  9396. while (range.second != itr)
  9397. {
  9398. if (predicate(*itr))
  9399. {
  9400. if (!first_time)
  9401. output += delimiter;
  9402. else
  9403. first_time = false;
  9404. output += type_to_string(*itr);
  9405. }
  9406. if (range.second == (++itr))
  9407. break;
  9408. }
  9409. }
  9410. template <typename T,
  9411. typename Predicate,
  9412. typename Allocator,
  9413. template <typename,typename> class Sequence>
  9414. inline void join_if(std::string& output,
  9415. const std::string& delimiter,
  9416. Predicate predicate,
  9417. const Sequence<T,Allocator>& sequence)
  9418. {
  9419. join_if(output,delimiter,predicate,sequence.begin(),sequence.end());
  9420. }
  9421. template <typename T,
  9422. typename Predicate,
  9423. typename Comparator,
  9424. typename Allocator>
  9425. inline void join_if(std::string& output,
  9426. const std::string& delimiter,
  9427. Predicate predicate,
  9428. const std::set<T,Comparator,Allocator>& set)
  9429. {
  9430. join_if(output,delimiter,predicate,set.begin(),set.end());
  9431. }
  9432. template <typename T,
  9433. typename Predicate,
  9434. typename Comparator,
  9435. typename Allocator>
  9436. inline void join_if(std::string& output,
  9437. const std::string& delimiter,
  9438. Predicate predicate,
  9439. const std::multiset<T,Comparator,Allocator>& multiset)
  9440. {
  9441. join_if(output,delimiter,predicate,multiset.begin(),multiset.end());
  9442. }
  9443. template <typename InputIterator, typename Predicate>
  9444. inline std::string join_if(const std::string& delimiter,
  9445. Predicate predicate,
  9446. const InputIterator begin,
  9447. const InputIterator end)
  9448. {
  9449. std::string output;
  9450. output.reserve(one_kilobyte);
  9451. join_if(output,delimiter,predicate,begin,end);
  9452. return output;
  9453. }
  9454. template <typename InputIterator, typename Predicate>
  9455. inline std::string join_if(const std::string& delimiter,
  9456. Predicate predicate,
  9457. const std::pair<InputIterator,InputIterator>& range)
  9458. {
  9459. std::string output;
  9460. output.reserve(one_kilobyte);
  9461. join_if(output,delimiter,predicate,range.first,range.second);
  9462. return output;
  9463. }
  9464. template <typename T,
  9465. typename Predicate,
  9466. typename Allocator,
  9467. template <typename,typename> class Sequence>
  9468. inline std::string join_if(const std::string& delimiter,
  9469. Predicate predicate,
  9470. const Sequence<T,Allocator>& sequence)
  9471. {
  9472. return join(delimiter,predicate,sequence.begin(),sequence.end());
  9473. }
  9474. template <typename T,
  9475. typename Predicate,
  9476. typename Comparator,
  9477. typename Allocator>
  9478. inline std::string join_if(const std::string& delimiter,
  9479. Predicate predicate,
  9480. const std::set<T,Comparator,Allocator>& set)
  9481. {
  9482. return join_if(delimiter,predicate,set.begin(),set.end());
  9483. }
  9484. template <typename T,
  9485. typename Predicate,
  9486. typename Comparator,
  9487. typename Allocator>
  9488. inline std::string join_if(const std::string& delimiter,
  9489. Predicate predicate,
  9490. const std::multiset<T,Comparator,Allocator>& multiset)
  9491. {
  9492. return join_if(delimiter,predicate,multiset.begin(),multiset.end());
  9493. }
  9494. class build_string
  9495. {
  9496. public:
  9497. build_string(const std::size_t& initial_size = 64)
  9498. {
  9499. data_.reserve(initial_size);
  9500. }
  9501. template <typename T>
  9502. inline build_string& operator << (const T& t)
  9503. {
  9504. data_ += type_to_string(t);
  9505. return (*this);
  9506. }
  9507. inline operator std::string () const
  9508. {
  9509. return data_;
  9510. }
  9511. inline std::string as_string() const
  9512. {
  9513. return data_;
  9514. }
  9515. inline operator const char* () const
  9516. {
  9517. return data_.data();
  9518. }
  9519. private:
  9520. std::string data_;
  9521. };
  9522. inline void replicate(const std::size_t& n,
  9523. const std::string& str,
  9524. std::string& output)
  9525. {
  9526. if (0 == n) return;
  9527. output.reserve(output.size() + (str.size() * n));
  9528. for (std::size_t i = 0; i < n; ++i)
  9529. {
  9530. output.append(str);
  9531. }
  9532. }
  9533. inline std::string replicate(const std::size_t& n,
  9534. const std::string& str)
  9535. {
  9536. std::string output;
  9537. replicate(n,str,output);
  9538. return output;
  9539. }
  9540. inline void replicate_inplace(const std::size_t& n,
  9541. std::string& str)
  9542. {
  9543. std::string temp_str = str;
  9544. str.reserve(str.size() + (str.size() * n));
  9545. for (std::size_t i = 0; i < n; ++i)
  9546. {
  9547. str.append(temp_str);
  9548. }
  9549. }
  9550. template <typename InputIterator>
  9551. inline void bracketize(std::string& output,
  9552. const std::string& pre,
  9553. const std::string& post,
  9554. const InputIterator begin,
  9555. const InputIterator end)
  9556. {
  9557. InputIterator itr = begin;
  9558. std::string s;
  9559. s.reserve(one_kilobyte);
  9560. while (end != itr)
  9561. {
  9562. s.clear();
  9563. s.append(pre);
  9564. s.append(type_to_string(*itr));
  9565. s.append(post);
  9566. output.append(s);
  9567. ++itr;
  9568. }
  9569. }
  9570. template <typename T,
  9571. typename Allocator,
  9572. template <typename,typename> class Sequence>
  9573. inline void bracketize(std::string& output,
  9574. const std::string& pre,
  9575. const std::string& post,
  9576. Sequence<T,Allocator>& sequence)
  9577. {
  9578. bracketize(output,pre,post,sequence.begin(),sequence.end());
  9579. }
  9580. template <typename T,
  9581. typename Comparator,
  9582. typename Allocator>
  9583. inline void bracketize(std::string& output,
  9584. const std::string& pre,
  9585. const std::string& post,
  9586. std::set<T,Comparator,Allocator>& set)
  9587. {
  9588. bracketize(output,pre,post,set.begin(),set.end());
  9589. }
  9590. template <typename T,
  9591. typename Comparator,
  9592. typename Allocator>
  9593. inline void bracketize(std::string& output,
  9594. const std::string& pre,
  9595. const std::string& post,
  9596. std::multiset<T,Comparator,Allocator>& multiset)
  9597. {
  9598. bracketize(output,pre,post,multiset.begin(),multiset.end());
  9599. }
  9600. template <typename InputIterator>
  9601. inline std::string bracketize(const std::string& pre,
  9602. const std::string& post,
  9603. const InputIterator begin,
  9604. const InputIterator end)
  9605. {
  9606. std::string output;
  9607. output.reserve(one_kilobyte);
  9608. bracketize(output,pre,post,begin,end);
  9609. return output;
  9610. }
  9611. template <typename T,
  9612. typename Allocator,
  9613. template <typename,typename> class Sequence>
  9614. inline std::string bracketize(const std::string& pre,
  9615. const std::string& post,
  9616. Sequence<T,Allocator>& sequence)
  9617. {
  9618. return bracketize(pre,post,sequence.begin(),sequence.end());
  9619. }
  9620. template <typename T,
  9621. typename Comparator,
  9622. typename Allocator>
  9623. inline std::string bracketize(const std::string& pre,
  9624. const std::string& post,
  9625. std::set<T,Comparator,Allocator>& set)
  9626. {
  9627. return bracketize(pre,post,set.begin(),set.end());
  9628. }
  9629. template <typename T,
  9630. typename Comparator,
  9631. typename Allocator>
  9632. inline std::string bracketize(const std::string& pre,
  9633. const std::string& post,
  9634. std::multiset<T,Comparator,Allocator>& multiset)
  9635. {
  9636. return bracketize(pre,post,multiset.begin(),multiset.end());
  9637. }
  9638. template <typename T>
  9639. struct interval_inserter
  9640. {
  9641. typedef T type;
  9642. interval_inserter(const std::size_t& interval, const T& t)
  9643. : count_(0),
  9644. interval_(interval),
  9645. t_(t)
  9646. {}
  9647. inline bool operator()(const type&)
  9648. {
  9649. if (++count_ == interval_)
  9650. {
  9651. count_ = 0;
  9652. return true;
  9653. }
  9654. else
  9655. return false;
  9656. }
  9657. inline T operator()()
  9658. {
  9659. return t_;
  9660. }
  9661. private:
  9662. std::size_t count_;
  9663. std::size_t interval_;
  9664. T t_;
  9665. };
  9666. template <typename Inserter,
  9667. typename InputIterator,
  9668. typename OutputIterator>
  9669. inline std::size_t inserter(Inserter ins,
  9670. const InputIterator begin, const InputIterator end,
  9671. OutputIterator out)
  9672. {
  9673. std::size_t size = 0;
  9674. InputIterator itr = begin;
  9675. while (end != itr)
  9676. {
  9677. (*out) = (*itr);
  9678. ++out;
  9679. if (ins(*itr++))
  9680. {
  9681. (*out) = ins();
  9682. ++out;
  9683. size += 2;
  9684. }
  9685. else
  9686. ++size;
  9687. }
  9688. return size;
  9689. }
  9690. template <typename Iterator, typename T>
  9691. inline void iota(Iterator begin, Iterator end, T value)
  9692. {
  9693. Iterator itr = begin;
  9694. while (end != itr)
  9695. {
  9696. (*itr) = value++;
  9697. ++itr;
  9698. }
  9699. }
  9700. template <typename T>
  9701. inline void iota(typename range::adapter<T>& r, T value)
  9702. {
  9703. iota(r.begin(),r.end(),value);
  9704. }
  9705. template <typename T,
  9706. typename Allocator,
  9707. template <typename,typename> class Sequence>
  9708. inline void iota(Sequence<T,Allocator>& sequence, std::size_t count, T value)
  9709. {
  9710. while (count)
  9711. {
  9712. sequence.push_back(value++);
  9713. --count;
  9714. }
  9715. }
  9716. template <typename T,
  9717. typename Comparator,
  9718. typename Allocator>
  9719. inline void iota(std::set<T,Comparator,Allocator>& set, std::size_t count, T value)
  9720. {
  9721. while (count)
  9722. {
  9723. set.insert(value++);
  9724. --count;
  9725. }
  9726. }
  9727. template <typename T,
  9728. typename Comparator,
  9729. typename Allocator>
  9730. inline void iota(std::multiset<T,Comparator,Allocator>& multiset, std::size_t count, T value)
  9731. {
  9732. while (count)
  9733. {
  9734. multiset.insert(value++);
  9735. --count;
  9736. }
  9737. }
  9738. template <typename OutputIterator, typename T>
  9739. inline void iota(std::size_t count, T value, OutputIterator out)
  9740. {
  9741. while (count)
  9742. {
  9743. (*out) = value++;
  9744. ++out;
  9745. --count;
  9746. }
  9747. }
  9748. template <typename T,
  9749. typename Allocator,
  9750. template <typename,typename> class Sequence>
  9751. inline void iota(Sequence<T,Allocator>& sequence, const T& value)
  9752. {
  9753. strtk::iota(sequence.begin(),sequence.end(),value);
  9754. }
  9755. template <typename T,
  9756. typename Comparator,
  9757. typename Allocator>
  9758. inline void iota(std::set<T,Comparator,Allocator>& set, const T& value)
  9759. {
  9760. strtk::iota(set.begin(),set.end(),value);
  9761. }
  9762. template <typename T,
  9763. typename Comparator,
  9764. typename Allocator>
  9765. inline void iota(std::multiset<T,Comparator,Allocator>& multiset, const T& value)
  9766. {
  9767. strtk::iota(multiset.begin(),multiset.end(),value);
  9768. }
  9769. template <typename InputIterator, typename OutputIterator>
  9770. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9771. const InputIterator begin, InputIterator end,
  9772. OutputIterator out)
  9773. {
  9774. // static assert: InputIterator must be of type std::string
  9775. InputIterator itr = begin;
  9776. while (end != itr)
  9777. {
  9778. const std::string& s = (*itr);
  9779. ++itr;
  9780. if (s.size() < r0)
  9781. continue;
  9782. (*out++) = s.substr(r0,std::min(r1,s.size()) - r0);
  9783. }
  9784. }
  9785. template <typename Allocator,
  9786. template <typename,typename> class Sequence,
  9787. typename OutputIterator>
  9788. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9789. const Sequence<std::string, Allocator>& sequence,
  9790. OutputIterator out)
  9791. {
  9792. cut(r0,r1,sequence.begin(),sequence.end(),out);
  9793. }
  9794. template <typename Iterator>
  9795. inline void cut_inplace(const std::size_t& r0, const std::size_t& r1,
  9796. const Iterator begin, const Iterator end)
  9797. {
  9798. // static assert: InputIterator must be of type std::string
  9799. Iterator itr = begin;
  9800. while (end != itr)
  9801. {
  9802. if ((*itr).size() >= r0)
  9803. {
  9804. (*itr) = (*itr).substr(r0,std::min(r1,(*itr).size()) - r0);
  9805. }
  9806. ++itr;
  9807. }
  9808. }
  9809. template <typename Allocator,
  9810. template <typename,typename> class Sequence>
  9811. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9812. const Sequence<std::string, Allocator>& sequence)
  9813. {
  9814. cut(r0,r1,sequence.begin(),sequence.end());
  9815. }
  9816. template <typename Comparator, typename Allocator>
  9817. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9818. const std::set<std::string, Comparator, Allocator>& set)
  9819. {
  9820. cut(r0,r1,set.begin(),set.end());
  9821. }
  9822. template <typename Comparator, typename Allocator>
  9823. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9824. const std::multiset<std::string, Comparator, Allocator>& multiset)
  9825. {
  9826. cut(r0,r1,multiset.begin(),multiset.end());
  9827. }
  9828. class translation_table
  9829. {
  9830. public:
  9831. translation_table(const std::string& itable, const std::string& otable)
  9832. {
  9833. if (itable.size() != otable.size())
  9834. {
  9835. throw std::runtime_error("translation_table() - Input/Output table size mismatch.");
  9836. }
  9837. strtk::iota(table_, table_ + 256, static_cast<unsigned char>(0));
  9838. for (std::size_t i = 0; i < itable.size(); ++i)
  9839. {
  9840. table_[static_cast<unsigned int>(itable[i])] = static_cast<unsigned char>(otable[i]);
  9841. }
  9842. }
  9843. inline char operator()(const char c) const
  9844. {
  9845. return static_cast<char>(table_[static_cast<unsigned int>(c)]);
  9846. }
  9847. inline unsigned char operator()(const unsigned char c) const
  9848. {
  9849. return static_cast<unsigned char>(table_[static_cast<unsigned int>(c)]);
  9850. }
  9851. private:
  9852. unsigned char table_[256];
  9853. };
  9854. inline std::string translate(const translation_table& trans_table, const std::string& s)
  9855. {
  9856. std::string result = s;
  9857. std::transform(result.begin(),result.end(),result.begin(),trans_table);
  9858. return result;
  9859. }
  9860. inline void translate_inplace(const translation_table& trans_table, std::string& s)
  9861. {
  9862. std::transform(s.begin(),s.end(),s.begin(),trans_table);
  9863. }
  9864. #ifdef strtk_enable_random
  9865. inline void generate_random_data(unsigned char* data,
  9866. std::size_t length,
  9867. unsigned int pre_gen_cnt = 0,
  9868. unsigned int seed = magic_seed)
  9869. {
  9870. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  9871. boost::uniform_int<unsigned int> dist(std::numeric_limits<unsigned int>::min(),std::numeric_limits<unsigned int>::max());
  9872. boost::variate_generator<boost::mt19937&, boost::uniform_int<unsigned int> > rnd(rng,dist);
  9873. if (pre_gen_cnt > 0)
  9874. {
  9875. while (pre_gen_cnt--) rnd();
  9876. }
  9877. unsigned char* itr = data;
  9878. unsigned int* x = 0;
  9879. while (length >= sizeof(unsigned int))
  9880. {
  9881. x = reinterpret_cast<unsigned int*>(itr);
  9882. (*x) = rnd();
  9883. itr += sizeof(unsigned int);
  9884. length -= sizeof(unsigned int);
  9885. }
  9886. if (length > 0)
  9887. {
  9888. itr -= (sizeof(unsigned int) - length);
  9889. x = reinterpret_cast<unsigned int*>(itr);
  9890. (*x) = rnd();
  9891. }
  9892. }
  9893. namespace details
  9894. {
  9895. struct rand_int_type_tag {};
  9896. struct rand_real_type_tag {};
  9897. template <typename T> struct supported_random_type {};
  9898. #define strtk_register_rand_int_type_tag(T)\
  9899. template<> struct supported_random_type<T> { typedef rand_int_type_tag type; enum { value = true }; };
  9900. #define strtk_register_rand_real_type_tag(T)\
  9901. template<> struct supported_random_type<T> { typedef rand_real_type_tag type; enum { value = true }; };
  9902. strtk_register_rand_int_type_tag(char)
  9903. strtk_register_rand_int_type_tag(unsigned char)
  9904. strtk_register_rand_int_type_tag(short)
  9905. strtk_register_rand_int_type_tag(int)
  9906. strtk_register_rand_int_type_tag(long)
  9907. strtk_register_rand_int_type_tag(unsigned short)
  9908. strtk_register_rand_int_type_tag(unsigned int)
  9909. strtk_register_rand_int_type_tag(unsigned long)
  9910. strtk_register_rand_real_type_tag(float)
  9911. strtk_register_rand_real_type_tag(double)
  9912. strtk_register_rand_real_type_tag(long double)
  9913. #undef strtk_register_rand_int_type_tag
  9914. #undef strtk_register_rand_real_type_tag
  9915. template <typename T, typename OutputIterator, typename RandomNumberGenerator>
  9916. inline void generate_random_values_impl(const std::size_t& count,
  9917. const T& min,
  9918. const T& max,
  9919. OutputIterator out,
  9920. RandomNumberGenerator& rng,
  9921. rand_int_type_tag)
  9922. {
  9923. // Note: The implied range will be: [min,max]
  9924. using namespace boost;
  9925. variate_generator<RandomNumberGenerator&,uniform_int<T> > rnd(rng,uniform_int<T>(min,max));
  9926. for (std::size_t i = 0; i < count; ++i, *out++ = rnd()) ;
  9927. }
  9928. template <typename T, typename OutputIterator, typename RandomNumberGenerator>
  9929. inline void generate_random_values_impl(const std::size_t& count,
  9930. const T& min,
  9931. const T& max,
  9932. OutputIterator out,
  9933. RandomNumberGenerator& rng,
  9934. rand_real_type_tag)
  9935. {
  9936. // Note: The implied range will be: [min,max)
  9937. using namespace boost;
  9938. variate_generator<RandomNumberGenerator&, uniform_real<T> > rnd(rng,uniform_real<T>(min,max));
  9939. for (std::size_t i = 0; i < count; ++i, *out++ = rnd()) ;
  9940. }
  9941. } // namespace details
  9942. class uniform_real_rng
  9943. {
  9944. private:
  9945. typedef boost::mt19937 rng_type;
  9946. typedef boost::variate_generator<rng_type, boost::uniform_real<double> > variate_type;
  9947. public:
  9948. uniform_real_rng(const std::size_t& seed = magic_seed,
  9949. std::size_t pregen = 0)
  9950. : rng_(static_cast<rng_type::result_type>(seed)),
  9951. rnd_(rng_,boost::uniform_real<double>(0.0,1.0))
  9952. {
  9953. while (pregen--) rng_();
  9954. }
  9955. inline double operator()()
  9956. {
  9957. return rnd_();
  9958. }
  9959. private:
  9960. rng_type rng_;
  9961. variate_type rnd_;
  9962. };
  9963. template <typename T, typename OutputIterator>
  9964. inline void generate_random_values(const std::size_t& count,
  9965. const T& min,
  9966. const T& max,
  9967. OutputIterator out,
  9968. const std::size_t& seed = magic_seed,
  9969. const std::size_t& pregen = 0)
  9970. {
  9971. typename details::supported_random_type<T>::type type;
  9972. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  9973. for (std::size_t i = 0; i++ < pregen; rng()) ;
  9974. generate_random_values_impl(count,min,max,out,rng,type);
  9975. }
  9976. template <typename T,
  9977. typename Allocator,
  9978. template <typename,typename> class Sequence>
  9979. inline void generate_random_values(const std::size_t& count,
  9980. const T& min,
  9981. const T& max,
  9982. Sequence<T,Allocator>& sequence,
  9983. const std::size_t& seed = magic_seed,
  9984. const std::size_t& pregen = 0)
  9985. {
  9986. typename details::supported_random_type<T>::type type;
  9987. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  9988. for (std::size_t i = 0; i++ < pregen; rng()) ;
  9989. generate_random_values_impl(count,min,max,std::back_inserter(sequence),rng,type);
  9990. }
  9991. template <typename Iterator,
  9992. typename RandomNumberGenerator,
  9993. typename OutputIterator>
  9994. inline void random_permutation(const Iterator begin, const Iterator end,
  9995. RandomNumberGenerator& rng,
  9996. OutputIterator out)
  9997. {
  9998. const std::size_t size = std::distance(begin,end);
  9999. if ((rng. min() < 0.0) || (rng.max() > 1.0)) return;
  10000. std::deque<std::size_t> index;
  10001. for (std::size_t i = 0; i < size; index.push_back(i++)) ;
  10002. while (!index.empty())
  10003. {
  10004. std::size_t idx = static_cast<std::size_t>(index.size() * rng());
  10005. (*out) = *(begin + index[idx]);
  10006. index.erase(index.begin() + idx);
  10007. ++out;
  10008. }
  10009. }
  10010. template <typename Iterator,
  10011. typename OutputIterator>
  10012. inline void random_permutation(const Iterator begin, const Iterator end,
  10013. OutputIterator out,
  10014. const std::size_t& seed = magic_seed,
  10015. const std::size_t& pregen = 0)
  10016. {
  10017. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  10018. for (std::size_t i = 0; i++ < pregen; rng()) ;
  10019. boost::uniform_real<double> dist(0.0,1.0);
  10020. boost::variate_generator<boost::mt19937&, boost::uniform_real<double> > rnd(rng,dist);
  10021. random_permutation(begin,end,rnd,out);
  10022. }
  10023. template <typename T,
  10024. typename Allocator,
  10025. template <typename,typename> class Sequence,
  10026. typename OutputIterator>
  10027. inline void random_permutation(const Sequence<T,Allocator>& sequence,
  10028. OutputIterator out,
  10029. const std::size_t& seed = magic_seed,
  10030. const std::size_t& pregen = 0)
  10031. {
  10032. random_permutation(sequence.begin(),sequence.end(),out,seed,pregen);
  10033. }
  10034. template <typename Iterator,
  10035. typename RandomNumberGenerator,
  10036. typename OutputIterator>
  10037. inline bool random_combination(const Iterator begin, const Iterator end,
  10038. std::size_t set_size,
  10039. RandomNumberGenerator& rng,
  10040. OutputIterator out)
  10041. {
  10042. const std::size_t size = std::distance(begin,end);
  10043. if ((size < set_size) || (rng. min() < 0.0) || (rng.max() > 1.0)) return false;
  10044. std::deque<std::size_t> index;
  10045. for (std::size_t i = 0; i < size; index.push_back(i++)) ;
  10046. while (set_size)
  10047. {
  10048. std::size_t idx = static_cast<std::size_t>(index.size() * rng());
  10049. (*out) = *(begin + index[idx]);
  10050. index.erase(index.begin() + idx);
  10051. ++out;
  10052. --set_size;
  10053. }
  10054. return true;
  10055. }
  10056. template <typename Iterator,
  10057. typename OutputIterator>
  10058. inline void random_combination(const Iterator begin, const Iterator end,
  10059. const std::size_t& set_size,
  10060. OutputIterator out,
  10061. const std::size_t& seed = magic_seed,
  10062. const std::size_t& pregen = 0)
  10063. {
  10064. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  10065. for (std::size_t i = 0; i++ < pregen; rng()) ;
  10066. boost::uniform_real<double> dist(0.0,1.0);
  10067. boost::variate_generator<boost::mt19937&, boost::uniform_real<double> > rnd(rng,dist);
  10068. random_combination(begin,end,set_size,rnd,out);
  10069. }
  10070. template <typename T,
  10071. typename Allocator,
  10072. template <typename,typename> class Sequence,
  10073. typename OutputIterator>
  10074. inline void random_combination(const Sequence<T,Allocator>& sequence,
  10075. const std::size_t& set_size,
  10076. OutputIterator out,
  10077. const std::size_t& seed = magic_seed,
  10078. const std::size_t& pregen = 0)
  10079. {
  10080. random_combination(sequence.begin(),sequence.end(),set_size,out,seed,pregen);
  10081. }
  10082. template <typename Iterator,
  10083. typename OutputIterator,
  10084. typename RandomNumberGenerator>
  10085. inline std::size_t select_k_randomly(const Iterator begin, const Iterator end,
  10086. const std::size_t k,
  10087. OutputIterator out,
  10088. RandomNumberGenerator& rng)
  10089. {
  10090. typedef typename std::iterator_traits<Iterator>::value_type T;
  10091. std::vector<T> selection;
  10092. selection.resize(k);
  10093. Iterator itr = begin;
  10094. std::size_t index = 0;
  10095. while ((index < k) && (end != itr))
  10096. {
  10097. selection[index] = (*itr);
  10098. ++index;
  10099. ++itr;
  10100. }
  10101. if (0 == index)
  10102. return 0;
  10103. else if (index < k)
  10104. {
  10105. std::copy(selection.begin(),selection.begin() + index, out);
  10106. return index;
  10107. }
  10108. double n = k + 1;
  10109. while (end != itr)
  10110. {
  10111. if (rng() < (k / n))
  10112. {
  10113. selection[static_cast<std::size_t>(rng() * k)] = (*itr);
  10114. }
  10115. ++itr;
  10116. ++n;
  10117. }
  10118. std::copy(selection.begin(),selection.end(),out);
  10119. return k;
  10120. }
  10121. template <typename Iterator,
  10122. typename OutputIterator,
  10123. typename RandomNumberGenerator>
  10124. inline void select_1_randomly(const Iterator begin, const Iterator end,
  10125. OutputIterator out,
  10126. RandomNumberGenerator& rng)
  10127. {
  10128. typedef typename std::iterator_traits<Iterator>::value_type T;
  10129. T selection;
  10130. if (begin == end)
  10131. return;
  10132. Iterator itr = begin;
  10133. std::size_t n = 0;
  10134. while (end != itr)
  10135. {
  10136. if (rng() < (1.0 / ++n))
  10137. {
  10138. selection = (*itr);
  10139. }
  10140. ++itr;
  10141. }
  10142. (*out) = selection;
  10143. ++out;
  10144. }
  10145. #endif // strtk_enable_random
  10146. template <typename Iterator>
  10147. inline bool next_combination(const Iterator first, Iterator k, const Iterator last)
  10148. {
  10149. /* Credits: Thomas Draper */
  10150. if ((first == last) || (first == k) || (last == k))
  10151. return false;
  10152. Iterator itr1 = first;
  10153. Iterator itr2 = last;
  10154. ++itr1;
  10155. if (last == itr1)
  10156. return false;
  10157. itr1 = last;
  10158. --itr1;
  10159. itr1 = k;
  10160. --itr2;
  10161. while (first != itr1)
  10162. {
  10163. if (*--itr1 < (*itr2))
  10164. {
  10165. Iterator j = k;
  10166. while (!((*itr1) < (*j))) ++j;
  10167. std::iter_swap(itr1,j);
  10168. ++itr1;
  10169. ++j;
  10170. itr2 = k;
  10171. std::rotate(itr1,j,last);
  10172. while (last != j)
  10173. {
  10174. ++j;
  10175. ++itr2;
  10176. }
  10177. std::rotate(k,itr2,last);
  10178. return true;
  10179. }
  10180. }
  10181. std::rotate(first,k,last);
  10182. return false;
  10183. }
  10184. template <typename T,
  10185. typename Allocator,
  10186. template <typename,typename> class Sequence>
  10187. inline bool next_combination(Sequence<T,Allocator>& sequence, const std::size_t& size)
  10188. {
  10189. return next_combination(sequence.begin(), sequence.begin() + size, sequence.end());
  10190. }
  10191. template <typename Iterator, typename Function>
  10192. inline void for_each_permutation(Iterator begin, Iterator end, Function function)
  10193. {
  10194. do
  10195. {
  10196. function(begin,end);
  10197. }
  10198. while (std::next_permutation(begin,end));
  10199. }
  10200. template <typename Iterator, typename Function>
  10201. inline bool for_each_permutation_conditional(Iterator begin, Iterator end, Function function)
  10202. {
  10203. do
  10204. {
  10205. if (!function(begin,end))
  10206. return false;
  10207. }
  10208. while (std::next_permutation(begin,end));
  10209. return true;
  10210. }
  10211. namespace details
  10212. {
  10213. /*
  10214. Credits:
  10215. (C) Copyright Howard Hinnant 2005-2011.
  10216. Use, modification and distribution are subject to the Boost Software License,
  10217. Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  10218. http://www.boost.org/LICENSE_1_0.txt).
  10219. */
  10220. template <typename Iterator>
  10221. static inline void rotate_discontinuous(Iterator first1, Iterator last1,
  10222. typename std::iterator_traits<Iterator>::difference_type d1,
  10223. Iterator first2, Iterator last2,
  10224. typename std::iterator_traits<Iterator>::difference_type d2)
  10225. {
  10226. using std::swap;
  10227. if (d1 <= d2)
  10228. std::rotate(first2, std::swap_ranges(first1, last1, first2), last2);
  10229. else
  10230. {
  10231. Iterator i1 = last1;
  10232. while (first2 != last2)
  10233. {
  10234. swap(*--i1,*--last2);
  10235. }
  10236. std::rotate(first1, i1, last1);
  10237. }
  10238. }
  10239. template <typename Iterator, class Function>
  10240. inline void combine_discontinuous(Iterator first1, Iterator last1, typename std::iterator_traits<Iterator>::difference_type d1,
  10241. Iterator first2, Iterator last2, typename std::iterator_traits<Iterator>::difference_type d2,
  10242. Function& f,
  10243. typename std::iterator_traits<Iterator>::difference_type d = 0)
  10244. {
  10245. typedef typename std::iterator_traits<Iterator>::difference_type D;
  10246. using std::swap;
  10247. if ((0 == d1) || (0 == d2))
  10248. return f();
  10249. if (1 == d1)
  10250. {
  10251. Iterator i2 = first2;
  10252. while (i2 != last2)
  10253. {
  10254. f();
  10255. swap(*first1, *i2);
  10256. ++i2;
  10257. }
  10258. }
  10259. else
  10260. {
  10261. Iterator f1p = first1;
  10262. std::advance(f1p,1);
  10263. Iterator i2 = first2;
  10264. D d22 = d2;
  10265. while (i2 != last2)
  10266. {
  10267. combine_discontinuous(f1p, last1, d1 - 1, i2, last2, d22, f, d + 1);
  10268. swap(*first1, *i2);
  10269. ++i2;
  10270. --d22;
  10271. }
  10272. }
  10273. f();
  10274. if (0 != d)
  10275. {
  10276. Iterator f2p = first2;
  10277. std::advance(f2p,1);
  10278. rotate_discontinuous(first1, last1, d1, f2p, last2, d2 - 1);
  10279. }
  10280. else
  10281. rotate_discontinuous(first1, last1, d1, first2, last2, d2);
  10282. }
  10283. template <typename Iterator, class Function>
  10284. inline bool combine_discontinuous_conditional(Iterator first1, Iterator last1, typename std::iterator_traits<Iterator>::difference_type d1,
  10285. Iterator first2, Iterator last2, typename std::iterator_traits<Iterator>::difference_type d2,
  10286. Function& f,
  10287. typename std::iterator_traits<Iterator>::difference_type d = 0)
  10288. {
  10289. typedef typename std::iterator_traits<Iterator>::difference_type D;
  10290. using std::swap;
  10291. if (d1 == 0 || d2 == 0)
  10292. return f();
  10293. if (d1 == 1)
  10294. {
  10295. for (Iterator i2 = first2; i2 != last2; ++i2)
  10296. {
  10297. if (!f())
  10298. return false;
  10299. swap(*first1, *i2);
  10300. }
  10301. }
  10302. else
  10303. {
  10304. Iterator f1p = first1;
  10305. std::advance(f1p,1);
  10306. Iterator i2 = first2;
  10307. for (D d22 = d2; i2 != last2; ++i2, --d22)
  10308. {
  10309. if (!combine_discontinuous_conditional(f1p, last1, d1-1, i2, last2, d22, f, d + 1))
  10310. return false;
  10311. swap(*first1, *i2);
  10312. }
  10313. }
  10314. if (!f())
  10315. return false;
  10316. if (d != 0)
  10317. {
  10318. Iterator f2p = first2;
  10319. std::advance(f2p,1);
  10320. rotate_discontinuous(first1, last1, d1, f2p, last2, d2 - 1);
  10321. }
  10322. else
  10323. rotate_discontinuous(first1, last1, d1, first2, last2, d2);
  10324. return true;
  10325. }
  10326. template <class Function, typename Iterator>
  10327. class bound_range
  10328. {
  10329. public:
  10330. bound_range(Function f, Iterator first, Iterator last)
  10331. : f_(f),
  10332. first_(first),
  10333. last_(last)
  10334. {}
  10335. inline void operator()()
  10336. {
  10337. f_(first_,last_);
  10338. }
  10339. private:
  10340. inline bound_range& operator=(const bound_range&);
  10341. Function f_;
  10342. Iterator first_;
  10343. Iterator last_;
  10344. };
  10345. template <class Function, typename Iterator>
  10346. class bound_range_conditional
  10347. {
  10348. public:
  10349. bound_range_conditional(Function f, Iterator first, Iterator last)
  10350. : f_(f),
  10351. first_(first),
  10352. last_(last)
  10353. {}
  10354. inline bool operator()()
  10355. {
  10356. return f_(first_,last_);
  10357. }
  10358. private:
  10359. inline bound_range_conditional& operator=(const bound_range_conditional&);
  10360. Function f_;
  10361. Iterator first_;
  10362. Iterator last_;
  10363. };
  10364. }
  10365. template <typename Iterator, typename Function>
  10366. inline void for_each_combination(Iterator begin, Iterator end,
  10367. const std::size_t& size,
  10368. Function function)
  10369. {
  10370. if (static_cast<typename std::iterator_traits<Iterator>::difference_type>(size) > std::distance(begin,end))
  10371. return;
  10372. Iterator mid = begin + size;
  10373. details::bound_range<Function&, Iterator> func(function,begin,mid);
  10374. details::combine_discontinuous(begin, mid,
  10375. std::distance(begin,mid),
  10376. mid, end,
  10377. std::distance(mid,end),
  10378. func);
  10379. }
  10380. template <typename Iterator, typename Function>
  10381. inline void for_each_combination_conditional(Iterator begin, Iterator end,
  10382. const std::size_t& size,
  10383. Function function)
  10384. {
  10385. if (static_cast<typename std::iterator_traits<Iterator>::difference_type>(size) > std::distance(begin,end))
  10386. return;
  10387. Iterator mid = begin + size;
  10388. details::bound_range_conditional<Function&, Iterator> func(function,begin,mid);
  10389. details::combine_discontinuous_conditional(begin, mid,
  10390. std::distance(begin,mid),
  10391. mid, end,
  10392. std::distance(mid,end),
  10393. func);
  10394. }
  10395. inline unsigned long long int n_choose_k(const unsigned long long int& n, const unsigned long long int& k)
  10396. {
  10397. if (n < k) return 0;
  10398. if (0 == n) return 0;
  10399. if (0 == k) return 1;
  10400. if (n == k) return 1;
  10401. if (1 == k) return n;
  10402. typedef unsigned long long int value_type;
  10403. class n_choose_k_impl
  10404. {
  10405. public:
  10406. n_choose_k_impl(value_type* table, const value_type& dimension)
  10407. : table_(table),
  10408. dimension_(dimension / 2)
  10409. {}
  10410. inline value_type& lookup(const value_type& n, const value_type& k)
  10411. {
  10412. const std::size_t difference = static_cast<std::size_t>(n - k);
  10413. return table_[static_cast<std::size_t>((dimension_ * n) + std::min<value_type>(k,difference))];
  10414. }
  10415. inline value_type compute(const value_type& n, const value_type& k)
  10416. {
  10417. // n-Choose-k = (n-1)-Choose-(k-1) + (n-1)-Choose-k
  10418. if ((0 == k) || (k == n))
  10419. return 1;
  10420. value_type v1 = lookup(n - 1,k - 1);
  10421. if (0 == v1)
  10422. v1 = lookup(n - 1,k - 1) = compute(n - 1,k - 1);
  10423. value_type v2 = lookup(n - 1,k);
  10424. if (0 == v2)
  10425. v2 = lookup(n - 1,k) = compute(n - 1,k);
  10426. return v1 + v2;
  10427. }
  10428. value_type* table_;
  10429. const value_type dimension_;
  10430. private:
  10431. inline n_choose_k_impl& operator=(const n_choose_k_impl&)
  10432. {
  10433. return *this;
  10434. }
  10435. };
  10436. static const std::size_t static_table_dim = 100;
  10437. static const std::size_t static_table_size = static_cast<std::size_t>((static_table_dim * static_table_dim) / 2);
  10438. static value_type static_table[static_table_size];
  10439. static bool static_table_initialized = false;
  10440. if (!static_table_initialized && (n <= static_table_dim))
  10441. {
  10442. std::fill_n(static_table,static_table_size,0);
  10443. static_table_initialized = true;
  10444. }
  10445. const std::size_t table_size = static_cast<std::size_t>(n * (n / 2) + (n & 1));
  10446. unsigned long long int dimension = static_table_dim;
  10447. value_type* table = 0;
  10448. if (table_size <= static_table_size)
  10449. table = static_table;
  10450. else
  10451. {
  10452. dimension = n;
  10453. table = new value_type[table_size];
  10454. std::fill_n(table,table_size,0ULL);
  10455. }
  10456. value_type result = n_choose_k_impl(table,dimension).compute(n,k);
  10457. if (table != static_table)
  10458. delete [] table;
  10459. return result;
  10460. }
  10461. inline void initialize_n_choose_k()
  10462. {
  10463. const unsigned long long int max_n = 100ULL;
  10464. for (unsigned long long int n = 0; n < max_n; ++n)
  10465. {
  10466. for (unsigned long long int k = 0; k < max_n; ++k)
  10467. {
  10468. n_choose_k(n,k);
  10469. }
  10470. }
  10471. }
  10472. template <typename OutputIterator>
  10473. inline void nth_combination_sequence(unsigned long long int n,
  10474. const std::size_t& r,
  10475. const std::size_t& k,
  10476. OutputIterator out,
  10477. const bool complete_index = true)
  10478. {
  10479. //Compute the indicies for the n'th combination of r-choose-k
  10480. //n must be in the range [0,r-choose-k)
  10481. typedef unsigned long long int value_type;
  10482. std::vector<std::size_t> index_list(k,0);
  10483. value_type j = 0;
  10484. value_type x = 0;
  10485. ++n;
  10486. for (std::size_t i = 1; i <= (k - 1); ++i)
  10487. {
  10488. index_list[i - 1] = 0;
  10489. if (1 < i)
  10490. {
  10491. index_list[i - 1] = index_list[i - 2];
  10492. }
  10493. do
  10494. {
  10495. index_list[i - 1] += 1;
  10496. j = n_choose_k(r - index_list[i - 1], k - i);
  10497. x += j;
  10498. }
  10499. while (n > x);
  10500. x -= j;
  10501. }
  10502. index_list[k - 1] = index_list[k - 2] + static_cast<std::size_t>(n) - static_cast<std::size_t>(x);
  10503. for (std::size_t i = 0; i < index_list.size(); --index_list[i++]);
  10504. std::copy(index_list.begin(),index_list.end(),out);
  10505. if (complete_index)
  10506. {
  10507. std::vector<unsigned int> exist_table(r,0);
  10508. for (std::size_t i = 0; i < index_list.size(); ++i)
  10509. {
  10510. exist_table[index_list[i]] = 1;
  10511. }
  10512. for (std::size_t i = 0; i < exist_table.size(); ++i)
  10513. {
  10514. if (0 == exist_table[i])
  10515. {
  10516. (*out) = i;
  10517. ++out;
  10518. }
  10519. }
  10520. }
  10521. }
  10522. template <typename InputIterator, typename OutputIterator>
  10523. inline void nth_combination_sequence(const std::size_t& n,
  10524. const std::size_t& k,
  10525. const InputIterator begin,
  10526. const InputIterator end,
  10527. OutputIterator out,
  10528. const bool complete_index = true)
  10529. {
  10530. const std::size_t length = std::distance(begin,end);
  10531. std::vector<std::size_t> index_list;
  10532. nth_combination_sequence(n,length,k,std::back_inserter(index_list),complete_index);
  10533. for (std::size_t i = 0; i < index_list.size(); ++i)
  10534. {
  10535. (*out) = *(begin + index_list[i]);
  10536. ++out;
  10537. }
  10538. }
  10539. template <typename OutputIterator>
  10540. inline void nth_permutation_sequence(std::size_t n, const std::size_t k, OutputIterator out)
  10541. {
  10542. //Note: n in [0,k!)
  10543. std::vector<std::size_t> factorid (k,0);
  10544. std::vector<std::size_t> permutate(k,0);
  10545. factorid[0] = 1;
  10546. for (std::size_t i = 1; i < k; ++i)
  10547. {
  10548. factorid[i] = factorid[i - 1] * i;
  10549. }
  10550. for (std::size_t i = 0; i < k; ++i)
  10551. {
  10552. permutate[i] = n / factorid[k - i - 1];
  10553. n = n % factorid[k - i - 1];
  10554. }
  10555. for (std::size_t i = k - 1; i > 0; --i)
  10556. {
  10557. for (int j = static_cast<int>(i - 1); j >= 0; --j)
  10558. {
  10559. if (permutate[j] <= permutate[i])
  10560. {
  10561. ++permutate[i];
  10562. }
  10563. }
  10564. }
  10565. for (std::size_t i = 0; i < k; ++i)
  10566. {
  10567. *(out++) = permutate[i];
  10568. }
  10569. }
  10570. template <typename InputIterator, typename OutputIterator>
  10571. inline void nth_permutation_sequence(std::size_t n,
  10572. const InputIterator begin,
  10573. const InputIterator end,
  10574. OutputIterator out)
  10575. {
  10576. const std::size_t size = std::distance(begin,end);
  10577. std::vector<std::size_t> index_list(size,0);
  10578. nth_permutation_sequence(n,size,index_list.begin());
  10579. for (std::size_t i = 0; i < size; ++i)
  10580. {
  10581. *(out++) = (begin + index_list[i]);
  10582. }
  10583. }
  10584. inline std::string nth_permutation_sequence(const std::size_t& n, const std::string& s)
  10585. {
  10586. std::vector<std::size_t> index_list(s.size(),0);
  10587. nth_permutation_sequence(n,s.size(),index_list.begin());
  10588. std::string result;
  10589. result.reserve(s.size());
  10590. for (std::size_t i = 0; i < index_list.size(); ++i)
  10591. {
  10592. result += s[index_list[i]];
  10593. }
  10594. return result;
  10595. }
  10596. template <typename Iterator>
  10597. class combination_iterator : public std::iterator<std::forward_iterator_tag,
  10598. std::pair<Iterator,Iterator>,
  10599. void,
  10600. void>
  10601. {
  10602. public:
  10603. typedef Iterator iterator;
  10604. typedef const iterator const_iterator;
  10605. typedef std::pair<Iterator,Iterator> range_type;
  10606. explicit inline combination_iterator(const std::size_t& k,
  10607. iterator begin, iterator end,
  10608. const bool sorted = true)
  10609. : begin_(begin),
  10610. end_(end),
  10611. middle_(begin + k),
  10612. current_combination_(begin_,middle_)
  10613. {
  10614. if (!sorted)
  10615. {
  10616. std::sort(begin,end);
  10617. }
  10618. }
  10619. template <typename T,
  10620. typename Allocator,
  10621. template <typename,typename> class Sequence>
  10622. explicit inline combination_iterator(const std::size_t& k,
  10623. Sequence<T,Allocator>& seq,
  10624. const bool sorted = true)
  10625. : begin_(seq.begin()),
  10626. end_(seq.end()),
  10627. middle_(begin_ + k),
  10628. current_combination_(begin_,middle_)
  10629. {
  10630. if (!sorted)
  10631. {
  10632. std::sort(begin_,end_);
  10633. }
  10634. }
  10635. explicit inline combination_iterator(const std::size_t& k,
  10636. std::string& str,
  10637. const bool sorted = true)
  10638. : begin_(const_cast<char*>(str.data())),
  10639. end_(const_cast<char*>(str.data() + str.size())),
  10640. middle_(begin_ + k),
  10641. current_combination_(begin_,middle_)
  10642. {
  10643. if (!sorted)
  10644. {
  10645. std::sort(begin_,end_);
  10646. }
  10647. }
  10648. inline combination_iterator(iterator end)
  10649. : begin_(end),
  10650. end_(end),
  10651. middle_(end),
  10652. current_combination_(end,end)
  10653. {}
  10654. inline combination_iterator(const std::string& str)
  10655. : begin_(const_cast<char*>(str.data() + str.size())),
  10656. end_(begin_),
  10657. middle_(end_),
  10658. current_combination_(end_,end_)
  10659. {}
  10660. template <typename T,
  10661. typename Allocator,
  10662. template <typename,typename> class Sequence>
  10663. explicit inline combination_iterator(Sequence<T,Allocator>& seq)
  10664. : begin_(seq.end()),
  10665. end_(seq.end()),
  10666. middle_(end_),
  10667. current_combination_(end_,end_)
  10668. {}
  10669. inline combination_iterator& operator++()
  10670. {
  10671. if (begin_ != end_)
  10672. {
  10673. if (!next_combination(begin_,middle_,end_))
  10674. {
  10675. begin_ = middle_ = end_;
  10676. }
  10677. }
  10678. return (*this);
  10679. }
  10680. inline combination_iterator operator++(int)
  10681. {
  10682. combination_iterator tmp = *this;
  10683. this->operator++();
  10684. return tmp;
  10685. }
  10686. inline combination_iterator& operator+=(const int inc)
  10687. {
  10688. if (inc > 0)
  10689. {
  10690. for (int i = 0; i < inc; ++i, ++(*this)) ;
  10691. }
  10692. return (*this);
  10693. }
  10694. inline range_type operator*() const
  10695. {
  10696. return current_combination_;
  10697. }
  10698. inline bool operator==(const combination_iterator& itr) const
  10699. {
  10700. return (begin_ == itr.begin_ ) &&
  10701. (end_ == itr.end_ ) &&
  10702. (middle_ == itr.middle_);
  10703. }
  10704. inline bool operator!=(const combination_iterator& itr) const
  10705. {
  10706. return !operator==(itr);
  10707. }
  10708. protected:
  10709. iterator begin_;
  10710. iterator end_;
  10711. iterator middle_;
  10712. range_type current_combination_;
  10713. };
  10714. namespace fast
  10715. {
  10716. /*
  10717. Note: The following routines perform no sanity checks at all
  10718. upon the input data. Hence they should only be used with
  10719. data that is known to be completely 'valid'.
  10720. */
  10721. namespace details
  10722. {
  10723. template <typename Iterator, int N>
  10724. struct all_digits_check_impl
  10725. {
  10726. static inline bool process(Iterator)
  10727. {
  10728. throw std::runtime_error("all_digits_check_impl - unsupported value for N.");
  10729. }
  10730. };
  10731. template <typename Iterator>
  10732. struct all_digits_check_impl<Iterator,19>
  10733. {
  10734. static inline bool process(Iterator itr)
  10735. {
  10736. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10737. all_digits_check_impl<Iterator,18>::process(itr + 1);
  10738. }
  10739. };
  10740. template <typename Iterator>
  10741. struct all_digits_check_impl<Iterator,18>
  10742. {
  10743. static inline bool process(Iterator itr)
  10744. {
  10745. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10746. all_digits_check_impl<Iterator,17>::process(itr + 1);
  10747. }
  10748. };
  10749. template <typename Iterator>
  10750. struct all_digits_check_impl<Iterator,17>
  10751. {
  10752. static inline bool process(Iterator itr)
  10753. {
  10754. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10755. all_digits_check_impl<Iterator,16>::process(itr + 1);
  10756. }
  10757. };
  10758. template <typename Iterator>
  10759. struct all_digits_check_impl<Iterator,16>
  10760. {
  10761. static inline bool process(Iterator itr)
  10762. {
  10763. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  10764. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  10765. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  10766. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  10767. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  10768. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  10769. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  10770. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  10771. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  10772. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  10773. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  10774. static_cast<unsigned char>(itr[11] - '0') < 10 &&
  10775. static_cast<unsigned char>(itr[12] - '0') < 10 &&
  10776. static_cast<unsigned char>(itr[13] - '0') < 10 &&
  10777. static_cast<unsigned char>(itr[14] - '0') < 10 &&
  10778. static_cast<unsigned char>(itr[15] - '0') < 10;
  10779. }
  10780. };
  10781. template <typename Iterator>
  10782. struct all_digits_check_impl<Iterator,15>
  10783. {
  10784. static inline bool process(Iterator itr)
  10785. {
  10786. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  10787. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  10788. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  10789. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  10790. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  10791. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  10792. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  10793. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  10794. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  10795. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  10796. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  10797. static_cast<unsigned char>(itr[11] - '0') < 10 &&
  10798. static_cast<unsigned char>(itr[12] - '0') < 10 &&
  10799. static_cast<unsigned char>(itr[13] - '0') < 10 &&
  10800. static_cast<unsigned char>(itr[14] - '0') < 10;
  10801. }
  10802. };
  10803. template <typename Iterator>
  10804. struct all_digits_check_impl<Iterator,14>
  10805. {
  10806. static inline bool process(Iterator itr)
  10807. {
  10808. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  10809. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  10810. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  10811. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  10812. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  10813. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  10814. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  10815. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  10816. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  10817. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  10818. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  10819. static_cast<unsigned char>(itr[11] - '0') < 10 &&
  10820. static_cast<unsigned char>(itr[12] - '0') < 10 &&
  10821. static_cast<unsigned char>(itr[13] - '0') < 10;
  10822. }
  10823. };
  10824. template <typename Iterator>
  10825. struct all_digits_check_impl<Iterator,13>
  10826. {
  10827. static inline bool process(Iterator itr)
  10828. {
  10829. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  10830. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  10831. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  10832. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  10833. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  10834. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  10835. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  10836. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  10837. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  10838. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  10839. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  10840. static_cast<unsigned char>(itr[11] - '0') < 10 &&
  10841. static_cast<unsigned char>(itr[12] - '0') < 10;
  10842. }
  10843. };
  10844. template <typename Iterator>
  10845. struct all_digits_check_impl<Iterator,12>
  10846. {
  10847. static inline bool process(Iterator itr)
  10848. {
  10849. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  10850. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  10851. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  10852. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  10853. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  10854. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  10855. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  10856. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  10857. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  10858. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  10859. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  10860. static_cast<unsigned char>(itr[11] - '0') < 10;
  10861. }
  10862. };
  10863. template <typename Iterator>
  10864. struct all_digits_check_impl<Iterator,11>
  10865. {
  10866. static inline bool process(Iterator itr)
  10867. {
  10868. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  10869. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  10870. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  10871. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  10872. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  10873. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  10874. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  10875. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  10876. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  10877. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  10878. static_cast<unsigned char>(itr[10] - '0') < 10;
  10879. }
  10880. };
  10881. template <typename Iterator>
  10882. struct all_digits_check_impl<Iterator,10>
  10883. {
  10884. static inline bool process(Iterator itr)
  10885. {
  10886. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10887. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  10888. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  10889. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  10890. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  10891. static_cast<unsigned char>(itr[5] - '0') < 10 &&
  10892. static_cast<unsigned char>(itr[6] - '0') < 10 &&
  10893. static_cast<unsigned char>(itr[7] - '0') < 10 &&
  10894. static_cast<unsigned char>(itr[8] - '0') < 10 &&
  10895. static_cast<unsigned char>(itr[9] - '0') < 10;
  10896. }
  10897. };
  10898. template <typename Iterator>
  10899. struct all_digits_check_impl<Iterator,9>
  10900. {
  10901. static inline bool process(Iterator itr)
  10902. {
  10903. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10904. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  10905. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  10906. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  10907. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  10908. static_cast<unsigned char>(itr[5] - '0') < 10 &&
  10909. static_cast<unsigned char>(itr[6] - '0') < 10 &&
  10910. static_cast<unsigned char>(itr[7] - '0') < 10 &&
  10911. static_cast<unsigned char>(itr[8] - '0') < 10;
  10912. }
  10913. };
  10914. template <typename Iterator>
  10915. struct all_digits_check_impl<Iterator,8>
  10916. {
  10917. static inline bool process(Iterator itr)
  10918. {
  10919. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10920. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  10921. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  10922. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  10923. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  10924. static_cast<unsigned char>(itr[5] - '0') < 10 &&
  10925. static_cast<unsigned char>(itr[6] - '0') < 10 &&
  10926. static_cast<unsigned char>(itr[7] - '0') < 10;
  10927. }
  10928. };
  10929. template <typename Iterator>
  10930. struct all_digits_check_impl<Iterator,7>
  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. }
  10942. };
  10943. template <typename Iterator>
  10944. struct all_digits_check_impl<Iterator,6>
  10945. {
  10946. static inline bool process(Iterator itr)
  10947. {
  10948. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10949. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  10950. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  10951. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  10952. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  10953. static_cast<unsigned char>(itr[5] - '0') < 10;
  10954. }
  10955. };
  10956. template <typename Iterator>
  10957. struct all_digits_check_impl<Iterator,5>
  10958. {
  10959. static inline bool process(Iterator itr)
  10960. {
  10961. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10962. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  10963. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  10964. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  10965. static_cast<unsigned char>(itr[4] - '0') < 10;
  10966. }
  10967. };
  10968. template <typename Iterator>
  10969. struct all_digits_check_impl<Iterator,4>
  10970. {
  10971. static inline bool process(Iterator itr)
  10972. {
  10973. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10974. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  10975. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  10976. static_cast<unsigned char>(itr[3] - '0') < 10;
  10977. }
  10978. };
  10979. template <typename Iterator>
  10980. struct all_digits_check_impl<Iterator,3>
  10981. {
  10982. static inline bool process(Iterator itr)
  10983. {
  10984. return
  10985. static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10986. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  10987. static_cast<unsigned char>(itr[2] - '0') < 10;
  10988. }
  10989. };
  10990. template <typename Iterator>
  10991. struct all_digits_check_impl<Iterator,2>
  10992. {
  10993. static inline bool process(Iterator itr)
  10994. {
  10995. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  10996. static_cast<unsigned char>(itr[ 1] - '0') < 10;
  10997. }
  10998. };
  10999. template <typename Iterator>
  11000. struct all_digits_check_impl<Iterator,1>
  11001. {
  11002. static inline bool process(Iterator itr)
  11003. {
  11004. return static_cast<unsigned char>(itr[ 0] - '0') < 10;
  11005. }
  11006. };
  11007. template <typename Iterator>
  11008. struct all_digits_check_impl<Iterator,0>
  11009. {
  11010. static inline bool process(Iterator)
  11011. {
  11012. return false;
  11013. }
  11014. };
  11015. template <typename T, typename Iterator, int N>
  11016. struct numeric_convert_impl
  11017. {
  11018. static inline void process(Iterator, T&)
  11019. { throw std::runtime_error("numeric_convert_impl::process( - unsupported value for N."); }
  11020. };
  11021. template <typename T, typename Iterator>
  11022. struct numeric_convert_impl<T,Iterator,19>
  11023. {
  11024. static inline void process(Iterator itr, T& t)
  11025. {
  11026. strtk::fast::details::numeric_convert_impl<T,Iterator,18>::process(itr + 1,t);
  11027. t += static_cast<T>((itr[0] - '0') * 1000000000000000000LL);
  11028. }
  11029. };
  11030. template <typename T, typename Iterator>
  11031. struct numeric_convert_impl<T,Iterator,18>
  11032. {
  11033. static inline void process(Iterator itr, T& t)
  11034. {
  11035. strtk::fast::details::numeric_convert_impl<T,Iterator,17>::process(itr + 1,t);
  11036. t += static_cast<T>((itr[0] - '0') * 100000000000000000LL);
  11037. }
  11038. };
  11039. template <typename T, typename Iterator>
  11040. struct numeric_convert_impl<T,Iterator,17>
  11041. {
  11042. static inline void process(Iterator itr, T& t)
  11043. {
  11044. numeric_convert_impl<T,Iterator,16>::process(itr + 1,t);
  11045. t += static_cast<T>((itr[0] - '0') * 10000000000000000LL);
  11046. }
  11047. };
  11048. template <typename T, typename Iterator>
  11049. struct numeric_convert_impl<T,Iterator,16>
  11050. {
  11051. static inline void process(Iterator itr, T& t)
  11052. {
  11053. T x = static_cast<T>((itr[ 0] - '0') * 1000000000000000LL);
  11054. x += static_cast<T>((itr[ 1] - '0') * 100000000000000LL);
  11055. x += static_cast<T>((itr[ 2] - '0') * 10000000000000LL);
  11056. x += static_cast<T>((itr[ 3] - '0') * 1000000000000LL);
  11057. x += static_cast<T>((itr[ 4] - '0') * 100000000000LL);
  11058. x += static_cast<T>((itr[ 5] - '0') * 10000000000LL);
  11059. x += static_cast<T>((itr[ 6] - '0') * 1000000000LL);
  11060. x += static_cast<T>((itr[ 7] - '0') * 100000000LL);
  11061. x += static_cast<T>((itr[ 8] - '0') * 10000000LL);
  11062. x += static_cast<T>((itr[ 9] - '0') * 1000000LL);
  11063. x += static_cast<T>((itr[10] - '0') * 100000LL);
  11064. x += static_cast<T>((itr[11] - '0') * 10000LL);
  11065. x += static_cast<T>((itr[12] - '0') * 1000LL);
  11066. x += static_cast<T>((itr[13] - '0') * 100LL);
  11067. x += static_cast<T>((itr[14] - '0') * 10LL);
  11068. x += static_cast<T>((itr[15] - '0') );
  11069. t = x;
  11070. }
  11071. };
  11072. template <typename T, typename Iterator>
  11073. struct numeric_convert_impl<T,Iterator,15>
  11074. {
  11075. static inline void process(Iterator itr, T& t)
  11076. {
  11077. T x = static_cast<T>((itr[ 0] - '0') * 100000000000000LL);
  11078. x += static_cast<T>((itr[ 1] - '0') * 10000000000000LL);
  11079. x += static_cast<T>((itr[ 2] - '0') * 1000000000000LL);
  11080. x += static_cast<T>((itr[ 3] - '0') * 100000000000LL);
  11081. x += static_cast<T>((itr[ 4] - '0') * 10000000000LL);
  11082. x += static_cast<T>((itr[ 5] - '0') * 1000000000LL);
  11083. x += static_cast<T>((itr[ 6] - '0') * 100000000LL);
  11084. x += static_cast<T>((itr[ 7] - '0') * 10000000LL);
  11085. x += static_cast<T>((itr[ 8] - '0') * 1000000LL);
  11086. x += static_cast<T>((itr[ 9] - '0') * 100000LL);
  11087. x += static_cast<T>((itr[10] - '0') * 10000LL);
  11088. x += static_cast<T>((itr[11] - '0') * 1000LL);
  11089. x += static_cast<T>((itr[12] - '0') * 100LL);
  11090. x += static_cast<T>((itr[13] - '0') * 10LL);
  11091. x += static_cast<T>((itr[14] - '0') );
  11092. t = x;
  11093. }
  11094. };
  11095. template <typename T, typename Iterator>
  11096. struct numeric_convert_impl<T,Iterator,14>
  11097. {
  11098. static inline void process(Iterator itr, T& t)
  11099. {
  11100. T x = static_cast<T>((itr[ 0] - '0') * 10000000000000LL);
  11101. x += static_cast<T>((itr[ 1] - '0') * 1000000000000LL);
  11102. x += static_cast<T>((itr[ 2] - '0') * 100000000000LL);
  11103. x += static_cast<T>((itr[ 3] - '0') * 10000000000LL);
  11104. x += static_cast<T>((itr[ 4] - '0') * 1000000000LL);
  11105. x += static_cast<T>((itr[ 5] - '0') * 100000000LL);
  11106. x += static_cast<T>((itr[ 6] - '0') * 10000000LL);
  11107. x += static_cast<T>((itr[ 7] - '0') * 1000000LL);
  11108. x += static_cast<T>((itr[ 8] - '0') * 100000LL);
  11109. x += static_cast<T>((itr[ 9] - '0') * 10000LL);
  11110. x += static_cast<T>((itr[10] - '0') * 1000LL);
  11111. x += static_cast<T>((itr[11] - '0') * 100LL);
  11112. x += static_cast<T>((itr[12] - '0') * 10LL);
  11113. x += static_cast<T>((itr[13] - '0') );
  11114. t = x;
  11115. }
  11116. };
  11117. template <typename T, typename Iterator>
  11118. struct numeric_convert_impl<T,Iterator,13>
  11119. {
  11120. static inline void process(Iterator itr, T& t)
  11121. {
  11122. T x = static_cast<T>((itr[ 0] - '0') * 1000000000000LL);
  11123. x += static_cast<T>((itr[ 1] - '0') * 100000000000LL);
  11124. x += static_cast<T>((itr[ 2] - '0') * 10000000000LL);
  11125. x += static_cast<T>((itr[ 3] - '0') * 1000000000LL);
  11126. x += static_cast<T>((itr[ 4] - '0') * 100000000LL);
  11127. x += static_cast<T>((itr[ 5] - '0') * 10000000LL);
  11128. x += static_cast<T>((itr[ 6] - '0') * 1000000LL);
  11129. x += static_cast<T>((itr[ 7] - '0') * 100000LL);
  11130. x += static_cast<T>((itr[ 8] - '0') * 10000LL);
  11131. x += static_cast<T>((itr[ 9] - '0') * 1000LL);
  11132. x += static_cast<T>((itr[10] - '0') * 100LL);
  11133. x += static_cast<T>((itr[11] - '0') * 10LL);
  11134. x += static_cast<T>((itr[12] - '0') );
  11135. t = x;
  11136. }
  11137. };
  11138. template <typename T, typename Iterator>
  11139. struct numeric_convert_impl<T,Iterator,12>
  11140. {
  11141. static inline void process(Iterator itr, T& t)
  11142. {
  11143. T x = static_cast<T>((itr[ 0] - '0') * 100000000000LL);
  11144. x += static_cast<T>((itr[ 1] - '0') * 10000000000LL);
  11145. x += static_cast<T>((itr[ 2] - '0') * 1000000000LL);
  11146. x += static_cast<T>((itr[ 3] - '0') * 100000000LL);
  11147. x += static_cast<T>((itr[ 4] - '0') * 10000000LL);
  11148. x += static_cast<T>((itr[ 5] - '0') * 1000000LL);
  11149. x += static_cast<T>((itr[ 6] - '0') * 100000LL);
  11150. x += static_cast<T>((itr[ 7] - '0') * 10000LL);
  11151. x += static_cast<T>((itr[ 8] - '0') * 1000LL);
  11152. x += static_cast<T>((itr[ 9] - '0') * 100LL);
  11153. x += static_cast<T>((itr[10] - '0') * 10LL);
  11154. x += static_cast<T>((itr[11] - '0') );
  11155. t = x;
  11156. }
  11157. };
  11158. template <typename T, typename Iterator>
  11159. struct numeric_convert_impl<T,Iterator,11>
  11160. {
  11161. static inline void process(Iterator itr, T& t)
  11162. {
  11163. T x = static_cast<T>((itr[ 0] - '0') * 10000000000LL);
  11164. x += static_cast<T>((itr[ 1] - '0') * 1000000000LL);
  11165. x += static_cast<T>((itr[ 2] - '0') * 100000000LL);
  11166. x += static_cast<T>((itr[ 3] - '0') * 10000000LL);
  11167. x += static_cast<T>((itr[ 4] - '0') * 1000000LL);
  11168. x += static_cast<T>((itr[ 5] - '0') * 100000LL);
  11169. x += static_cast<T>((itr[ 6] - '0') * 10000LL);
  11170. x += static_cast<T>((itr[ 7] - '0') * 1000LL);
  11171. x += static_cast<T>((itr[ 8] - '0') * 100LL);
  11172. x += static_cast<T>((itr[ 9] - '0') * 10LL);
  11173. x += static_cast<T>((itr[10] - '0') );
  11174. t = x;
  11175. }
  11176. };
  11177. template <typename T, typename Iterator>
  11178. struct numeric_convert_impl<T,Iterator,10>
  11179. {
  11180. static inline void process(Iterator itr, T& t)
  11181. {
  11182. T x = static_cast<T>((itr[0] - '0') * 1000000000);
  11183. x += static_cast<T>((itr[1] - '0') * 100000000);
  11184. x += static_cast<T>((itr[2] - '0') * 10000000);
  11185. x += static_cast<T>((itr[3] - '0') * 1000000);
  11186. x += static_cast<T>((itr[4] - '0') * 100000);
  11187. x += static_cast<T>((itr[5] - '0') * 10000);
  11188. x += static_cast<T>((itr[6] - '0') * 1000);
  11189. x += static_cast<T>((itr[7] - '0') * 100);
  11190. x += static_cast<T>((itr[8] - '0') * 10);
  11191. x += static_cast<T>((itr[9] - '0') );
  11192. t = x;
  11193. }
  11194. };
  11195. template <typename T, typename Iterator>
  11196. struct numeric_convert_impl<T,Iterator,9>
  11197. {
  11198. static inline void process(Iterator itr, T& t)
  11199. {
  11200. T x = static_cast<T>((itr[0] - '0') * 100000000);
  11201. x += static_cast<T>((itr[1] - '0') * 10000000);
  11202. x += static_cast<T>((itr[2] - '0') * 1000000);
  11203. x += static_cast<T>((itr[3] - '0') * 100000);
  11204. x += static_cast<T>((itr[4] - '0') * 10000);
  11205. x += static_cast<T>((itr[5] - '0') * 1000);
  11206. x += static_cast<T>((itr[6] - '0') * 100);
  11207. x += static_cast<T>((itr[7] - '0') * 10);
  11208. x += static_cast<T>((itr[8] - '0') );
  11209. t = x;
  11210. }
  11211. };
  11212. template <typename T, typename Iterator>
  11213. struct numeric_convert_impl<T,Iterator,8>
  11214. {
  11215. static inline void process(Iterator itr, T& t)
  11216. {
  11217. T x = static_cast<T>((itr[0] - '0') * 10000000);
  11218. x += static_cast<T>((itr[1] - '0') * 1000000);
  11219. x += static_cast<T>((itr[2] - '0') * 100000);
  11220. x += static_cast<T>((itr[3] - '0') * 10000);
  11221. x += static_cast<T>((itr[4] - '0') * 1000);
  11222. x += static_cast<T>((itr[5] - '0') * 100);
  11223. x += static_cast<T>((itr[6] - '0') * 10);
  11224. x += static_cast<T>((itr[7] - '0') );
  11225. t = x;
  11226. }
  11227. };
  11228. template <typename T, typename Iterator>
  11229. struct numeric_convert_impl<T,Iterator,7>
  11230. {
  11231. static inline void process(Iterator itr, T& t)
  11232. {
  11233. T x = static_cast<T>((itr[0] - '0') * 1000000);
  11234. x += static_cast<T>((itr[1] - '0') * 100000);
  11235. x += static_cast<T>((itr[2] - '0') * 10000);
  11236. x += static_cast<T>((itr[3] - '0') * 1000);
  11237. x += static_cast<T>((itr[4] - '0') * 100);
  11238. x += static_cast<T>((itr[5] - '0') * 10);
  11239. x += static_cast<T>((itr[6] - '0') );
  11240. t = x;
  11241. }
  11242. };
  11243. template <typename T, typename Iterator>
  11244. struct numeric_convert_impl<T,Iterator,6>
  11245. {
  11246. static inline void process(Iterator itr, T& t)
  11247. {
  11248. T x = static_cast<T>((itr[0] - '0') * 100000);
  11249. x += static_cast<T>((itr[1] - '0') * 10000);
  11250. x += static_cast<T>((itr[2] - '0') * 1000);
  11251. x += static_cast<T>((itr[3] - '0') * 100);
  11252. x += static_cast<T>((itr[4] - '0') * 10);
  11253. x += static_cast<T>((itr[5] - '0') );
  11254. t = x;
  11255. }
  11256. };
  11257. template <typename T, typename Iterator>
  11258. struct numeric_convert_impl<T,Iterator,5>
  11259. {
  11260. static inline void process(Iterator itr, T& t)
  11261. {
  11262. T x = static_cast<T>((itr[0] - '0') * 10000);
  11263. x += static_cast<T>((itr[1] - '0') * 1000);
  11264. x += static_cast<T>((itr[2] - '0') * 100);
  11265. x += static_cast<T>((itr[3] - '0') * 10);
  11266. x += static_cast<T>((itr[4] - '0') );
  11267. t = x;
  11268. }
  11269. };
  11270. template <typename T, typename Iterator>
  11271. struct numeric_convert_impl<T,Iterator,4>
  11272. {
  11273. static inline void process(Iterator itr, T& t)
  11274. {
  11275. T x = static_cast<T>((itr[0] - '0') * 1000);
  11276. x += static_cast<T>((itr[1] - '0') * 100);
  11277. x += static_cast<T>((itr[2] - '0') * 10);
  11278. x += static_cast<T>((itr[3] - '0') );
  11279. t = x;
  11280. }
  11281. };
  11282. template <typename T, typename Iterator>
  11283. struct numeric_convert_impl<T,Iterator,3>
  11284. {
  11285. static inline void process(Iterator itr, T& t)
  11286. {
  11287. T x = static_cast<T>((itr[0] - '0') * 100);
  11288. x += static_cast<T>((itr[1] - '0') * 10);
  11289. x += static_cast<T>((itr[2] - '0') );
  11290. t = x;
  11291. }
  11292. };
  11293. template <typename T, typename Iterator>
  11294. struct numeric_convert_impl<T,Iterator,2>
  11295. {
  11296. static inline void process(Iterator itr, T& t)
  11297. {
  11298. T x = static_cast<T>((itr[0] - '0') * 10);
  11299. x += static_cast<T>((itr[1] - '0') );
  11300. t = x;
  11301. }
  11302. };
  11303. template <typename T, typename Iterator>
  11304. struct numeric_convert_impl<T,Iterator,1>
  11305. {
  11306. static inline void process(Iterator itr, T& t)
  11307. {
  11308. t = static_cast<T>((itr[0] - '0'));
  11309. }
  11310. };
  11311. template <typename T, typename Iterator>
  11312. struct numeric_convert_impl<T,Iterator,0>
  11313. {
  11314. static inline void process(Iterator, T& t)
  11315. {
  11316. t = 0;
  11317. }
  11318. };
  11319. template <typename T, typename NoneSignedTag>
  11320. inline bool negate(T&, NoneSignedTag)
  11321. {
  11322. return false;
  11323. }
  11324. template <typename T>
  11325. inline bool negate(T& t, strtk::details::signed_type_tag)
  11326. {
  11327. t = -t;
  11328. return true;
  11329. }
  11330. } // namespace details
  11331. template <int N, typename Iterator>
  11332. inline bool all_digits_check(Iterator itr)
  11333. {
  11334. typedef typename strtk::details::is_valid_iterator<Iterator>::type itr_type;
  11335. return details::all_digits_check_impl<Iterator,N>::process(itr);
  11336. }
  11337. template <int N, typename Iterator>
  11338. inline bool all_digits_check(const std::string& s)
  11339. {
  11340. return all_digits_check<N,const char*>(s.data());
  11341. }
  11342. template <typename Iterator>
  11343. inline bool all_digits_check(const std::size_t& n, Iterator itr)
  11344. {
  11345. switch (n)
  11346. {
  11347. case 0 : return details::all_digits_check_impl<Iterator, 0>::process(itr);
  11348. case 1 : return details::all_digits_check_impl<Iterator, 1>::process(itr);
  11349. case 2 : return details::all_digits_check_impl<Iterator, 2>::process(itr);
  11350. case 3 : return details::all_digits_check_impl<Iterator, 3>::process(itr);
  11351. case 4 : return details::all_digits_check_impl<Iterator, 4>::process(itr);
  11352. case 5 : return details::all_digits_check_impl<Iterator, 5>::process(itr);
  11353. case 6 : return details::all_digits_check_impl<Iterator, 6>::process(itr);
  11354. case 7 : return details::all_digits_check_impl<Iterator, 7>::process(itr);
  11355. case 8 : return details::all_digits_check_impl<Iterator, 8>::process(itr);
  11356. case 9 : return details::all_digits_check_impl<Iterator, 9>::process(itr);
  11357. case 10 : return details::all_digits_check_impl<Iterator,10>::process(itr);
  11358. case 11 : return details::all_digits_check_impl<Iterator,11>::process(itr);
  11359. case 12 : return details::all_digits_check_impl<Iterator,12>::process(itr);
  11360. case 13 : return details::all_digits_check_impl<Iterator,13>::process(itr);
  11361. case 14 : return details::all_digits_check_impl<Iterator,14>::process(itr);
  11362. case 15 : return details::all_digits_check_impl<Iterator,15>::process(itr);
  11363. case 16 : return details::all_digits_check_impl<Iterator,16>::process(itr);
  11364. case 17 : return details::all_digits_check_impl<Iterator,17>::process(itr);
  11365. case 18 : return details::all_digits_check_impl<Iterator,18>::process(itr);
  11366. case 19 : return details::all_digits_check_impl<Iterator,19>::process(itr);
  11367. default : return false;
  11368. }
  11369. }
  11370. template <typename Iterator>
  11371. inline bool all_digits_check(Iterator begin, Iterator end)
  11372. {
  11373. return all_digits_check(std::distance(begin,end),begin);
  11374. }
  11375. inline bool all_digits_check(const std::string& s)
  11376. {
  11377. return all_digits_check(s.size(),s.data());
  11378. }
  11379. template <int N, typename Iterator>
  11380. inline bool signed_all_digits_check(Iterator itr)
  11381. {
  11382. if (('-' == (*itr)) || ('+' == (*itr)))
  11383. return all_digits_check<Iterator,N - 1>((itr + 1));
  11384. else
  11385. return all_digits_check<Iterator,N>(itr);
  11386. }
  11387. template <typename Iterator>
  11388. inline bool signed_all_digits_check(const std::size_t& n, Iterator itr)
  11389. {
  11390. if (('-' == (*itr)) || ('+' == (*itr)))
  11391. return all_digits_check(n - 1,(itr + 1));
  11392. else
  11393. return all_digits_check(n,itr);
  11394. }
  11395. template <int N>
  11396. inline bool signed_all_digits_check(const std::string& s)
  11397. {
  11398. return signed_all_digits_check<N,const char*>(s.data());
  11399. }
  11400. template <typename Iterator>
  11401. inline bool signed_all_digits_check(Iterator begin, Iterator end)
  11402. {
  11403. return signed_all_digits_check(std::distance(begin,end),begin);
  11404. }
  11405. inline bool signed_all_digits_check(const std::string& s)
  11406. {
  11407. return signed_all_digits_check(s.size(),s.data());
  11408. }
  11409. template <int N, typename T, typename Iterator>
  11410. inline void numeric_convert(Iterator itr, T& t, const bool digit_check = false)
  11411. {
  11412. typedef typename strtk::details::is_valid_iterator<Iterator>::type itr_type;
  11413. if (digit_check)
  11414. {
  11415. if (!all_digits_check<N,Iterator>(itr))
  11416. {
  11417. t = 0;
  11418. return;
  11419. }
  11420. }
  11421. details::numeric_convert_impl<T,Iterator,N>::process(itr,t);
  11422. }
  11423. template <int N, typename T>
  11424. inline void numeric_convert(const std::string& s, T& t, const bool digit_check = false)
  11425. {
  11426. numeric_convert<N,T,const char*>(s.data(),t,digit_check);
  11427. }
  11428. template <typename T, typename Iterator>
  11429. inline bool numeric_convert(const std::size_t& n,
  11430. Iterator itr, T& t,
  11431. const bool digit_check = false)
  11432. {
  11433. if (digit_check)
  11434. {
  11435. if (!all_digits_check(n,itr))
  11436. {
  11437. return false;
  11438. }
  11439. }
  11440. switch (n)
  11441. {
  11442. case 0 : details::numeric_convert_impl<T,Iterator, 0>::process(itr,t); return true;
  11443. case 1 : details::numeric_convert_impl<T,Iterator, 1>::process(itr,t); return true;
  11444. case 2 : details::numeric_convert_impl<T,Iterator, 2>::process(itr,t); return true;
  11445. case 3 : details::numeric_convert_impl<T,Iterator, 3>::process(itr,t); return true;
  11446. case 4 : details::numeric_convert_impl<T,Iterator, 4>::process(itr,t); return true;
  11447. case 5 : details::numeric_convert_impl<T,Iterator, 5>::process(itr,t); return true;
  11448. case 6 : details::numeric_convert_impl<T,Iterator, 6>::process(itr,t); return true;
  11449. case 7 : details::numeric_convert_impl<T,Iterator, 7>::process(itr,t); return true;
  11450. case 8 : details::numeric_convert_impl<T,Iterator, 8>::process(itr,t); return true;
  11451. case 9 : details::numeric_convert_impl<T,Iterator, 9>::process(itr,t); return true;
  11452. case 10 : details::numeric_convert_impl<T,Iterator,10>::process(itr,t); return true;
  11453. case 11 : details::numeric_convert_impl<T,Iterator,11>::process(itr,t); return true;
  11454. case 12 : details::numeric_convert_impl<T,Iterator,12>::process(itr,t); return true;
  11455. case 13 : details::numeric_convert_impl<T,Iterator,13>::process(itr,t); return true;
  11456. case 14 : details::numeric_convert_impl<T,Iterator,14>::process(itr,t); return true;
  11457. case 15 : details::numeric_convert_impl<T,Iterator,15>::process(itr,t); return true;
  11458. case 16 : details::numeric_convert_impl<T,Iterator,16>::process(itr,t); return true;
  11459. case 17 : details::numeric_convert_impl<T,Iterator,17>::process(itr,t); return true;
  11460. case 18 : details::numeric_convert_impl<T,Iterator,18>::process(itr,t); return true;
  11461. case 19 : details::numeric_convert_impl<T,Iterator,19>::process(itr,t); return true;
  11462. default : return false;
  11463. }
  11464. }
  11465. template <typename T>
  11466. inline void numeric_convert(const std::string& s, T& t, const bool digit_check = false)
  11467. {
  11468. numeric_convert(s.size(),s.data(),t,digit_check);
  11469. }
  11470. template <int N, typename T, typename Iterator>
  11471. inline void signed_numeric_convert(Iterator itr, T& t, const bool digit_check = false)
  11472. {
  11473. if ('-' == (*itr))
  11474. {
  11475. numeric_convert<N - 1,T,Iterator>((itr + 1),t,digit_check);
  11476. typename strtk::details::supported_conversion_to_type<T>::type type;
  11477. details::negate(t,type);
  11478. }
  11479. else if ('+' == (*itr))
  11480. {
  11481. numeric_convert<N - 1,T,Iterator>((itr + 1),t,digit_check);
  11482. }
  11483. else
  11484. numeric_convert<N,T,Iterator>(itr,t,digit_check);
  11485. }
  11486. template <typename T, typename Iterator>
  11487. inline bool signed_numeric_convert(const std::size_t& n,
  11488. Iterator itr,
  11489. T& t,
  11490. const bool digit_check = false)
  11491. {
  11492. if ('-' == (*itr))
  11493. {
  11494. bool result = numeric_convert((n - 1),(itr + 1),t,digit_check);
  11495. typename strtk::details::supported_conversion_to_type<T>::type type;
  11496. return details::negate<T>(t,type) && result;
  11497. }
  11498. else if ('+' == (*itr))
  11499. {
  11500. return numeric_convert((n - 1),(itr + 1),t,digit_check);
  11501. }
  11502. else
  11503. return numeric_convert(n,itr,t,digit_check);
  11504. }
  11505. template <int N, typename T>
  11506. inline void signed_numeric_convert(const std::string& s,
  11507. T& t,
  11508. const bool digit_check = false)
  11509. {
  11510. signed_numeric_convert<N,T,const char*>(s.data(),t,digit_check);
  11511. }
  11512. template <typename T>
  11513. inline bool signed_numeric_convert(const std::string& s,
  11514. T& t,
  11515. const bool digit_check = false)
  11516. {
  11517. return signed_numeric_convert<T,const char*>(s.size(),s.data(),t,digit_check);
  11518. }
  11519. } // namespace fast
  11520. namespace binary
  11521. {
  11522. namespace details
  11523. {
  11524. namespace details_endian
  11525. {
  11526. #if (defined(__LITTLE_ENDIAN__)) ||\
  11527. (defined(WIN32)) ||\
  11528. (defined(__MINGW32_VERSION)) ||\
  11529. (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
  11530. static const bool __le_result = true;
  11531. static const bool __be_result = false;
  11532. #else
  11533. static const bool __le_result = false;
  11534. static const bool __be_result = true;
  11535. #endif
  11536. }
  11537. static inline bool is_little_endian()
  11538. {
  11539. //Is the current architecture/platform little-endian?
  11540. return details_endian::__le_result;
  11541. }
  11542. static inline bool is_big_endian()
  11543. {
  11544. return details_endian::__be_result;
  11545. }
  11546. static inline unsigned short convert(const unsigned short v)
  11547. {
  11548. //static_assert(2 == sizeof(v),"");
  11549. return ((v >> 8) & 0x00FF) | ((v << 8) & 0xFFFF);
  11550. }
  11551. static inline unsigned int convert(const unsigned int v)
  11552. {
  11553. //static_assert(4 == sizeof(v),"");
  11554. return ((v >> 24) & 0x000000FF) | ((v << 24) & 0x0000FF00) |
  11555. ((v << 8) & 0x00FF0000) | ((v >> 8) & 0xFF000000);
  11556. }
  11557. static inline unsigned long long int convert(const unsigned long long int v)
  11558. {
  11559. //static_assert(8 == sizeof(v),"");
  11560. return ((v >> 56) & 0x00000000000000FFLL) | ((v << 56) & 0xFF00000000000000LL) |
  11561. ((v >> 40) & 0x000000000000FF00LL) | ((v << 40) & 0x00FF000000000000LL) |
  11562. ((v >> 24) & 0x0000000000FF0000LL) | ((v << 24) & 0x0000FF0000000000LL) |
  11563. ((v >> 8) & 0x00000000FF000000LL) | ((v << 8) & 0x000000FF00000000LL) ;
  11564. }
  11565. static inline short convert(const short v)
  11566. {
  11567. return static_cast<short>(convert(static_cast<unsigned short>(v)));
  11568. }
  11569. static inline int convert(const int v)
  11570. {
  11571. return static_cast<int>(convert(static_cast<unsigned int>(v)));
  11572. }
  11573. static inline unsigned long long int convert(const long long int v)
  11574. {
  11575. return static_cast<long long>(convert(static_cast<unsigned long long int>(v)));
  11576. }
  11577. static inline unsigned short convert_to_be(const unsigned short v)
  11578. {
  11579. if (is_little_endian()) convert(v);
  11580. return v;
  11581. }
  11582. static inline unsigned int convert_to_be(const unsigned int v)
  11583. {
  11584. if (is_little_endian()) convert(v);
  11585. return v;
  11586. }
  11587. static inline unsigned long long int convert_to_be(const unsigned long long int v)
  11588. {
  11589. if (is_little_endian()) convert(v);
  11590. return v;
  11591. }
  11592. static inline short convert_to_be(const short v)
  11593. {
  11594. if (is_little_endian()) convert(v);
  11595. return v;
  11596. }
  11597. static inline int convert_to_be(const int v)
  11598. {
  11599. if (is_little_endian()) convert(v);
  11600. return v;
  11601. }
  11602. static inline unsigned long long int convert_to_be(const long long int v)
  11603. {
  11604. if (is_little_endian()) convert(v);
  11605. return v;
  11606. }
  11607. static inline unsigned short convert_to_le(const unsigned short v)
  11608. {
  11609. if (is_big_endian()) convert(v);
  11610. return v;
  11611. }
  11612. static inline unsigned int convert_to_le(const unsigned int v)
  11613. {
  11614. if (is_big_endian()) convert(v);
  11615. return v;
  11616. }
  11617. static inline unsigned long long int convert_to_le(const unsigned long long int v)
  11618. {
  11619. if (is_big_endian()) convert(v);
  11620. return v;
  11621. }
  11622. static inline short convert_to_le(const short v)
  11623. {
  11624. if (is_big_endian()) convert(v);
  11625. return v;
  11626. }
  11627. static inline int convert_to_le(const int v)
  11628. {
  11629. if (is_big_endian()) convert(v);
  11630. return v;
  11631. }
  11632. static inline unsigned long long int convert_to_le(const long long int v)
  11633. {
  11634. if (is_big_endian()) convert(v);
  11635. return v;
  11636. }
  11637. class marker
  11638. {
  11639. private:
  11640. typedef std::pair<std::size_t,char*> mark_type;
  11641. public:
  11642. inline bool reset(std::size_t& v1, char*& v2)
  11643. {
  11644. if (stack_.empty())
  11645. return false;
  11646. v1 = stack_.top().first;
  11647. v2 = stack_.top().second;
  11648. stack_.pop();
  11649. return true;
  11650. }
  11651. inline void mark(const std::size_t& v1,char* v2)
  11652. {
  11653. stack_.push(std::make_pair(v1,v2));
  11654. }
  11655. private:
  11656. std::stack<mark_type> stack_;
  11657. };
  11658. }
  11659. class reader
  11660. {
  11661. public:
  11662. // should be sourced from cstdint
  11663. typedef unsigned int uint32_t;
  11664. typedef unsigned short uint16_t;
  11665. typedef unsigned char uint8_t;
  11666. typedef unsigned long long int uint64_t;
  11667. template <typename T>
  11668. reader(T* buffer,
  11669. const std::size_t& buffer_length)
  11670. : original_buffer_(reinterpret_cast<char*>(buffer)),
  11671. buffer_(reinterpret_cast<char*>(buffer)),
  11672. buffer_length_(buffer_length * sizeof(T)),
  11673. amount_read_sofar_(0)
  11674. {}
  11675. inline bool operator!() const
  11676. {
  11677. return (0 == buffer_length_) ||
  11678. (0 == original_buffer_) ||
  11679. (0 == buffer_);
  11680. }
  11681. inline void reset(const bool clear_buffer = false)
  11682. {
  11683. amount_read_sofar_ = 0;
  11684. buffer_ = original_buffer_;
  11685. if (clear_buffer)
  11686. clear();
  11687. }
  11688. inline std::size_t position() const
  11689. {
  11690. return amount_read_sofar_;
  11691. }
  11692. inline const char* position_ptr() const
  11693. {
  11694. return buffer_ ;
  11695. }
  11696. inline std::size_t amount_read()
  11697. {
  11698. return amount_read_sofar_;
  11699. }
  11700. inline bool rewind(const std::size_t& n_bytes)
  11701. {
  11702. if (n_bytes <= amount_read_sofar_)
  11703. {
  11704. amount_read_sofar_ -= n_bytes;
  11705. buffer_ -= n_bytes;
  11706. return true;
  11707. }
  11708. else
  11709. return false;
  11710. }
  11711. inline bool seek(const int& n_bytes)
  11712. {
  11713. if (n_bytes < 0)
  11714. return rewind(-n_bytes);
  11715. else if (n_bytes > 0)
  11716. {
  11717. if ((amount_read_sofar_ + n_bytes) <= buffer_length_)
  11718. {
  11719. amount_read_sofar_ += n_bytes;
  11720. buffer_ += n_bytes;
  11721. return true;
  11722. }
  11723. else
  11724. return false;
  11725. }
  11726. else
  11727. return true;
  11728. }
  11729. inline void clear()
  11730. {
  11731. reset();
  11732. std::memset(buffer_,0x00,buffer_length_);
  11733. }
  11734. template <typename T>
  11735. inline bool operator()(T*& data, uint32_t& length, const bool read_length = true)
  11736. {
  11737. if (read_length && !operator()(length))
  11738. return false;
  11739. const std::size_t raw_size = length * sizeof(T);
  11740. if (!buffer_capacity_ok(raw_size))
  11741. return false;
  11742. if (read_length)
  11743. {
  11744. data = new T[length];
  11745. }
  11746. std::copy(buffer_, buffer_ + raw_size, reinterpret_cast<char*>(data));
  11747. buffer_ += raw_size;
  11748. amount_read_sofar_ += raw_size;
  11749. return true;
  11750. }
  11751. template <typename T>
  11752. inline bool operator()(T*& data, uint64_t& length, const bool read_length = true)
  11753. {
  11754. uint32_t l = 0;
  11755. if (read_length)
  11756. l = static_cast<uint32_t>(length);
  11757. if (!operator()(data,l,read_length))
  11758. return false;
  11759. if (read_length)
  11760. length = l;
  11761. return true;
  11762. }
  11763. inline bool operator()(std::string& output)
  11764. {
  11765. uint32_t length = 0;
  11766. if (!operator()(length))
  11767. return false;
  11768. if (!buffer_capacity_ok(length))
  11769. return false;
  11770. output.resize(length);
  11771. std::copy(buffer_,
  11772. buffer_ + length,
  11773. const_cast<char*>(output.data()));
  11774. buffer_ += length;
  11775. amount_read_sofar_ += length;
  11776. return true;
  11777. }
  11778. template <typename T1, typename T2>
  11779. inline bool operator()(std::pair<T1,T2>& p)
  11780. {
  11781. if (!operator()(p.first))
  11782. return false;
  11783. if (!operator()(p.second))
  11784. return false;
  11785. return true;
  11786. }
  11787. template <typename T,
  11788. typename Allocator,
  11789. template <typename,typename> class Sequence>
  11790. inline bool operator()(Sequence<T,Allocator>& seq)
  11791. {
  11792. uint32_t size = 0;
  11793. if (!read_pod(size))
  11794. return false;
  11795. const std::size_t raw_size = size * sizeof(T);
  11796. if (!buffer_capacity_ok(raw_size))
  11797. return false;
  11798. T t = T();
  11799. for (std::size_t i = 0; i < size; ++i)
  11800. {
  11801. if (operator()(t))
  11802. seq.push_back(t);
  11803. else
  11804. return false;
  11805. }
  11806. return true;
  11807. }
  11808. template <typename T, typename Allocator>
  11809. inline bool operator()(std::vector<T,Allocator>& vec)
  11810. {
  11811. uint32_t size = 0;
  11812. if (!read_pod(size))
  11813. return false;
  11814. const std::size_t raw_size = size * sizeof(T);
  11815. if (!buffer_capacity_ok(raw_size))
  11816. return false;
  11817. vec.resize(size);
  11818. return selector<T>::type::batch_vector_read(*this,size,vec,false);
  11819. }
  11820. template <typename T,
  11821. typename Comparator,
  11822. typename Allocator>
  11823. inline bool operator()(std::set<T,Comparator,Allocator>& set)
  11824. {
  11825. uint32_t size = 0;
  11826. if (!read_pod(size))
  11827. return false;
  11828. const std::size_t raw_size = size * sizeof(T);
  11829. if (!buffer_capacity_ok(raw_size))
  11830. return false;
  11831. T t;
  11832. for (std::size_t i = 0; i < size; ++i)
  11833. {
  11834. if (!operator()(t))
  11835. return false;
  11836. set.insert(t);
  11837. }
  11838. return true;
  11839. }
  11840. template <typename T,
  11841. typename Allocator,
  11842. typename Comparator>
  11843. inline bool operator()(std::multiset<T,Allocator,Comparator>& multiset)
  11844. {
  11845. uint32_t size = 0;
  11846. if (!read_pod(size))
  11847. return false;
  11848. const std::size_t raw_size = size * sizeof(T);
  11849. if (!buffer_capacity_ok(raw_size))
  11850. return false;
  11851. T t;
  11852. for (std::size_t i = 0; i < size; ++i)
  11853. {
  11854. if (!operator()(t))
  11855. return false;
  11856. multiset.insert(t);
  11857. }
  11858. return true;
  11859. }
  11860. inline bool operator()(std::ifstream& stream, const std::size_t& length)
  11861. {
  11862. if (length > buffer_length_) return false;
  11863. stream.read(original_buffer_,static_cast<std::streamsize>(length));
  11864. return true;
  11865. }
  11866. inline bool operator()(std::ifstream& stream)
  11867. {
  11868. if (0 == amount_read_sofar_) return false;
  11869. stream.read(original_buffer_,static_cast<std::streamsize>(amount_read_sofar_));
  11870. return true;
  11871. }
  11872. template <typename T>
  11873. inline bool operator()(T& output)
  11874. {
  11875. return selector<T>::type::run(*this,output);
  11876. }
  11877. template <typename T>
  11878. inline bool operator()(const T& output)
  11879. {
  11880. return selector<T>::type::run(*this,const_cast<T&>(output));
  11881. }
  11882. template <typename T>
  11883. inline bool be_to_native(T& output)
  11884. {
  11885. //From big-endian to native
  11886. if (details::is_little_endian())
  11887. {
  11888. if (!operator()<T>(output)) return false;
  11889. output = details::convert(output);
  11890. return true;
  11891. }
  11892. else
  11893. return operator()(output);
  11894. }
  11895. template <typename T>
  11896. inline bool le_to_native(T& output)
  11897. {
  11898. //From little-endian to native
  11899. if (details::is_little_endian())
  11900. return operator()(output);
  11901. else
  11902. {
  11903. if (!operator()<T>(output)) return false;
  11904. output = details::convert(output);
  11905. return true;
  11906. }
  11907. }
  11908. template <typename T, std::size_t N>
  11909. inline bool operator()(T (&output)[N])
  11910. {
  11911. const std::size_t raw_size = N * sizeof(T);
  11912. if (buffer_capacity_ok(raw_size))
  11913. {
  11914. std::copy(buffer_,
  11915. buffer_ + raw_size,
  11916. reinterpret_cast<char*>(output));
  11917. buffer_ += raw_size;
  11918. amount_read_sofar_ += raw_size;
  11919. return true;
  11920. }
  11921. else
  11922. return false;
  11923. }
  11924. template <typename T>
  11925. inline bool operator()(T& output, const std::size_t& size)
  11926. {
  11927. if (buffer_capacity_ok(size))
  11928. {
  11929. bool result = strtk::string_to_type_converter<char*,T>(buffer_,buffer_ + size,output);
  11930. buffer_ += size;
  11931. amount_read_sofar_ += size;
  11932. return result;
  11933. }
  11934. else
  11935. return false;
  11936. }
  11937. inline void mark()
  11938. {
  11939. marker_.mark(amount_read_sofar_,buffer_);
  11940. }
  11941. inline bool reset_to_mark()
  11942. {
  11943. return marker_.reset(amount_read_sofar_,buffer_);
  11944. }
  11945. private:
  11946. reader();
  11947. reader(const reader& s);
  11948. reader& operator=(const reader& s);
  11949. inline bool buffer_capacity_ok(const std::size_t& required_read_qty)
  11950. {
  11951. return ((required_read_qty + amount_read_sofar_) <= buffer_length_);
  11952. }
  11953. template <typename Type>
  11954. struct selector
  11955. {
  11956. private:
  11957. template <typename T, typename IsPOD>
  11958. struct selector_impl
  11959. {
  11960. template <typename Reader>
  11961. static inline bool run(Reader& r, T& t)
  11962. {
  11963. return t(r);
  11964. }
  11965. template <typename Reader,
  11966. typename Allocator>
  11967. static inline bool batch_vector_read(Reader& r,
  11968. const std::size_t& size,
  11969. std::vector<T,Allocator>& v,
  11970. const bool)
  11971. {
  11972. T t;
  11973. for (std::size_t i = 0; i < size; ++i)
  11974. {
  11975. if (r.operator()(t))
  11976. v[i] = t;
  11977. else
  11978. return false;
  11979. }
  11980. return true;
  11981. }
  11982. };
  11983. template <typename T>
  11984. struct selector_impl<T,strtk::details::yes_t>
  11985. {
  11986. template <typename Reader>
  11987. static inline bool run(Reader& r,
  11988. T& t,
  11989. const bool perform_buffer_capacity_check = true)
  11990. {
  11991. return r.read_pod(t,perform_buffer_capacity_check);
  11992. }
  11993. template <typename Reader,
  11994. typename Allocator>
  11995. static inline bool batch_vector_read(Reader& r,
  11996. const std::size_t& size,
  11997. std::vector<T,Allocator>& v,
  11998. const bool)
  11999. {
  12000. const std::size_t raw_size = sizeof(T) * size;
  12001. char* ptr = const_cast<char*>(reinterpret_cast<const char*>(&v[0]));
  12002. std::copy(r.buffer_, r.buffer_ + raw_size, ptr);
  12003. r.buffer_ += raw_size;
  12004. r.amount_read_sofar_ += raw_size;
  12005. return true;
  12006. }
  12007. };
  12008. public:
  12009. typedef selector_impl<Type,typename strtk::details::is_pod<Type>::result_t> type;
  12010. };
  12011. template <typename T>
  12012. inline bool read_pod(T& data, const bool perform_buffer_capacity_check = true)
  12013. {
  12014. static const std::size_t data_length = sizeof(T);
  12015. if (perform_buffer_capacity_check)
  12016. {
  12017. if (!buffer_capacity_ok(data_length))
  12018. return false;
  12019. }
  12020. data = (*reinterpret_cast<T*>(buffer_));
  12021. buffer_ += data_length;
  12022. amount_read_sofar_ += data_length;
  12023. return true;
  12024. }
  12025. char* const original_buffer_;
  12026. char* buffer_;
  12027. std::size_t buffer_length_;
  12028. std::size_t amount_read_sofar_;
  12029. details::marker marker_;
  12030. };
  12031. class writer
  12032. {
  12033. public:
  12034. // should be sourced from cstdint
  12035. // should be sourced from cstdint
  12036. typedef unsigned int uint32_t;
  12037. typedef unsigned short uint16_t;
  12038. typedef unsigned char uint8_t;
  12039. typedef unsigned long long int uint64_t;
  12040. template <typename T>
  12041. writer(T* buffer, const std::size_t& buffer_length)
  12042. : original_buffer_(reinterpret_cast<char*>(buffer)),
  12043. buffer_(reinterpret_cast<char*>(buffer)),
  12044. buffer_length_(buffer_length * sizeof(T)),
  12045. amount_written_sofar_(0)
  12046. {}
  12047. inline bool operator!() const
  12048. {
  12049. return (0 == buffer_length_) ||
  12050. (0 == original_buffer_) ||
  12051. (0 == buffer_);
  12052. }
  12053. inline void reset(const bool clear_buffer = false)
  12054. {
  12055. amount_written_sofar_ = 0;
  12056. buffer_ = original_buffer_;
  12057. if (clear_buffer)
  12058. clear();
  12059. }
  12060. inline std::size_t position() const
  12061. {
  12062. return amount_written_sofar_;
  12063. }
  12064. inline const char* position_ptr() const
  12065. {
  12066. return buffer_ ;
  12067. }
  12068. inline std::size_t amount_written() const
  12069. {
  12070. return amount_written_sofar_;
  12071. }
  12072. inline void clear()
  12073. {
  12074. reset();
  12075. std::memset(buffer_,0x00,buffer_length_);
  12076. }
  12077. template <typename T, std::size_t N>
  12078. inline bool operator()(const T (&data)[N], const bool write_length = false)
  12079. {
  12080. if (write_length && !operator()(N))
  12081. return false;
  12082. const std::size_t raw_size = N * sizeof(T);
  12083. if (!buffer_capacity_ok(raw_size))
  12084. return false;
  12085. const char* ptr = reinterpret_cast<const char*>(data);
  12086. std::copy(ptr, ptr + raw_size, buffer_);
  12087. buffer_ += raw_size;
  12088. amount_written_sofar_ += raw_size;
  12089. return true;
  12090. }
  12091. template <typename T>
  12092. inline bool operator()(const T* data, const uint32_t& length, const bool write_length = true)
  12093. {
  12094. if (write_length && !operator()(length))
  12095. return false;
  12096. const std::size_t raw_size = length * sizeof(T);
  12097. if (!buffer_capacity_ok(raw_size))
  12098. return false;
  12099. const char* ptr = reinterpret_cast<const char*>(data);
  12100. std::copy(ptr, ptr + raw_size, buffer_);
  12101. buffer_ += raw_size;
  12102. amount_written_sofar_ += raw_size;
  12103. return true;
  12104. }
  12105. template <typename T>
  12106. inline bool operator()(const T* data, const uint64_t& length, const bool write_length = true)
  12107. {
  12108. return operator()(data,static_cast<uint32_t>(length),write_length);
  12109. }
  12110. template <typename T>
  12111. inline bool operator()(const T* data, const uint16_t& length, const bool write_length = true)
  12112. {
  12113. return operator()(data,static_cast<uint32_t>(length),write_length);
  12114. }
  12115. template <typename T>
  12116. inline bool operator()(const T* data, const uint8_t& length, const bool write_length = true)
  12117. {
  12118. return operator()(data,static_cast<uint32_t>(length),write_length);
  12119. }
  12120. template <typename T1, typename T2>
  12121. inline bool operator()(const std::pair<T1,T2>& p)
  12122. {
  12123. if (!operator()(p.first))
  12124. return false;
  12125. if (!operator()(p.second))
  12126. return false;
  12127. return true;
  12128. }
  12129. inline bool operator()(const std::string& input)
  12130. {
  12131. return operator()<const char>(input.data(),static_cast<uint32_t>(input.size()));
  12132. }
  12133. template <typename T,
  12134. typename Allocator,
  12135. template <typename,typename> class Sequence>
  12136. inline bool operator()(const Sequence<T,Allocator>& seq)
  12137. {
  12138. const uint32_t size = static_cast<uint32_t>(seq.size());
  12139. if (!operator()(size))
  12140. return false;
  12141. typename Sequence<T,Allocator>::