/strtk.hpp

http://strtk.codeplex.com · C++ Header · 23367 lines · 22563 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>::const_iterator itr = seq.begin();
  12142. typename Sequence<T,Allocator>::const_iterator end = seq.end();
  12143. while (end != itr)
  12144. {
  12145. if (!operator()(*itr))
  12146. return false;
  12147. ++itr;
  12148. }
  12149. return true;
  12150. }
  12151. template <typename T,
  12152. typename Allocator>
  12153. inline bool operator()(const std::vector<T,Allocator>& vec)
  12154. {
  12155. const uint32_t size = static_cast<uint32_t>(vec.size());
  12156. const std::size_t raw_size = (size * sizeof(T));
  12157. if (!buffer_capacity_ok(raw_size + sizeof(size)))
  12158. return false;
  12159. if (!operator()(size))
  12160. return false;
  12161. return selector<T>::type::batch_vector_writer(*this,raw_size,vec);
  12162. }
  12163. template <typename T,
  12164. typename Comparator,
  12165. typename Allocator>
  12166. inline bool operator()(const std::set<T,Comparator,Allocator>& set)
  12167. {
  12168. const uint32_t size = static_cast<uint32_t>(set.size());
  12169. if (!operator()(size))
  12170. return false;
  12171. const std::size_t raw_size = size * sizeof(T);
  12172. if (!buffer_capacity_ok(raw_size))
  12173. return false;
  12174. typename std::set<T,Comparator,Allocator>::const_iterator itr = set.begin();
  12175. typename std::set<T,Comparator,Allocator>::const_iterator end = set.end();
  12176. while (end != itr)
  12177. {
  12178. if (!operator()(*itr))
  12179. return false;
  12180. ++itr;
  12181. }
  12182. return true;
  12183. }
  12184. template <typename T,
  12185. typename Allocator,
  12186. typename Comparator>
  12187. inline bool operator()(const std::multiset<T,Allocator,Comparator>& multiset)
  12188. {
  12189. const uint32_t size = static_cast<uint32_t>(multiset.size());
  12190. if (!operator()(size))
  12191. return false;
  12192. const std::size_t raw_size = size * sizeof(T);
  12193. if (!buffer_capacity_ok(raw_size))
  12194. return false;
  12195. typename std::multiset<T,Allocator,Comparator>::const_iterator itr = multiset.begin();
  12196. typename std::multiset<T,Allocator,Comparator>::const_iterator end = multiset.end();
  12197. while (end != itr)
  12198. {
  12199. if (!operator()(*itr))
  12200. return false;
  12201. ++itr;
  12202. }
  12203. return true;
  12204. }
  12205. inline std::size_t operator()(std::ofstream& stream)
  12206. {
  12207. stream.write(original_buffer_,static_cast<std::streamsize>(amount_written_sofar_));
  12208. return amount_written_sofar_;
  12209. }
  12210. template <typename T>
  12211. inline bool operator()(const T& input)
  12212. {
  12213. return selector<T>::type::run(*this,input);
  12214. }
  12215. template <typename T>
  12216. inline bool native_to_be(const T& input)
  12217. {
  12218. //From native to big-endian
  12219. if (details::is_little_endian())
  12220. {
  12221. return operator()<T>(details::convert(input));
  12222. }
  12223. else
  12224. return operator()<T>(input);
  12225. }
  12226. template <typename T>
  12227. inline bool native_to_le(const T& input)
  12228. {
  12229. //From native to little-endian
  12230. if (details::is_little_endian())
  12231. return operator()<T>(input);
  12232. else
  12233. return operator()<T>(details::convert(input));
  12234. }
  12235. enum padding_mode
  12236. {
  12237. right_padding = 0,
  12238. left_padding = 1
  12239. };
  12240. template <typename T>
  12241. inline bool operator()(const T& input,
  12242. const std::size_t& size,
  12243. const padding_mode pmode,
  12244. const char padding = ' ')
  12245. {
  12246. if (amount_written_sofar_ + size <= buffer_length_)
  12247. {
  12248. std::string s;
  12249. s.reserve(size);
  12250. if (!strtk::type_to_string<T>(input,s))
  12251. return false;
  12252. else if (s.size() > size)
  12253. return false;
  12254. else if (s.size() < size)
  12255. {
  12256. if (right_padding == pmode)
  12257. s.resize(size - s.size(),padding);
  12258. else
  12259. s = std::string(size - s.size(),padding) + s;
  12260. }
  12261. return operator()<const char>(s.data(),static_cast<uint32_t>(size),false);
  12262. }
  12263. else
  12264. return false;
  12265. }
  12266. inline void mark()
  12267. {
  12268. marker_.mark(amount_written_sofar_,buffer_);
  12269. }
  12270. inline bool reset_to_mark()
  12271. {
  12272. return marker_.reset(amount_written_sofar_,buffer_);
  12273. }
  12274. private:
  12275. writer();
  12276. writer(const writer& s);
  12277. writer& operator=(const writer& s);
  12278. inline bool buffer_capacity_ok(const std::size_t& required_write_qty)
  12279. {
  12280. return ((required_write_qty + amount_written_sofar_) <= buffer_length_);
  12281. }
  12282. template <typename Type>
  12283. struct selector
  12284. {
  12285. private:
  12286. template <typename T, typename IsPOD>
  12287. struct selector_impl
  12288. {
  12289. template <typename Writer>
  12290. static inline bool run(Writer& w, const T& t)
  12291. {
  12292. return t(w);
  12293. }
  12294. template <typename Writer,
  12295. typename Allocator>
  12296. static inline bool batch_vector_writer(Writer& w,
  12297. const std::size_t&,
  12298. const std::vector<T,Allocator>& v)
  12299. {
  12300. for (std::size_t i = 0; i < v.size(); ++i)
  12301. {
  12302. if (w.operator()(v[i]))
  12303. continue;
  12304. else
  12305. return false;
  12306. }
  12307. return true;
  12308. }
  12309. };
  12310. template <typename T>
  12311. struct selector_impl<T,strtk::details::yes_t>
  12312. {
  12313. template <typename Writer>
  12314. static inline bool run(Writer& w, const T& t)
  12315. {
  12316. return w.write_pod(t);
  12317. }
  12318. template <typename Writer,
  12319. typename Allocator>
  12320. static inline bool batch_vector_writer(Writer& w,
  12321. const std::size_t& raw_size,
  12322. const std::vector<T,Allocator>& v)
  12323. {
  12324. const char* ptr = reinterpret_cast<const char*>(&v[0]);
  12325. std::copy(ptr, ptr + raw_size, w.buffer_);
  12326. w.buffer_ += raw_size;
  12327. w.amount_written_sofar_ += raw_size;
  12328. return true;
  12329. }
  12330. };
  12331. public:
  12332. typedef selector_impl<Type,typename strtk::details::is_pod<Type>::result_t> type;
  12333. };
  12334. template <typename T>
  12335. inline bool write_pod(const T& data, const bool perform_buffer_capacity_check = true)
  12336. {
  12337. static const std::size_t data_length = sizeof(T);
  12338. if (perform_buffer_capacity_check)
  12339. {
  12340. if ((data_length + amount_written_sofar_) > buffer_length_)
  12341. {
  12342. return false;
  12343. }
  12344. }
  12345. *(reinterpret_cast<T*>(buffer_)) = data;
  12346. buffer_ += data_length;
  12347. amount_written_sofar_ += data_length;
  12348. return true;
  12349. }
  12350. char* const original_buffer_;
  12351. char* buffer_;
  12352. std::size_t buffer_length_;
  12353. std::size_t amount_written_sofar_;
  12354. details::marker marker_;
  12355. };
  12356. #define strtk_binary_reader_begin()\
  12357. bool operator()(strtk::binary::reader& reader)\
  12358. { return true\
  12359. #define strtk_binary_reader(T)\
  12360. && reader(T)\
  12361. #define strtk_binary_reader_end()\
  12362. ;}\
  12363. #define strtk_binary_writer_begin()\
  12364. bool operator()(strtk::binary::writer& writer) const\
  12365. { return true\
  12366. #define strtk_binary_writer(T)\
  12367. && writer(T)\
  12368. #define strtk_binary_writer_end()\
  12369. ;}\
  12370. namespace details
  12371. {
  12372. template <typename size_type>
  12373. class short_string_impl
  12374. {
  12375. public:
  12376. short_string_impl()
  12377. : s(0)
  12378. {}
  12379. short_string_impl(std::string& str)
  12380. : s(&str)
  12381. {}
  12382. inline void clear()
  12383. {
  12384. s = 0;
  12385. }
  12386. inline short_string_impl<size_type>& set(std::string& str)
  12387. {
  12388. s = &str;
  12389. return *this;
  12390. }
  12391. inline bool operator()(reader& r)
  12392. {
  12393. if (0 == s)
  12394. return false;
  12395. size_type size = 0;
  12396. if (!r(size))
  12397. return false;
  12398. s->resize(size);
  12399. char* ptr = const_cast<char*>(s->data());
  12400. strtk::binary::reader::uint32_t length = size;
  12401. if (!r(ptr,length,false))
  12402. return false;
  12403. return true;
  12404. }
  12405. inline bool operator()(writer& w) const
  12406. {
  12407. if (0 == s)
  12408. return false;
  12409. if (s->size() > std::numeric_limits<size_type>::max())
  12410. return false;
  12411. const size_type size = static_cast<size_type>(s->size());
  12412. if (!w(size))
  12413. return false;
  12414. if (!w(s->data(),size, false))
  12415. return false;
  12416. return true;
  12417. }
  12418. private:
  12419. short_string_impl& operator=(const short_string_impl&);
  12420. mutable std::string* s;
  12421. };
  12422. }
  12423. typedef details::short_string_impl<reader::uint16_t> short_string;
  12424. typedef details::short_string_impl<reader::uint8_t> pascal_string;
  12425. } // namespace binary
  12426. class ignore_token
  12427. {
  12428. public:
  12429. template <typename InputIterator>
  12430. inline ignore_token& operator=(const std::pair<InputIterator,InputIterator>&)
  12431. {
  12432. return (*this);
  12433. }
  12434. inline ignore_token& operator=(const std::string&)
  12435. {
  12436. return (*this);
  12437. }
  12438. };
  12439. template <typename T>
  12440. class hex_to_number_sink
  12441. {
  12442. // static_assert for T either int or unsigned int and alike (could use a concept)
  12443. private:
  12444. struct hex_value_check
  12445. {
  12446. inline bool operator()(const unsigned char c) const
  12447. {
  12448. return (('0' <= c) && (c <= '9')) ||
  12449. (('A' <= c) && (c <= 'F')) ||
  12450. (('a' <= c) && (c <= 'f'));
  12451. }
  12452. inline bool operator()(const char c) const
  12453. {
  12454. return (*this)(static_cast<unsigned char>(c));
  12455. }
  12456. };
  12457. public:
  12458. hex_to_number_sink(T& t)
  12459. : valid_(false),
  12460. t_(&t)
  12461. {}
  12462. hex_to_number_sink(const hex_to_number_sink& hns)
  12463. : valid_(hns.valid),
  12464. t_(hns.t_)
  12465. {}
  12466. inline hex_to_number_sink& operator=(const hex_to_number_sink& hns)
  12467. {
  12468. valid_ = hns.valid_;
  12469. t_ = hns.t_;
  12470. return (*this);
  12471. }
  12472. template <typename InputIterator>
  12473. inline hex_to_number_sink& operator=(const std::pair<InputIterator,InputIterator>& s)
  12474. {
  12475. std::size_t offset = 0;
  12476. const std::size_t size = std::distance(s.first,s.second);
  12477. if ((size > 2) && ((*s.first) == '0') && (((*(s.first + 1)) == 'x') || ((*(s.first + 1)) == 'X')))
  12478. offset = 2;
  12479. if ((size - offset) > (2 * sizeof(T)))
  12480. return (*this);
  12481. const std::size_t buffer_size = 2 * sizeof(T);
  12482. const std::size_t buffer_offset = ((size - offset) % 2);
  12483. char buffer[buffer_size] = { '0' };
  12484. if (!range_only_contains(hex_value_check(),s.first + offset,s.first + size))
  12485. {
  12486. valid_ = false;
  12487. return (*this);
  12488. }
  12489. std::copy(s.first + offset, s.first + size, buffer + buffer_offset);
  12490. (*t_) = 0;
  12491. valid_= convert_hex_to_bin(buffer,
  12492. buffer + (size - offset) + buffer_offset,
  12493. reinterpret_cast<char*>(t_));
  12494. reverse_bytes();
  12495. return (*this);
  12496. }
  12497. inline hex_to_number_sink& operator=(const std::string& s)
  12498. {
  12499. return this->operator =(std::make_pair(s.data(),s.data() + s.size()));
  12500. }
  12501. inline bool valid() const
  12502. {
  12503. return valid_;
  12504. }
  12505. private:
  12506. inline void reverse_bytes()
  12507. {
  12508. unsigned char* itr1 = reinterpret_cast<unsigned char*>(t_);
  12509. unsigned char* itr2 = itr1 + (sizeof(T) - 1);
  12510. while (itr1 < itr2)
  12511. {
  12512. std::swap(*itr1,*itr2);
  12513. ++itr1;
  12514. --itr2;
  12515. }
  12516. }
  12517. private:
  12518. bool valid_;
  12519. T* t_;
  12520. };
  12521. template <typename T>
  12522. class base64_to_number_sink
  12523. {
  12524. // static_assert for T either int or unsigned int and alike (could use a concept)
  12525. private:
  12526. struct base64_value_check
  12527. {
  12528. inline bool operator()(const unsigned char c) const
  12529. {
  12530. return (('0' <= c) && (c <= '9')) ||
  12531. (('A' <= c) && (c <= 'Z')) ||
  12532. (('a' <= c) && (c <= 'z')) ||
  12533. ('+' == c) ||
  12534. ('/' == c) ||
  12535. ('=' == c);
  12536. }
  12537. inline bool operator()(const char c) const
  12538. {
  12539. return (*this)(static_cast<unsigned char>(c));
  12540. }
  12541. };
  12542. public:
  12543. base64_to_number_sink(T& t)
  12544. : valid_(false),
  12545. t_(&t)
  12546. {}
  12547. base64_to_number_sink(const base64_to_number_sink& bns)
  12548. : valid_(bns.valid),
  12549. t_(bns.t_)
  12550. {}
  12551. inline base64_to_number_sink& operator=(const base64_to_number_sink& bns)
  12552. {
  12553. valid_ = bns.valid_;
  12554. t_ = bns.t_;
  12555. return (*this);
  12556. }
  12557. inline base64_to_number_sink& operator=(const std::string& s)
  12558. {
  12559. if (!range_only_contains(base64_value_check(),s.data(),s.data() + s.size()))
  12560. {
  12561. valid_ = false;
  12562. return (*this);
  12563. }
  12564. (*t_) = T(0);
  12565. convert_base64_to_bin(s.data(),
  12566. s.data() + s.size(),
  12567. reinterpret_cast<char*>(t_));
  12568. reverse_bytes();
  12569. return (*this);
  12570. }
  12571. template <typename InputIterator>
  12572. inline base64_to_number_sink& operator=(const std::pair<InputIterator,InputIterator>& s)
  12573. {
  12574. if (!range_only_contains(base64_value_check(),s.first,s.second))
  12575. {
  12576. valid_ = false;
  12577. return (*this);
  12578. }
  12579. (*t_) = T(0);
  12580. convert_base64_to_bin(s.first, s.second,reinterpret_cast<char*>(t_));
  12581. reverse_bytes();
  12582. return (*this);
  12583. }
  12584. inline bool valid() const
  12585. {
  12586. return valid_;
  12587. }
  12588. private:
  12589. inline void reverse_bytes()
  12590. {
  12591. unsigned char* itr1 = reinterpret_cast<unsigned char*>(t_);
  12592. unsigned char* itr2 = itr1 + (sizeof(T) - 1);
  12593. while (itr1 < itr2)
  12594. {
  12595. std::swap(*itr1,*itr2);
  12596. ++itr1;
  12597. --itr2;
  12598. }
  12599. }
  12600. private:
  12601. bool valid_;
  12602. T* t_;
  12603. };
  12604. class hex_to_string_sink
  12605. {
  12606. public:
  12607. hex_to_string_sink(std::string& s)
  12608. : valid_(false),
  12609. s_(s)
  12610. {}
  12611. hex_to_string_sink(const hex_to_string_sink& hss)
  12612. : valid_(hss.valid_),
  12613. s_(hss.s_)
  12614. {}
  12615. inline hex_to_string_sink& operator=(const hex_to_string_sink& hss)
  12616. {
  12617. valid_ = hss.valid_;
  12618. s_ = hss.s_;
  12619. return (*this);
  12620. }
  12621. template <typename InputIterator>
  12622. inline hex_to_string_sink& operator=(const std::pair<InputIterator,InputIterator>& s)
  12623. {
  12624. const std::size_t size = std::distance(s.first,s.second);
  12625. std::size_t offset = 0;
  12626. if ((size > 2) && ((*s.first) == '0') && (((*(s.first + 1)) == 'x') || ((*(s.first + 1)) == 'X')))
  12627. offset = 2;
  12628. if ((size - offset) < 2)
  12629. {
  12630. valid_ = false;
  12631. return (*this);
  12632. }
  12633. s_.resize((size - offset) / 2);
  12634. valid_ = convert_hex_to_bin(s.first + offset,
  12635. s.second,
  12636. const_cast<char*>(s_.data()));
  12637. return (*this);
  12638. }
  12639. inline hex_to_string_sink& operator=(const std::string& s)
  12640. {
  12641. return this->operator=(std::make_pair<char*>(const_cast<char*>(s.data()),
  12642. const_cast<char*>(s.data() + s.size())));
  12643. }
  12644. inline bool valid() const
  12645. {
  12646. return valid_;
  12647. }
  12648. private:
  12649. bool valid_;
  12650. std::string& s_;
  12651. };
  12652. namespace details
  12653. {
  12654. template <typename InputIterator,
  12655. typename T,
  12656. typename Allocator,
  12657. template <typename,typename> class Sequence>
  12658. inline std::size_t parse_stl_container_proxy(const InputIterator begin,
  12659. const InputIterator end,
  12660. const std::string& delimiters,
  12661. Sequence<T,Allocator>& sequence,
  12662. const split_options::type& split_option = split_options::compress_delimiters)
  12663. {
  12664. return parse(begin,end,delimiters,sequence,split_option);
  12665. }
  12666. template <typename InputIterator,
  12667. typename T,
  12668. typename Comparator,
  12669. typename Allocator>
  12670. inline std::size_t parse_stl_container_proxy(const InputIterator begin,
  12671. const InputIterator end,
  12672. const std::string& delimiters,
  12673. std::set<T,Comparator,Allocator>& set,
  12674. const split_options::type& split_option = split_options::compress_delimiters)
  12675. {
  12676. return parse(begin,end,delimiters,set,split_option);
  12677. }
  12678. template <typename InputIterator,
  12679. typename T,
  12680. typename Comparator,
  12681. typename Allocator>
  12682. inline std::size_t parse_stl_container_proxy(const InputIterator begin,
  12683. const InputIterator end,
  12684. const std::string& delimiters,
  12685. std::multiset<T,Comparator,Allocator>& multiset,
  12686. const split_options::type& split_option = split_options::compress_delimiters)
  12687. {
  12688. return parse(begin,end,delimiters,multiset,split_option);
  12689. }
  12690. template <typename InputIterator,
  12691. typename T,
  12692. typename Container>
  12693. inline std::size_t parse_stl_container_proxy(const InputIterator begin,
  12694. const InputIterator end,
  12695. const std::string& delimiters,
  12696. std::queue<T,Container>& queue,
  12697. const split_options::type& split_option = split_options::compress_delimiters)
  12698. {
  12699. return parse(begin,end,delimiters,queue,split_option);
  12700. }
  12701. template <typename InputIterator,
  12702. typename T,
  12703. typename Container>
  12704. inline std::size_t parse_stl_container_proxy(const InputIterator begin,
  12705. const InputIterator end,
  12706. const std::string& delimiters,
  12707. std::stack<T,Container>& stack,
  12708. const split_options::type& split_option = split_options::compress_delimiters)
  12709. {
  12710. return parse(begin,end,delimiters,stack,split_option);
  12711. }
  12712. template <typename InputIterator,
  12713. typename T,
  12714. typename Container,
  12715. typename Comparator>
  12716. inline std::size_t parse_stl_container_proxy(const InputIterator begin,
  12717. const InputIterator end,
  12718. const std::string& delimiters,
  12719. std::priority_queue<T,Container,Comparator>& priority_queue,
  12720. const split_options::type& split_option = split_options::compress_delimiters)
  12721. {
  12722. return parse(begin,end,delimiters,priority_queue,split_option);
  12723. }
  12724. template <typename InputIterator,
  12725. typename T,
  12726. typename Allocator,
  12727. template <typename,typename> class Sequence>
  12728. inline std::size_t parse_n_stl_container_proxy(const InputIterator begin,
  12729. const InputIterator end,
  12730. const std::string& delimiters,
  12731. const std::size_t& n,
  12732. Sequence<T,Allocator>& sequence,
  12733. const split_options::type& split_option = split_options::compress_delimiters)
  12734. {
  12735. return parse_n(begin,end,delimiters,n,sequence,split_option);
  12736. }
  12737. template <typename InputIterator,
  12738. typename T,
  12739. typename Comparator,
  12740. typename Allocator>
  12741. inline std::size_t parse_n_stl_container_proxy(const InputIterator begin,
  12742. const InputIterator end,
  12743. const std::string& delimiters,
  12744. const std::size_t& n,
  12745. std::set<T,Comparator,Allocator>& set,
  12746. const split_options::type& split_option = split_options::compress_delimiters)
  12747. {
  12748. return parse_n(begin,end,delimiters,n,set,split_option);
  12749. }
  12750. template <typename InputIterator,
  12751. typename T,
  12752. typename Comparator,
  12753. typename Allocator>
  12754. inline std::size_t parse_n_stl_container_proxy(const InputIterator begin,
  12755. const InputIterator end,
  12756. const std::string& delimiters,
  12757. const std::size_t& n,
  12758. std::multiset<T,Comparator,Allocator>& multiset,
  12759. const split_options::type& split_option = split_options::compress_delimiters)
  12760. {
  12761. return parse_n(begin,end,delimiters,n,multiset,split_option);
  12762. }
  12763. template <typename InputIterator,
  12764. typename T,
  12765. typename Container>
  12766. inline std::size_t parse_n_stl_container_proxy(const InputIterator begin,
  12767. const InputIterator end,
  12768. const std::string& delimiters,
  12769. const std::size_t& n,
  12770. std::queue<T,Container>& queue,
  12771. const split_options::type& split_option = split_options::compress_delimiters)
  12772. {
  12773. return parse_n(begin,end,delimiters,n,queue,split_option);
  12774. }
  12775. template <typename InputIterator,
  12776. typename T,
  12777. typename Container>
  12778. inline std::size_t parse_n_stl_container_proxy(const InputIterator begin,
  12779. const InputIterator end,
  12780. const std::string& delimiters,
  12781. const std::size_t& n,
  12782. std::stack<T,Container>& stack,
  12783. const split_options::type& split_option = split_options::compress_delimiters)
  12784. {
  12785. return parse_n(begin,end,delimiters,n,stack,split_option);
  12786. }
  12787. template <typename InputIterator,
  12788. typename T,
  12789. typename Container,
  12790. typename Comparator>
  12791. inline std::size_t parse_n_stl_container_proxy(const InputIterator begin,
  12792. const InputIterator end,
  12793. const std::string& delimiters,
  12794. const std::size_t& n,
  12795. std::priority_queue<T,Container,Comparator>& priority_queue,
  12796. const split_options::type& split_option = split_options::compress_delimiters)
  12797. {
  12798. return parse_n(begin,end,delimiters,n,priority_queue,split_option);
  12799. }
  12800. } // namespace details
  12801. template <typename Container>
  12802. class sink_type
  12803. {
  12804. public:
  12805. typedef typename Container::value_type value_type;
  12806. inline sink_type(const std::string& delimiters,
  12807. const split_options::type& split_option = split_options::compress_delimiters)
  12808. : delimiters_(delimiters),
  12809. split_option_(split_option),
  12810. container_(0),
  12811. element_count_(std::numeric_limits<std::size_t>::max())
  12812. {}
  12813. inline sink_type(Container& container,
  12814. const std::string& delimiters,
  12815. const split_options::type& split_option = split_options::compress_delimiters)
  12816. : delimiters_(delimiters),
  12817. split_option_(split_option),
  12818. container_(&container)
  12819. {}
  12820. inline sink_type& count(const std::size_t& element_count = std::numeric_limits<std::size_t>::max())
  12821. {
  12822. element_count_ = element_count;
  12823. return (*this);
  12824. }
  12825. inline sink_type& operator()(Container& container,
  12826. const std::string& delimiters = "",
  12827. const split_options::type& split_option = split_options::compress_delimiters)
  12828. {
  12829. container_ = (&container);
  12830. if (!delimiters.empty())
  12831. delimiters_ = delimiters;
  12832. split_option_ = split_option;
  12833. return (*this);
  12834. }
  12835. template <typename InputIterator>
  12836. inline bool parse(InputIterator begin, InputIterator end)
  12837. {
  12838. if (container_)
  12839. {
  12840. if (std::numeric_limits<std::size_t>::max() == element_count_)
  12841. return (details::parse_stl_container_proxy
  12842. (begin,end,delimiters_,(*container_),split_option_) > 0);
  12843. else
  12844. return (details::parse_n_stl_container_proxy
  12845. (begin,end,delimiters_,element_count_,(*container_),split_option_) == element_count_);
  12846. }
  12847. else
  12848. return false;
  12849. }
  12850. sink_type<Container>& reference()
  12851. {
  12852. return *this;
  12853. }
  12854. private:
  12855. std::string delimiters_;
  12856. split_options::type split_option_;
  12857. Container* container_;
  12858. std::size_t element_count_;
  12859. };
  12860. template <typename T> struct vector_sink { typedef sink_type<std::vector<T> > type; };
  12861. template <typename T> struct deque_sink { typedef sink_type<std::deque<T> > type; };
  12862. template <typename T> struct list_sink { typedef sink_type<std::list<T> > type; };
  12863. template <typename T> struct set_sink { typedef sink_type<std::set<T> > type; };
  12864. template <typename T> struct multiset_sink { typedef sink_type<std::multiset<T> > type; };
  12865. template <typename T> struct queue_sink { typedef sink_type<std::queue<T> > type; };
  12866. template <typename T> struct stack_sink { typedef sink_type<std::stack<T> > type; };
  12867. template <typename T> struct priority_queue_sink { typedef sink_type<std::priority_queue<T> > type; };
  12868. namespace text
  12869. {
  12870. inline std::string center(const std::size_t& width,
  12871. const std::string::value_type& pad,
  12872. const std::string& str)
  12873. {
  12874. if (str.size() >= width) return str;
  12875. const std::size_t pad_count = width - str.size();
  12876. const std::size_t pad_count_2 = (pad_count >> 1) + (pad_count & 1);
  12877. return std::string(pad_count >> 1,pad) + str + std::string(pad_count_2,pad);
  12878. }
  12879. inline std::string right_align(const std::size_t& width,
  12880. const std::string::value_type& pad,
  12881. const std::string& str)
  12882. {
  12883. if (str.size() >= width) return str;
  12884. return std::string(width - str.size(),pad) + str;
  12885. }
  12886. inline std::string left_align(const std::size_t& width,
  12887. const std::string::value_type& pad,
  12888. const std::string& str)
  12889. {
  12890. if (str.size() >= width) return str;
  12891. return str + std::string(width - str.size(),pad);
  12892. }
  12893. template <typename T>
  12894. inline std::string center(const std::size_t& width,
  12895. const std::string::value_type& pad,
  12896. const T& t)
  12897. {
  12898. return center(width,pad,type_to_string(t));
  12899. }
  12900. template <typename T>
  12901. inline std::string right_align(const std::size_t& width,
  12902. const std::string::value_type& pad,
  12903. const T& t)
  12904. {
  12905. return right_align(width,pad,type_to_string(t));
  12906. }
  12907. template <typename T>
  12908. inline std::string left_align(const std::size_t& width,
  12909. const std::string::value_type& pad,
  12910. const T& t)
  12911. {
  12912. return left_align(width,pad,type_to_string(t));
  12913. }
  12914. template <typename T>
  12915. inline std::string center(const std::size_t& width, const T& t)
  12916. {
  12917. return center(width,' ',type_to_string(t));
  12918. }
  12919. template <typename T>
  12920. inline std::string right_align(const std::size_t& width, const T& t)
  12921. {
  12922. return right_align(width,' ',type_to_string(t));
  12923. }
  12924. template <typename T>
  12925. inline std::string left_align(const std::size_t& width, const T& t)
  12926. {
  12927. return left_align(width,' ',type_to_string(t));
  12928. }
  12929. inline std::string remaining_string(const std::size_t& index,
  12930. const std::string& str)
  12931. {
  12932. return (index < str.size()) ? str.substr(index,str.size() - index) : str;
  12933. }
  12934. inline void remaining_string(const std::size_t& index,
  12935. const std::string& str,
  12936. std::string& result)
  12937. {
  12938. result = (index < str.size()) ? str.substr(index,str.size() - index) : str;
  12939. }
  12940. inline bool is_letter(const char c)
  12941. {
  12942. return (('A' <= c) && ( c <= 'Z')) || (('a' <= c) && ( c <= 'z'));
  12943. }
  12944. inline bool is_lowercase_letter(const char c)
  12945. {
  12946. return (('a' <= c) && ( c <= 'z'));
  12947. }
  12948. inline bool is_uppercase_letter(const char c)
  12949. {
  12950. return (('A' <= c) && ( c <= 'Z'));
  12951. }
  12952. inline bool is_digit(const char c)
  12953. {
  12954. return (('0' <= c) && ( c <= '9'));
  12955. }
  12956. inline bool is_hex_digit(const char c)
  12957. {
  12958. return (('0' <= c) && (c <= '9')) ||
  12959. (('A' <= c) && (c <= 'F')) ||
  12960. (('a' <= c) && (c <= 'f'));
  12961. }
  12962. inline bool is_letter_or_digit(const char c)
  12963. {
  12964. return (is_letter(c) || is_digit(c));
  12965. }
  12966. inline bool is_all_letters(const std::string& s)
  12967. {
  12968. for (std::size_t i = 0; i < s.size(); ++i)
  12969. {
  12970. if (!is_letter(s[i]))
  12971. return false;
  12972. }
  12973. return true;
  12974. }
  12975. inline bool is_all_digits(const std::string& s)
  12976. {
  12977. for (std::size_t i = 0; i < s.size(); ++i)
  12978. {
  12979. if (!is_digit(s[i]))
  12980. return false;
  12981. }
  12982. return true;
  12983. }
  12984. inline void swap_inplace(std::string& s, const std::size_t& i0, const std::size_t& i1)
  12985. {
  12986. if (i0 >= s.size()) return;
  12987. if (i1 >= s.size()) return;
  12988. std::swap(s[i0],s[i1]);
  12989. }
  12990. inline std::string swap(const std::string& s, const std::size_t& i0, const std::size_t& i1)
  12991. {
  12992. std::string result = s;
  12993. swap_inplace(result,i0,i1);
  12994. return result;
  12995. }
  12996. inline void remove_inplace(std::string& s, const std::size_t& index)
  12997. {
  12998. if (index >= s.size())
  12999. return;
  13000. std::memcpy(const_cast<char*>(s.data() + index), const_cast<char*>(s.data() + (index + 1)), s.size() - index);
  13001. s.resize(s.size() - 1);
  13002. }
  13003. inline std::string remove(const std::string& s, const std::size_t& index)
  13004. {
  13005. std::string result = s;
  13006. remove_inplace(result,index);
  13007. return result;
  13008. }
  13009. inline void insert_inplace(std::string& s, const std::size_t& index, const char c)
  13010. {
  13011. s.resize(s.size() + 1);
  13012. std::memcpy(const_cast<char*>(s.data() + index + 1), const_cast<char*>(s.data() + (index)), s.size() - index);
  13013. s[index] = c;
  13014. }
  13015. inline std::string insert(const std::string& s, const std::size_t& index, const char c)
  13016. {
  13017. std::string result = s;
  13018. insert_inplace(result,index,c);
  13019. return result;
  13020. }
  13021. } // namespace text
  13022. namespace find_mode
  13023. {
  13024. enum type
  13025. {
  13026. exactly_n,
  13027. atleast_n
  13028. };
  13029. }
  13030. namespace find_type
  13031. {
  13032. enum type
  13033. {
  13034. digits,
  13035. letters,
  13036. lowercase_letters,
  13037. uppercase_letters,
  13038. letters_digits
  13039. };
  13040. }
  13041. namespace details
  13042. {
  13043. template <typename Iterator>
  13044. struct range_type
  13045. {
  13046. typedef typename std::pair<Iterator,Iterator> type;
  13047. };
  13048. template <typename Iterator, typename Predicate>
  13049. inline typename range_type<Iterator>::type find_exactly_n_consecutive_values(const std::size_t n,
  13050. Predicate p,
  13051. Iterator itr,
  13052. const Iterator end,
  13053. const bool stateful_predicate = false)
  13054. {
  13055. if (static_cast<unsigned int>(std::distance(itr,end)) < n)
  13056. return typename range_type<Iterator>::type(end,end);
  13057. std::size_t count = n;
  13058. while (end != itr)
  13059. {
  13060. if (p(*itr))
  13061. {
  13062. if (0 != --count)
  13063. ++itr;
  13064. else
  13065. {
  13066. std::advance(itr,1 - n);
  13067. return typename range_type<Iterator>::type(itr,itr + n);
  13068. }
  13069. }
  13070. else
  13071. {
  13072. ++itr;
  13073. while ((end != itr) && !p(*itr))
  13074. ++itr;
  13075. if (!stateful_predicate)
  13076. count = n;
  13077. else
  13078. {
  13079. --count;
  13080. ++itr;
  13081. }
  13082. }
  13083. }
  13084. return typename range_type<Iterator>::type(end,end);
  13085. }
  13086. template <typename Iterator, typename Predicate>
  13087. inline typename range_type<Iterator>::type find_atleast_n_consecutive_values(const std::size_t n,
  13088. Predicate p,
  13089. Iterator itr,
  13090. const Iterator end)
  13091. {
  13092. if (static_cast<unsigned int>(std::distance(itr,end)) < n)
  13093. return typename range_type<Iterator>::type(end,end);
  13094. std::size_t count = 0;
  13095. while (end != itr)
  13096. {
  13097. if (p(*itr))
  13098. {
  13099. ++count;
  13100. ++itr;
  13101. }
  13102. else
  13103. {
  13104. if (count >= n)
  13105. {
  13106. std::advance(itr,-static_cast<int>(count));
  13107. return typename range_type<Iterator>::type(itr,itr + count);
  13108. }
  13109. while ((end != itr) && !p(*itr))
  13110. ++itr;
  13111. count = 0;
  13112. }
  13113. }
  13114. if (count >= n)
  13115. {
  13116. std::advance(itr,-static_cast<int>(count));
  13117. return typename range_type<Iterator>::type(itr,itr + count);
  13118. }
  13119. else
  13120. return typename range_type<Iterator>::type(end,end);
  13121. }
  13122. template <typename Iterator, typename Predicate>
  13123. inline typename range_type<Iterator>::type find_exactly_n_consecutive_values(const std::size_t n,
  13124. Predicate p,
  13125. typename details::range_type<Iterator>::type range,
  13126. const bool stateful_predicate = false)
  13127. {
  13128. return find_exactly_n_consecutive_values(n,p,range.first,range.second,stateful_predicate);
  13129. }
  13130. template <typename Iterator, typename Predicate>
  13131. inline typename range_type<Iterator>::type find_atleast_n_consecutive_values(const std::size_t n,
  13132. Predicate p,
  13133. typename details::range_type<Iterator>::type range)
  13134. {
  13135. return find_atleast_n_consecutive_values(n,p,range.first,range.second);
  13136. }
  13137. template <typename Iterator, typename Predicate>
  13138. inline typename range_type<Iterator>::type find_n_consecutive_values(const std::size_t n,
  13139. find_mode::type mode,
  13140. Predicate p,
  13141. Iterator itr,
  13142. const Iterator end)
  13143. {
  13144. switch (mode)
  13145. {
  13146. case find_mode::exactly_n : return find_exactly_n_consecutive_values(n,p,itr,end);
  13147. case find_mode::atleast_n : return find_atleast_n_consecutive_values(n,p,itr,end);
  13148. default : return typename range_type<Iterator>::type(end,end);
  13149. }
  13150. }
  13151. template <typename Iterator,typename Predicate>
  13152. inline bool match_exactly_n_consecutive_values(const std::size_t n,
  13153. Predicate p,
  13154. Iterator itr,
  13155. const Iterator end)
  13156. {
  13157. if (static_cast<unsigned int>(std::distance(itr,end)) < n)
  13158. return false;
  13159. std::size_t count = n;
  13160. while (end != itr)
  13161. {
  13162. if (p(*itr))
  13163. {
  13164. if (0 == --count)
  13165. return true;
  13166. else
  13167. ++itr;
  13168. }
  13169. else
  13170. return false;
  13171. }
  13172. return false;
  13173. }
  13174. template <typename Iterator,typename Predicate>
  13175. inline bool match_atleast_n_consecutive_values(const std::size_t n,
  13176. Predicate p,
  13177. Iterator itr,
  13178. const Iterator end)
  13179. {
  13180. if (static_cast<unsigned int>(std::distance(itr,end)) < n)
  13181. return false;
  13182. std::size_t count = 0;
  13183. while (end != itr)
  13184. {
  13185. if (p(*itr))
  13186. {
  13187. ++count;
  13188. ++itr;
  13189. }
  13190. else if (count >= n)
  13191. return true;
  13192. else
  13193. return false;
  13194. }
  13195. return false;
  13196. }
  13197. template <typename Iterator,typename Predicate>
  13198. inline bool match_n_consecutive_values(const std::size_t n,
  13199. find_mode::type mode,
  13200. Predicate p,
  13201. Iterator itr,
  13202. const Iterator end)
  13203. {
  13204. switch (mode)
  13205. {
  13206. case find_mode::exactly_n : return match_exactly_n_consecutive_values(n,p,itr,end);
  13207. case find_mode::atleast_n : return match_atleast_n_consecutive_values(n,p,itr,end);
  13208. default : return false;
  13209. }
  13210. }
  13211. }
  13212. template <typename Iterator>
  13213. inline typename details::range_type<Iterator>::type find_n_consecutive(const std::size_t n,
  13214. find_type::type type,
  13215. find_mode::type mode,
  13216. typename details::range_type<Iterator>::type range)
  13217. {
  13218. switch (type)
  13219. {
  13220. case find_type::digits : return details::find_n_consecutive_values<Iterator>(n,
  13221. mode,
  13222. strtk::text::is_digit,
  13223. range.first,range.second);
  13224. case find_type::letters : return details::find_n_consecutive_values<Iterator>(n,
  13225. mode,
  13226. strtk::text::is_letter,
  13227. range.first,range.second);
  13228. case find_type::lowercase_letters : return details::find_n_consecutive_values<Iterator>(n,
  13229. mode,
  13230. strtk::text::is_lowercase_letter,
  13231. range.first,range.second);
  13232. case find_type::uppercase_letters : return details::find_n_consecutive_values<Iterator>(n,
  13233. mode,
  13234. strtk::text::is_uppercase_letter,
  13235. range.first,range.second);
  13236. case find_type::letters_digits : return details::find_n_consecutive_values<Iterator>(n,
  13237. mode,
  13238. strtk::text::is_letter_or_digit,
  13239. range.first,range.second);
  13240. default : return typename details::range_type<Iterator>::type(range.second,range.second);
  13241. }
  13242. }
  13243. template <typename Iterator>
  13244. inline bool match_n_consecutive(const std::size_t n,
  13245. find_type::type type,
  13246. find_mode::type mode,
  13247. typename details::range_type<Iterator>::type range)
  13248. {
  13249. switch (type)
  13250. {
  13251. case find_type::digits : return details::match_n_consecutive_values<Iterator>(n,
  13252. mode,
  13253. strtk::text::is_digit,
  13254. range.first,range.second);
  13255. case find_type::letters : return details::match_n_consecutive_values<Iterator>(n,
  13256. mode,
  13257. strtk::text::is_letter,
  13258. range.first,range.second);
  13259. case find_type::lowercase_letters : return details::match_n_consecutive_values<Iterator>(n,
  13260. mode,
  13261. strtk::text::is_lowercase_letter,
  13262. range.first,range.second);
  13263. case find_type::uppercase_letters : return details::match_n_consecutive_values<Iterator>(n,
  13264. mode,
  13265. strtk::text::is_uppercase_letter,
  13266. range.first,range.second);
  13267. case find_type::letters_digits : return details::match_n_consecutive_values<Iterator>(n,
  13268. mode,
  13269. strtk::text::is_letter_or_digit,
  13270. range.first,range.second);
  13271. default : return false;
  13272. }
  13273. }
  13274. template <typename Predicate,
  13275. typename OutputIterator>
  13276. inline std::size_t split_on_consecutive(const std::size_t n,
  13277. Predicate p,
  13278. char* begin,
  13279. char* end,
  13280. OutputIterator out,
  13281. const bool stateful_predicate = false)
  13282. {
  13283. if (0 == n) return 0;
  13284. typedef char* iterator_type;
  13285. typedef details::range_type<iterator_type>::type range_type;
  13286. range_type itr_range(begin,end);
  13287. std::size_t match_count = 0;
  13288. while (end != itr_range.first)
  13289. {
  13290. range_type found_itr =
  13291. details::find_exactly_n_consecutive_values<iterator_type,Predicate>(n,
  13292. p,
  13293. itr_range,
  13294. stateful_predicate);
  13295. if ((end == found_itr.first) && (found_itr.first == found_itr.second))
  13296. {
  13297. break;
  13298. }
  13299. else
  13300. {
  13301. (*out) = found_itr;
  13302. ++out;
  13303. ++match_count;
  13304. itr_range.first = found_itr.second;
  13305. }
  13306. }
  13307. return match_count;
  13308. }
  13309. template <typename Predicate,
  13310. typename OutputIterator>
  13311. inline std::size_t split_on_consecutive(const std::size_t n,
  13312. const std::size_t m,
  13313. Predicate p,
  13314. char* begin,
  13315. char* end,
  13316. OutputIterator out)
  13317. {
  13318. if (0 == n) return 0;
  13319. typedef char* iterator_type;
  13320. typedef details::range_type<iterator_type>::type range_type;
  13321. range_type itr_range(begin,end);
  13322. std::size_t match_count = 0;
  13323. while ((end != itr_range.first) && (match_count <= n))
  13324. {
  13325. range_type found_itr = details::find_exactly_n_consecutive_values(m,p,itr_range);
  13326. if ((end == found_itr.first) && (found_itr.first == found_itr.second))
  13327. {
  13328. break;
  13329. }
  13330. else
  13331. {
  13332. (*out) = found_itr;
  13333. ++out;
  13334. ++match_count;
  13335. itr_range.first = found_itr.second;
  13336. }
  13337. }
  13338. return match_count;
  13339. }
  13340. template <typename InputIterator, typename OutputIterator>
  13341. inline std::size_t split_on_consecutive(const std::size_t& n,
  13342. const find_type::type type,
  13343. const find_mode::type mode,
  13344. char* begin,
  13345. char* end,
  13346. OutputIterator out)
  13347. {
  13348. if (0 == n) return 0;
  13349. typedef char* iterator_type;
  13350. typedef details::range_type<iterator_type>::type range_type;
  13351. range_type itr_range(begin,end);
  13352. std::size_t match_count = 0;
  13353. while (end != itr_range.first)
  13354. {
  13355. range_type found_itr = find_n_consecutive<iterator_type>(n,type,mode,itr_range);
  13356. if ((end == found_itr.first) && (found_itr.first == found_itr.second))
  13357. {
  13358. break;
  13359. }
  13360. else
  13361. {
  13362. (*out) = found_itr;
  13363. ++out;
  13364. ++match_count;
  13365. itr_range.first = found_itr.second;
  13366. }
  13367. }
  13368. return match_count;
  13369. }
  13370. template <typename InputIterator, typename OutputIterator>
  13371. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13372. const std::size_t& m,
  13373. const find_type::type type,
  13374. const find_mode::type mode,
  13375. char* begin,
  13376. char* end,
  13377. OutputIterator out)
  13378. {
  13379. if (0 == n) return 0;
  13380. typedef char* iterator_type;
  13381. typedef details::range_type<iterator_type>::type range_type;
  13382. range_type itr_range(begin,end);
  13383. std::size_t match_count = 0;
  13384. while ((end != itr_range.first) && (match_count <= n))
  13385. {
  13386. range_type found_itr = find_n_consecutive<iterator_type>(m,type,mode,itr_range);
  13387. if ((end == found_itr.first) && (found_itr.first == found_itr.second))
  13388. {
  13389. break;
  13390. }
  13391. else
  13392. {
  13393. (*out) = found_itr;
  13394. ++out;
  13395. ++match_count;
  13396. itr_range.first = found_itr.second;
  13397. }
  13398. }
  13399. return match_count;
  13400. }
  13401. template <typename OutputIterator>
  13402. inline std::size_t split_on_consecutive(const std::size_t& n,
  13403. const find_type::type type,
  13404. const find_mode::type mode,
  13405. const char* begin,
  13406. const char* end,
  13407. OutputIterator out)
  13408. {
  13409. return split_on_consecutive<char*,OutputIterator>(n,
  13410. type,
  13411. mode,
  13412. const_cast<char*>(begin),
  13413. const_cast<char*>(end),
  13414. out);
  13415. }
  13416. template <typename OutputIterator>
  13417. inline std::size_t split_on_consecutive(const std::size_t& n,
  13418. const find_type::type type,
  13419. const find_mode::type mode,
  13420. const unsigned char* begin,
  13421. const unsigned char* end,
  13422. OutputIterator out)
  13423. {
  13424. return split_on_consecutive<OutputIterator>(n,
  13425. type,
  13426. mode,
  13427. reinterpret_cast<const char*>(begin),
  13428. reinterpret_cast<const char*>(end),
  13429. out);
  13430. }
  13431. template <typename OutputIterator>
  13432. inline std::size_t split_on_consecutive(const std::size_t& n,
  13433. const find_type::type type,
  13434. const find_mode::type mode,
  13435. const std::string& str,
  13436. OutputIterator out)
  13437. {
  13438. return split_on_consecutive<OutputIterator>(n,
  13439. type,
  13440. mode,
  13441. str.data(),
  13442. str.data() + str.size(),
  13443. out);
  13444. }
  13445. template <typename OutputIterator>
  13446. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13447. const std::size_t& m,
  13448. const find_type::type type,
  13449. const find_mode::type mode,
  13450. const char* begin,
  13451. const char* end,
  13452. OutputIterator out)
  13453. {
  13454. return split_on_consecutive_n<char*,OutputIterator>(n,
  13455. m,
  13456. type,
  13457. mode,
  13458. const_cast<char*>(begin),
  13459. const_cast<char*>(end),
  13460. out);
  13461. }
  13462. template <typename OutputIterator>
  13463. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13464. const std::size_t& m,
  13465. const find_type::type type,
  13466. const find_mode::type mode,
  13467. const unsigned char* begin,
  13468. const unsigned char* end,
  13469. OutputIterator out)
  13470. {
  13471. return split_on_consecutive_n<OutputIterator>(n,
  13472. m,
  13473. type,
  13474. mode,
  13475. reinterpret_cast<const char*>(begin),
  13476. reinterpret_cast<const char*>(end),
  13477. out);
  13478. }
  13479. template <typename OutputIterator>
  13480. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13481. const std::size_t& m,
  13482. const find_type::type type,
  13483. const find_mode::type mode,
  13484. const std::string& str,
  13485. OutputIterator out)
  13486. {
  13487. return split_on_consecutive_n<OutputIterator>(n,
  13488. m,
  13489. type,
  13490. mode,
  13491. str.data(),
  13492. str.data() + str.size(),
  13493. out);
  13494. }
  13495. template <typename Predicate, typename OutputIterator>
  13496. inline std::size_t split_on_consecutive(const std::size_t& n,
  13497. Predicate p,
  13498. const char* begin,
  13499. const char* end,
  13500. OutputIterator out,
  13501. const bool stateful_predicate = false)
  13502. {
  13503. return split_on_consecutive<Predicate,
  13504. OutputIterator>(n,
  13505. p,
  13506. const_cast<char*>(begin),
  13507. const_cast<char*>(end),
  13508. out,
  13509. stateful_predicate);
  13510. }
  13511. template <typename Predicate, typename OutputIterator>
  13512. inline std::size_t split_on_consecutive(const std::size_t& n,
  13513. Predicate p,
  13514. const unsigned char* begin,
  13515. const unsigned char* end,
  13516. OutputIterator out,
  13517. const bool stateful_predicate = false)
  13518. {
  13519. return split_on_consecutive<Predicate,
  13520. OutputIterator>(n,
  13521. p,
  13522. reinterpret_cast<const char*>(begin),
  13523. reinterpret_cast<const char*>(end),
  13524. out,
  13525. stateful_predicate);
  13526. }
  13527. template <typename Predicate, typename OutputIterator>
  13528. inline std::size_t split_on_consecutive(const std::size_t& n,
  13529. Predicate p,
  13530. const std::string& str,
  13531. OutputIterator out,
  13532. const bool stateful_predicate = false)
  13533. {
  13534. return split_on_consecutive<Predicate,
  13535. OutputIterator>(n,
  13536. p,
  13537. str.data(),
  13538. str.data() + str.size(),
  13539. out,
  13540. stateful_predicate);
  13541. }
  13542. template <typename Predicate, typename OutputIterator>
  13543. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13544. const std::size_t& m,
  13545. Predicate p,
  13546. const char* begin,
  13547. const char* end,
  13548. OutputIterator out)
  13549. {
  13550. return split_on_consecutive_n<Predicate,
  13551. char*,
  13552. OutputIterator>(n,
  13553. m,
  13554. p,
  13555. const_cast<char*>(begin),
  13556. const_cast<char*>(end),
  13557. out);
  13558. }
  13559. template <typename Predicate, typename OutputIterator>
  13560. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13561. const std::size_t& m,
  13562. Predicate p,
  13563. const unsigned char* begin,
  13564. const unsigned char* end,
  13565. OutputIterator out)
  13566. {
  13567. return split_on_consecutive_n<Predicate,
  13568. OutputIterator>(n,
  13569. m,
  13570. p,
  13571. reinterpret_cast<const char*>(begin),
  13572. reinterpret_cast<const char*>(end),
  13573. out);
  13574. }
  13575. template <typename Predicate, typename OutputIterator>
  13576. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13577. const std::size_t& m,
  13578. Predicate p,
  13579. const std::string& str,
  13580. OutputIterator out)
  13581. {
  13582. return split_on_consecutive_n<Predicate,
  13583. OutputIterator>(n,
  13584. m,
  13585. p,
  13586. str.data(),
  13587. str.data() + str.size(),
  13588. out);
  13589. }
  13590. // Required for broken versions of GCC pre 4.5
  13591. namespace util { class value; }
  13592. namespace details
  13593. {
  13594. class expect_impl
  13595. {
  13596. public:
  13597. expect_impl(const std::string& s)
  13598. : s_(s)
  13599. {}
  13600. template <typename InputIterator>
  13601. inline bool operator()(InputIterator begin, InputIterator end)
  13602. {
  13603. if (static_cast<std::size_t>(std::distance(begin,end)) != s_.size())
  13604. return false;
  13605. else
  13606. return std::equal(s_.data(),s_.data() + s_.size(),begin);
  13607. }
  13608. inline expect_impl& ref()
  13609. {
  13610. return (*this);
  13611. }
  13612. inline void set_value(const std::string& s)
  13613. {
  13614. s_ = s;
  13615. }
  13616. private:
  13617. std::string s_;
  13618. };
  13619. class iexpect_impl
  13620. {
  13621. public:
  13622. iexpect_impl(const std::string& s)
  13623. : s_(s)
  13624. {}
  13625. template <typename InputIterator>
  13626. inline bool operator()(InputIterator begin, InputIterator end)
  13627. {
  13628. if (static_cast<std::size_t>(std::distance(begin,end)) != s_.size())
  13629. return false;
  13630. else
  13631. return std::equal(s_.data(),s_.data() + s_.size(),begin,imatch_char);
  13632. }
  13633. inline iexpect_impl& ref()
  13634. {
  13635. return (*this);
  13636. }
  13637. inline void set_value(const std::string& s)
  13638. {
  13639. s_ = s;
  13640. }
  13641. private:
  13642. std::string s_;
  13643. };
  13644. class like_impl
  13645. {
  13646. public:
  13647. like_impl(const std::string& s)
  13648. : s_(s)
  13649. {}
  13650. template <typename InputIterator>
  13651. inline bool operator()(InputIterator begin, InputIterator end)
  13652. {
  13653. typedef typename std::iterator_traits<InputIterator>::value_type value_type;
  13654. static const value_type zero_or_more = value_type('*');
  13655. static const value_type zero_or_one = value_type('?');
  13656. return strtk::match(s_.data(),s_.data() + s_.size(),begin,end,zero_or_more,zero_or_one);
  13657. }
  13658. inline like_impl& ref()
  13659. {
  13660. return (*this);
  13661. }
  13662. inline void set_pattern(const std::string& s)
  13663. {
  13664. s_ = s;
  13665. }
  13666. private:
  13667. std::string s_;
  13668. };
  13669. template <typename T>
  13670. class inrange_impl
  13671. {
  13672. public:
  13673. inrange_impl(T& t, const T& low, const T& hi)
  13674. : t_(&t),
  13675. low_(low),
  13676. hi_(hi)
  13677. {}
  13678. template <typename InputIterator>
  13679. inline bool operator()(InputIterator begin, InputIterator end)
  13680. {
  13681. T temp;
  13682. if (!strtk::string_to_type_converter(begin,end,temp))
  13683. return false;
  13684. else if (temp < low_)
  13685. return false;
  13686. else if (temp > hi_)
  13687. return false;
  13688. (*t_) = temp;
  13689. return true;
  13690. }
  13691. inline inrange_impl<T>& ref()
  13692. {
  13693. return (*this);
  13694. }
  13695. inline void set_low_hi(const T& low, const T& hi)
  13696. {
  13697. low_ = low;
  13698. hi_ = hi;
  13699. }
  13700. private:
  13701. T* t_;
  13702. T low_;
  13703. T hi_;
  13704. };
  13705. namespace trim_details
  13706. {
  13707. template <typename Type>
  13708. struct convert_impl
  13709. {
  13710. template <typename InputIterator>
  13711. static bool execute(InputIterator begin, InputIterator end,
  13712. const std::string& rem_chars,
  13713. std::size_t mode,
  13714. Type& t)
  13715. {
  13716. std::string s;
  13717. if (!strtk::string_to_type_converter(begin,end,s))
  13718. return false;
  13719. switch (mode)
  13720. {
  13721. case 0 : remove_leading_trailing(rem_chars,s); break;
  13722. case 1 : remove_leading (rem_chars,s); break;
  13723. case 2 : remove_trailing (rem_chars,s); break;
  13724. default : return false;
  13725. }
  13726. return strtk::string_to_type_converter(s,t);
  13727. }
  13728. };
  13729. template <>
  13730. struct convert_impl <std::string>
  13731. {
  13732. template <typename InputIterator>
  13733. static bool execute(InputIterator begin, InputIterator end,
  13734. const std::string& rem_chars,
  13735. std::size_t mode,
  13736. std::string& t)
  13737. {
  13738. if (!strtk::string_to_type_converter(begin,end,t))
  13739. return false;
  13740. switch (mode)
  13741. {
  13742. case 0 : remove_leading_trailing(rem_chars,t); break;
  13743. case 1 : remove_leading (rem_chars,t); break;
  13744. case 2 : remove_trailing (rem_chars,t); break;
  13745. default : return false;
  13746. }
  13747. return true;
  13748. }
  13749. };
  13750. }
  13751. template <typename T>
  13752. class trim_impl
  13753. {
  13754. public:
  13755. trim_impl(const std::size_t mode,
  13756. T& t,
  13757. const std::string& rem_chars = " ")
  13758. : mode_(mode),
  13759. t_(&t),
  13760. rem_chars_(rem_chars)
  13761. {}
  13762. template <typename InputIterator>
  13763. inline bool operator()(InputIterator begin, InputIterator end)
  13764. {
  13765. return trim_details::convert_impl<T>::execute(begin,end,rem_chars_,mode_,(*t_));
  13766. }
  13767. inline trim_impl<T>& ref()
  13768. {
  13769. return (*this);
  13770. }
  13771. private:
  13772. std::size_t mode_;
  13773. T* t_;
  13774. std::string rem_chars_;
  13775. };
  13776. class conv_to_lcase_impl
  13777. {
  13778. public:
  13779. conv_to_lcase_impl(std::string& s)
  13780. : s_(&s)
  13781. {}
  13782. template <typename InputIterator>
  13783. inline bool operator()(InputIterator begin, InputIterator end)
  13784. {
  13785. std::string& s = (*s_);
  13786. s.assign(begin,end);
  13787. convert_to_lowercase(s);
  13788. return true;
  13789. }
  13790. inline conv_to_lcase_impl& ref()
  13791. {
  13792. return (*this);
  13793. }
  13794. private:
  13795. std::string* s_;
  13796. };
  13797. class conv_to_ucase_impl
  13798. {
  13799. public:
  13800. conv_to_ucase_impl(std::string& s)
  13801. : s_(&s)
  13802. {}
  13803. template <typename InputIterator>
  13804. inline bool operator()(InputIterator begin, InputIterator end)
  13805. {
  13806. std::string& s = (*s_);
  13807. s.assign(begin,end);
  13808. convert_to_uppercase(s);
  13809. return true;
  13810. }
  13811. inline conv_to_ucase_impl& ref()
  13812. {
  13813. return (*this);
  13814. }
  13815. private:
  13816. std::string* s_;
  13817. };
  13818. class fill_array_impl
  13819. {
  13820. public:
  13821. fill_array_impl(unsigned char* data, const std::size_t& size)
  13822. : data_(data),
  13823. size_(size)
  13824. {}
  13825. template <typename InputIterator>
  13826. inline bool operator()(InputIterator begin, InputIterator end)
  13827. {
  13828. const std::size_t range_size = static_cast<std::size_t>(std::distance(begin,end));
  13829. if (range_size != size_)
  13830. return false;
  13831. std::memcpy(data_,begin,range_size);
  13832. return true;
  13833. }
  13834. inline fill_array_impl& ref()
  13835. {
  13836. return (*this);
  13837. }
  13838. inline fill_array_impl& set(unsigned char* data, const std::size_t& size)
  13839. {
  13840. data_ = data;
  13841. size_ = size;
  13842. return (*this);
  13843. }
  13844. inline fill_array_impl& set(char* data, const std::size_t& size)
  13845. {
  13846. data_ = reinterpret_cast<unsigned char*>(data);
  13847. size_ = size;
  13848. return (*this);
  13849. }
  13850. inline fill_array_impl& set_data(unsigned char* data)
  13851. {
  13852. data_ = data;
  13853. return (*this);
  13854. }
  13855. inline fill_array_impl& set_data(char* data)
  13856. {
  13857. data_ = reinterpret_cast<unsigned char*>(data);
  13858. return (*this);
  13859. }
  13860. inline fill_array_impl& set_size(const std::size_t& size)
  13861. {
  13862. size_ = size;
  13863. return (*this);
  13864. }
  13865. private:
  13866. unsigned char* data_;
  13867. std::size_t size_;
  13868. };
  13869. }
  13870. inline details::expect_impl expect(const std::string& s)
  13871. {
  13872. return details::expect_impl(s);
  13873. }
  13874. inline details::iexpect_impl iexpect(const std::string& s)
  13875. {
  13876. return details::iexpect_impl(s);
  13877. }
  13878. inline details::like_impl like(const std::string& s)
  13879. {
  13880. return details::like_impl(s);
  13881. }
  13882. template <typename T, typename T0, typename T1>
  13883. inline details::inrange_impl<T> inrange(T& t, const T0& low, const T1& hi)
  13884. {
  13885. return details::inrange_impl<T>(t,T(low),T(hi));
  13886. }
  13887. template <typename T>
  13888. inline details::trim_impl<T> trim(const std::string& rem_chars, T& t)
  13889. {
  13890. return details::trim_impl<T>(0,t,rem_chars);
  13891. }
  13892. template <typename T>
  13893. inline details::trim_impl<T> trim_leading(const std::string& rem_chars, T& t)
  13894. {
  13895. return details::trim_impl<T>(1,t,rem_chars);
  13896. }
  13897. template <typename T>
  13898. inline details::trim_impl<T> trim_trailing(const std::string& rem_chars, T& t)
  13899. {
  13900. return details::trim_impl<T>(2,t,rem_chars);
  13901. }
  13902. inline details::conv_to_lcase_impl as_lcase(std::string& s)
  13903. {
  13904. return details::conv_to_lcase_impl(s);
  13905. }
  13906. inline details::conv_to_ucase_impl as_ucase(std::string& s)
  13907. {
  13908. return details::conv_to_ucase_impl(s);
  13909. }
  13910. inline details::fill_array_impl fill_array(unsigned char* data, const std::size_t& size)
  13911. {
  13912. return details::fill_array_impl(data,size);
  13913. }
  13914. inline details::fill_array_impl fill_array(char* data, const std::size_t& size)
  13915. {
  13916. return details::fill_array_impl(reinterpret_cast<unsigned char*>(data),size);
  13917. }
  13918. template <std::size_t N>
  13919. inline details::fill_array_impl fill_array(unsigned char (&data)[N])
  13920. {
  13921. return details::fill_array_impl(data,N);
  13922. }
  13923. template <std::size_t N>
  13924. inline details::fill_array_impl fill_array(char (&data)[N])
  13925. {
  13926. return details::fill_array_impl(reinterpret_cast<unsigned char*>(data),N);
  13927. }
  13928. inline details::fill_array_impl fill_array(std::string& data, const std::size_t& size)
  13929. {
  13930. return fill_array(const_cast<char*>(data.data()),size);
  13931. }
  13932. inline details::fill_array_impl fill_array(std::string& data)
  13933. {
  13934. return fill_array(const_cast<char*>(data.data()),data.size());
  13935. }
  13936. namespace details
  13937. {
  13938. static const unsigned char digit_table[] =
  13939. {
  13940. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xFF - 0x07
  13941. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x08 - 0x0F
  13942. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x10 - 0x17
  13943. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x18 - 0x1F
  13944. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x20 - 0x27
  13945. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x28 - 0x2F
  13946. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 0x30 - 0x37
  13947. 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x38 - 0x3F
  13948. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x40 - 0x47
  13949. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x48 - 0x4F
  13950. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x50 - 0x57
  13951. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x58 - 0x5F
  13952. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x60 - 0x67
  13953. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x68 - 0x6F
  13954. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x70 - 0x77
  13955. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x78 - 0x7F
  13956. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x80 - 0x87
  13957. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x88 - 0x8F
  13958. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x90 - 0x97
  13959. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x98 - 0x9F
  13960. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA0 - 0xA7
  13961. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA8 - 0xAF
  13962. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB0 - 0xB7
  13963. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB8 - 0xBF
  13964. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC0 - 0xC7
  13965. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC8 - 0xCF
  13966. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD0 - 0xD7
  13967. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD8 - 0xDF
  13968. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE0 - 0xE7
  13969. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE8 - 0xEF
  13970. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xF0 - 0xF7
  13971. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 0xF8 - 0xFF
  13972. };
  13973. static const std::size_t digit_table_size = sizeof(digit_table) / sizeof(unsigned char);
  13974. template <typename T>
  13975. static inline bool is_invalid_digit(const T& t)
  13976. {
  13977. static const unsigned int invalid_digit = 0xFF;
  13978. return (static_cast<T>(invalid_digit) == t);
  13979. }
  13980. template <typename T>
  13981. static inline bool is_valid_digit(const T& t)
  13982. {
  13983. static const unsigned int invalid_digit = 0xFF;
  13984. return (static_cast<T>(invalid_digit) != t);
  13985. }
  13986. static const unsigned char digitr[] =
  13987. {
  13988. "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  13989. };
  13990. static const unsigned char rev_3digit_lut[] =
  13991. {
  13992. "000100200300400500600700800900010110210310410510610710810910020120220320420"
  13993. "520620720820920030130230330430530630730830930040140240340440540640740840940"
  13994. "050150250350450550650750850950060160260360460560660760860960070170270370470"
  13995. "570670770870970080180280380480580680780880980090190290390490590690790890990"
  13996. "001101201301401501601701801901011111211311411511611711811911021121221321421"
  13997. "521621721821921031131231331431531631731831931041141241341441541641741841941"
  13998. "051151251351451551651751851951061161261361461561661761861961071171271371471"
  13999. "571671771871971081181281381481581681781881981091191291391491591691791891991"
  14000. "002102202302402502602702802902012112212312412512612712812912022122222322422"
  14001. "522622722822922032132232332432532632732832932042142242342442542642742842942"
  14002. "052152252352452552652752852952062162262362462562662762862962072172272372472"
  14003. "572672772872972082182282382482582682782882982092192292392492592692792892992"
  14004. "003103203303403503603703803903013113213313413513613713813913023123223323423"
  14005. "523623723823923033133233333433533633733833933043143243343443543643743843943"
  14006. "053153253353453553653753853953063163263363463563663763863963073173273373473"
  14007. "573673773873973083183283383483583683783883983093193293393493593693793893993"
  14008. "004104204304404504604704804904014114214314414514614714814914024124224324424"
  14009. "524624724824924034134234334434534634734834934044144244344444544644744844944"
  14010. "054154254354454554654754854954064164264364464564664764864964074174274374474"
  14011. "574674774874974084184284384484584684784884984094194294394494594694794894994"
  14012. "005105205305405505605705805905015115215315415515615715815915025125225325425"
  14013. "525625725825925035135235335435535635735835935045145245345445545645745845945"
  14014. "055155255355455555655755855955065165265365465565665765865965075175275375475"
  14015. "575675775875975085185285385485585685785885985095195295395495595695795895995"
  14016. "006106206306406506606706806906016116216316416516616716816916026126226326426"
  14017. "526626726826926036136236336436536636736836936046146246346446546646746846946"
  14018. "056156256356456556656756856956066166266366466566666766866966076176276376476"
  14019. "576676776876976086186286386486586686786886986096196296396496596696796896996"
  14020. "007107207307407507607707807907017117217317417517617717817917027127227327427"
  14021. "527627727827927037137237337437537637737837937047147247347447547647747847947"
  14022. "057157257357457557657757857957067167267367467567667767867967077177277377477"
  14023. "577677777877977087187287387487587687787887987097197297397497597697797897997"
  14024. "008108208308408508608708808908018118218318418518618718818918028128228328428"
  14025. "528628728828928038138238338438538638738838938048148248348448548648748848948"
  14026. "058158258358458558658758858958068168268368468568668768868968078178278378478"
  14027. "578678778878978088188288388488588688788888988098198298398498598698798898998"
  14028. "009109209309409509609709809909019119219319419519619719819919029129229329429"
  14029. "529629729829929039139239339439539639739839939049149249349449549649749849949"
  14030. "059159259359459559659759859959069169269369469569669769869969079179279379479"
  14031. "579679779879979089189289389489589689789889989099199299399499599699799899999"
  14032. };
  14033. static const unsigned char rev_2digit_lut[] =
  14034. {
  14035. "0010203040506070809001112131415161718191"
  14036. "0212223242526272829203132333435363738393"
  14037. "0414243444546474849405152535455565758595"
  14038. "0616263646566676869607172737475767778797"
  14039. "0818283848586878889809192939495969798999"
  14040. };
  14041. #define strtk_register_pod_type(T)\
  14042. template<> struct is_pod<T>{ typedef yes_t result_t; enum {result = true }; };\
  14043. template<> struct is_pod<const T>{ typedef yes_t result_t; enum {result = true }; };\
  14044. template<> struct is_pod<volatile T>{ typedef yes_t result_t; enum {result = true }; };\
  14045. template<> struct is_pod<const volatile T>{ typedef yes_t result_t; enum {result = true }; };\
  14046. strtk_register_pod_type(bool)
  14047. strtk_register_pod_type(signed char)
  14048. strtk_register_pod_type(char)
  14049. strtk_register_pod_type(short)
  14050. strtk_register_pod_type(int)
  14051. strtk_register_pod_type(long int)
  14052. strtk_register_pod_type(long long int)
  14053. strtk_register_pod_type(unsigned char)
  14054. strtk_register_pod_type(unsigned short)
  14055. strtk_register_pod_type(unsigned int)
  14056. strtk_register_pod_type(unsigned long int)
  14057. strtk_register_pod_type(unsigned long long int)
  14058. strtk_register_pod_type(float)
  14059. strtk_register_pod_type(double)
  14060. strtk_register_pod_type(long double)
  14061. #undef strtk_register_pod_type
  14062. template <typename>
  14063. struct numeric { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; };
  14064. template<> struct numeric<short> { enum { length = 5, size = 16, bound_length = 4}; };
  14065. template<> struct numeric<unsigned short> { enum { length = 5, size = 16, bound_length = 4}; };
  14066. template<> struct numeric<int> { enum { length = 10, size = 16, bound_length = 9}; };
  14067. template<> struct numeric<unsigned int> { enum { length = 10, size = 16, bound_length = 9}; };
  14068. template<> struct numeric<long> { enum { length = 10, size = 16, bound_length = 9}; };
  14069. template<> struct numeric<unsigned long> { enum { length = 10, size = 16, bound_length = 9}; };
  14070. template<> struct numeric<long long> { enum { length = 19, size = 24, bound_length = 18}; };
  14071. template<> struct numeric<unsigned long long int> { enum { length = 20, size = 24, bound_length = 19}; };
  14072. template<> struct numeric<float> { enum { min_exp = -38, max_exp = +38, precision = 10}; };
  14073. template<> struct numeric<double> { enum { min_exp = -308, max_exp = +308, precision = 15}; };
  14074. template<> struct numeric<long double> { enum { min_exp = -308, max_exp = +308, precision = 15}; };
  14075. #define strtk_register_unsigned_type_tag(T)\
  14076. template<> struct supported_conversion_to_type<T> { typedef unsigned_type_tag type; };\
  14077. template<> struct supported_conversion_from_type<T> { typedef unsigned_type_tag type; };
  14078. #define strtk_register_signed_type_tag(T)\
  14079. template<> struct supported_conversion_to_type<T>{ typedef signed_type_tag type; };\
  14080. template<> struct supported_conversion_from_type<T> { typedef signed_type_tag type; };
  14081. #define strtk_register_real_type_tag(T)\
  14082. template<> struct supported_conversion_to_type<T>{ typedef real_type_tag type; };
  14083. #define strtk_register_byte_type_tag(T)\
  14084. template<> struct supported_conversion_to_type<T>{ typedef byte_type_tag type; };\
  14085. template<> struct supported_conversion_from_type<T> { typedef byte_type_tag type; };
  14086. #define strtk_register_hex_number_type_tag(T)\
  14087. template<> struct supported_conversion_to_type<T >{ typedef hex_number_type_tag type; };
  14088. template<> struct supported_conversion_to_type<hex_to_string_sink>{ typedef hex_string_type_tag type; };
  14089. #define strtk_register_base64_type_tag(T)\
  14090. template<> struct supported_conversion_to_type<T >{ typedef base64_type_tag type; };
  14091. #define strtk_register_supported_iterator_type(T)\
  14092. template<> struct supported_iterator_type<T> { enum { value = true }; };
  14093. template<> struct supported_conversion_to_type<bool> { typedef bool_type_tag type; };
  14094. template<> struct supported_iterator_type<bool> { enum { value = true }; };
  14095. template<> struct supported_conversion_to_type<std::string> { typedef stdstring_type_tag type; };
  14096. template<> struct supported_iterator_type<std::string> { enum { value = true }; };
  14097. template<> struct supported_conversion_to_type<strtk::util::value> { typedef value_type_tag type; };
  14098. template<> struct supported_conversion_from_type<strtk::util::value> { typedef value_type_tag type; };
  14099. template<> struct supported_iterator_type<strtk::util::value> { enum { value = true }; };
  14100. template<> struct supported_conversion_to_type<strtk::details::expect_impl> { typedef expect_type_tag type; };
  14101. template<> struct supported_iterator_type<strtk::details::expect_impl> { enum { value = true }; };
  14102. template<> struct supported_conversion_to_type<strtk::details::iexpect_impl> { typedef expect_type_tag type; };
  14103. template<> struct supported_iterator_type<strtk::details::iexpect_impl> { enum { value = true }; };
  14104. template<> struct supported_conversion_to_type<strtk::details::like_impl> { typedef like_type_tag type; };
  14105. template<> struct supported_iterator_type<strtk::details::like_impl> { enum { value = true }; };
  14106. template<> struct supported_conversion_to_type<strtk::details::fill_array_impl> { typedef fillchararray_type_tag type; };
  14107. template<> struct supported_iterator_type<strtk::details::fill_array_impl> { enum { value = true }; };
  14108. template<> struct supported_conversion_to_type<strtk::details::conv_to_lcase_impl> { typedef lcase_type_tag type; };
  14109. template<> struct supported_iterator_type<strtk::details::conv_to_lcase_impl> { enum { value = true }; };
  14110. template<> struct supported_conversion_to_type<strtk::details::conv_to_ucase_impl> { typedef ucase_type_tag type; };
  14111. template<> struct supported_iterator_type<strtk::details::conv_to_ucase_impl> { enum { value = true }; };
  14112. #define strtk_register_inrange_type_tag(T)\
  14113. template<> struct supported_conversion_to_type<strtk::details::inrange_impl<T> > { typedef inrange_type_tag type; };\
  14114. template<> struct supported_iterator_type<strtk::details::inrange_impl<T> > { enum { value = true }; };\
  14115. #define strtk_register_trim_type_tag(T)\
  14116. template<> struct supported_conversion_to_type<strtk::details::trim_impl<T> > { typedef trim_type_tag type; };\
  14117. template<> struct supported_iterator_type<strtk::details::trim_impl<T> > { enum { value = true }; };
  14118. #define strtk_register_stdstring_range_type_tag(T)\
  14119. template<> struct supported_conversion_to_type< std::pair<T,T> >{ typedef stdstring_range_type_tag type; };
  14120. #define strtk_register_sink_type_tag(T)\
  14121. template<> struct supported_conversion_to_type<sink_type<std::vector<T> > > { typedef sink_type_tag type; };\
  14122. template<> struct supported_conversion_to_type<sink_type<std::deque<T> > > { typedef sink_type_tag type; };\
  14123. template<> struct supported_conversion_to_type<sink_type<std::list<T> > > { typedef sink_type_tag type; };\
  14124. template<> struct supported_conversion_to_type<sink_type<std::set<T> > > { typedef sink_type_tag type; };\
  14125. template<> struct supported_conversion_to_type<sink_type<std::multiset<T> > > { typedef sink_type_tag type; };\
  14126. template<> struct supported_conversion_to_type<sink_type<std::queue<T> > > { typedef sink_type_tag type; };\
  14127. template<> struct supported_conversion_to_type<sink_type<std::stack<T> > > { typedef sink_type_tag type; };\
  14128. template<> struct supported_conversion_to_type<sink_type<std::priority_queue<T> > > { typedef sink_type_tag type; };\
  14129. template<> struct supported_conversion_from_type<sink_type<std::vector<T> > > { typedef sink_type_tag type; };\
  14130. template<> struct supported_conversion_from_type<sink_type<std::deque<T> > > { typedef sink_type_tag type; };\
  14131. template<> struct supported_conversion_from_type<sink_type<std::list<T> > > { typedef sink_type_tag type; };\
  14132. template<> struct supported_conversion_from_type<sink_type<std::set<T> > > { typedef sink_type_tag type; };\
  14133. template<> struct supported_conversion_from_type<sink_type<std::multiset<T> > > { typedef sink_type_tag type; };\
  14134. template<> struct supported_conversion_from_type<sink_type<std::queue<T> > > { typedef sink_type_tag type; };\
  14135. template<> struct supported_conversion_from_type<sink_type<std::stack<T> > > { typedef sink_type_tag type; };\
  14136. template<> struct supported_conversion_from_type<sink_type<std::priority_queue<T> > > { typedef sink_type_tag type; };\
  14137. #define strtk_register_stl_container_to_string_conv_type_tag(T)\
  14138. template<> struct supported_conversion_from_type<std::vector<T> > { typedef stl_seq_type_tag type; };\
  14139. template<> struct supported_conversion_from_type<std::deque<T> > { typedef stl_seq_type_tag type; };\
  14140. template<> struct supported_conversion_from_type<std::list<T> > { typedef stl_seq_type_tag type; };\
  14141. template<> struct supported_conversion_from_type<std::set<T> > { typedef stl_seq_type_tag type; };\
  14142. template<> struct supported_conversion_from_type<std::multiset<T> > { typedef stl_seq_type_tag type; };\
  14143. template<> struct supported_conversion_from_type<std::queue<T> > { typedef stl_seq_type_tag type; };\
  14144. template<> struct supported_conversion_from_type<std::stack<T> > { typedef stl_seq_type_tag type; };\
  14145. template<> struct supported_conversion_from_type<std::priority_queue<T> > { typedef stl_seq_type_tag type; };\
  14146. template<> struct supported_conversion_to_type<ignore_token>{ typedef ignore_token_type_tag type; };
  14147. #define strtk_register_sequence_iterator_type(sequence)\
  14148. strtk_register_supported_iterator_type(sequence<char>::iterator)\
  14149. strtk_register_supported_iterator_type(sequence<char>::const_iterator)\
  14150. strtk_register_supported_iterator_type(sequence<unsigned char>::iterator)\
  14151. strtk_register_supported_iterator_type(sequence<unsigned char>::const_iterator)
  14152. strtk_register_unsigned_type_tag(unsigned short)
  14153. strtk_register_unsigned_type_tag(unsigned int)
  14154. strtk_register_unsigned_type_tag(unsigned long)
  14155. strtk_register_unsigned_type_tag(unsigned long long int)
  14156. strtk_register_signed_type_tag(short)
  14157. strtk_register_signed_type_tag(int)
  14158. strtk_register_signed_type_tag(long)
  14159. strtk_register_signed_type_tag(long long)
  14160. strtk_register_real_type_tag(float)
  14161. strtk_register_real_type_tag(double)
  14162. strtk_register_real_type_tag(long double)
  14163. strtk_register_byte_type_tag(unsigned char)
  14164. strtk_register_byte_type_tag(signed char)
  14165. strtk_register_byte_type_tag(char)
  14166. strtk_register_hex_number_type_tag(hex_to_number_sink<short>)
  14167. strtk_register_hex_number_type_tag(hex_to_number_sink<int>)
  14168. strtk_register_hex_number_type_tag(hex_to_number_sink<long>)
  14169. strtk_register_hex_number_type_tag(hex_to_number_sink<unsigned short>)
  14170. strtk_register_hex_number_type_tag(hex_to_number_sink<unsigned int>)
  14171. strtk_register_hex_number_type_tag(hex_to_number_sink<unsigned long>)
  14172. strtk_register_hex_number_type_tag(hex_to_number_sink<unsigned long long int>)
  14173. strtk_register_base64_type_tag(base64_to_number_sink<short>)
  14174. strtk_register_base64_type_tag(base64_to_number_sink<int>)
  14175. strtk_register_base64_type_tag(base64_to_number_sink<long>)
  14176. strtk_register_base64_type_tag(base64_to_number_sink<unsigned short>)
  14177. strtk_register_base64_type_tag(base64_to_number_sink<unsigned int>)
  14178. strtk_register_base64_type_tag(base64_to_number_sink<unsigned long>)
  14179. strtk_register_base64_type_tag(base64_to_number_sink<unsigned long long int>)
  14180. strtk_register_stdstring_range_type_tag(std::string::iterator)
  14181. strtk_register_stdstring_range_type_tag(std::string::const_iterator)
  14182. strtk_register_stdstring_range_type_tag(char*)
  14183. strtk_register_stdstring_range_type_tag(signed char*)
  14184. strtk_register_stdstring_range_type_tag(unsigned char*)
  14185. strtk_register_stdstring_range_type_tag(const char*)
  14186. strtk_register_stdstring_range_type_tag(const unsigned char*)
  14187. strtk_register_supported_iterator_type(char*)
  14188. strtk_register_supported_iterator_type(signed char*)
  14189. strtk_register_supported_iterator_type(unsigned char*)
  14190. strtk_register_supported_iterator_type(const char*)
  14191. strtk_register_supported_iterator_type(const signed char*)
  14192. strtk_register_supported_iterator_type(const unsigned char*)
  14193. strtk_register_supported_iterator_type(std::string::iterator)
  14194. strtk_register_supported_iterator_type(std::string::const_iterator)
  14195. strtk_register_sequence_iterator_type(std::vector)
  14196. strtk_register_sequence_iterator_type(std::deque)
  14197. strtk_register_sink_type_tag(float)
  14198. strtk_register_sink_type_tag(double)
  14199. strtk_register_sink_type_tag(long double)
  14200. strtk_register_sink_type_tag(signed char)
  14201. strtk_register_sink_type_tag(char)
  14202. strtk_register_sink_type_tag(short)
  14203. strtk_register_sink_type_tag(int)
  14204. strtk_register_sink_type_tag(long)
  14205. strtk_register_sink_type_tag(unsigned char)
  14206. strtk_register_sink_type_tag(unsigned short)
  14207. strtk_register_sink_type_tag(unsigned int)
  14208. strtk_register_sink_type_tag(unsigned long)
  14209. strtk_register_sink_type_tag(unsigned long long int)
  14210. strtk_register_sink_type_tag(std::string)
  14211. strtk_register_stl_container_to_string_conv_type_tag(float)
  14212. strtk_register_stl_container_to_string_conv_type_tag(double)
  14213. strtk_register_stl_container_to_string_conv_type_tag(long double)
  14214. strtk_register_stl_container_to_string_conv_type_tag(signed char)
  14215. strtk_register_stl_container_to_string_conv_type_tag(char)
  14216. strtk_register_stl_container_to_string_conv_type_tag(short)
  14217. strtk_register_stl_container_to_string_conv_type_tag(int)
  14218. strtk_register_stl_container_to_string_conv_type_tag(long)
  14219. strtk_register_stl_container_to_string_conv_type_tag(unsigned char)
  14220. strtk_register_stl_container_to_string_conv_type_tag(unsigned short)
  14221. strtk_register_stl_container_to_string_conv_type_tag(unsigned int)
  14222. strtk_register_stl_container_to_string_conv_type_tag(unsigned long)
  14223. strtk_register_stl_container_to_string_conv_type_tag(unsigned long long int)
  14224. strtk_register_stl_container_to_string_conv_type_tag(std::string)
  14225. strtk_register_inrange_type_tag(float)
  14226. strtk_register_inrange_type_tag(double)
  14227. strtk_register_inrange_type_tag(long double)
  14228. strtk_register_inrange_type_tag(signed char)
  14229. strtk_register_inrange_type_tag(char)
  14230. strtk_register_inrange_type_tag(short)
  14231. strtk_register_inrange_type_tag(int)
  14232. strtk_register_inrange_type_tag(long)
  14233. strtk_register_inrange_type_tag(unsigned char)
  14234. strtk_register_inrange_type_tag(unsigned short)
  14235. strtk_register_inrange_type_tag(unsigned int)
  14236. strtk_register_inrange_type_tag(unsigned long)
  14237. strtk_register_inrange_type_tag(unsigned long long int)
  14238. strtk_register_inrange_type_tag(std::string)
  14239. strtk_register_trim_type_tag(float)
  14240. strtk_register_trim_type_tag(double)
  14241. strtk_register_trim_type_tag(long double)
  14242. strtk_register_trim_type_tag(signed char)
  14243. strtk_register_trim_type_tag(char)
  14244. strtk_register_trim_type_tag(short)
  14245. strtk_register_trim_type_tag(int)
  14246. strtk_register_trim_type_tag(long)
  14247. strtk_register_trim_type_tag(unsigned char)
  14248. strtk_register_trim_type_tag(unsigned short)
  14249. strtk_register_trim_type_tag(unsigned int)
  14250. strtk_register_trim_type_tag(unsigned long)
  14251. strtk_register_trim_type_tag(unsigned long long int)
  14252. strtk_register_trim_type_tag(std::string)
  14253. #define strtk_register_userdef_type_sink(T)\
  14254. namespace strtk { namespace details { strtk_register_sink_type_tag(T) }}
  14255. #undef strtk_register_unsigned_type_tag
  14256. #undef strtk_register_signed_type_tag
  14257. #undef strtk_register_real_type_tag
  14258. #undef strtk_register_byte_type_tag
  14259. #undef strtk_register_hex_number_type_tag
  14260. #undef strtk_register_base64_type_tag
  14261. #undef strtk_register_supported_iterator_type
  14262. #undef strtk_register_stdstring_range_type_tag
  14263. #undef strtk_register_sequence_iterator_type
  14264. #undef strtk_register_stl_container_to_string_conv_type_tag
  14265. #undef strtk_register_inrange_type_tag
  14266. #undef strtk_register_trim_type_tag
  14267. template <typename T>
  14268. struct precision
  14269. { static void set(std::iostream&) {} };
  14270. #define strtk_register_iostream_precision(T)\
  14271. template<> struct precision<T> { static void set(std::iostream& s, const std::streamsize& p = 10) { s.precision(p);} };
  14272. strtk_register_iostream_precision(float)
  14273. strtk_register_iostream_precision(double)
  14274. strtk_register_iostream_precision(long double)
  14275. #undef strtk_register_iostream_precision
  14276. template <typename Iterator, typename T, typename Tag>
  14277. inline bool string_to_type_converter_impl(Iterator& begin, const Iterator end, T& t, not_supported_type_tag)
  14278. {
  14279. #ifdef strtk_enable_lexical_cast
  14280. try
  14281. {
  14282. t = boost::lexical_cast<T>(std::string(begin,end));
  14283. }
  14284. catch (const boost::bad_lexical_cast&)
  14285. {
  14286. return false;
  14287. }
  14288. begin = end;
  14289. return true;
  14290. #else
  14291. try
  14292. {
  14293. std::stringstream ss(std::string(begin,end));
  14294. ss >> t;
  14295. }
  14296. catch (const std::exception&)
  14297. {
  14298. return false;
  14299. }
  14300. begin = end;
  14301. return true;
  14302. #endif
  14303. }
  14304. template <typename Iterator>
  14305. inline bool string_to_type_converter_impl(Iterator& begin, const Iterator end, strtk::util::value& v, value_type_tag)
  14306. {
  14307. return v(begin,end);
  14308. }
  14309. template <typename Iterator>
  14310. inline bool string_to_type_converter_impl(Iterator& begin, const Iterator end, std::string& t, stdstring_type_tag)
  14311. {
  14312. t.assign(begin,end);
  14313. begin = end;
  14314. return true;
  14315. }
  14316. template <typename Iterator, typename Expect>
  14317. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, Expect& t, expect_type_tag)
  14318. {
  14319. if (!t(itr,end))
  14320. return false;
  14321. itr = end;
  14322. return true;
  14323. }
  14324. template <typename Iterator, typename Like>
  14325. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, Like& t, like_type_tag)
  14326. {
  14327. if (!t(itr,end))
  14328. return false;
  14329. itr = end;
  14330. return true;
  14331. }
  14332. template <typename Iterator, typename InRange>
  14333. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, InRange& t, inrange_type_tag)
  14334. {
  14335. if (!t(itr,end))
  14336. return false;
  14337. itr = end;
  14338. return true;
  14339. }
  14340. template <typename Iterator, typename TrimToken>
  14341. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, TrimToken& t, trim_type_tag)
  14342. {
  14343. if (!t(itr,end))
  14344. return false;
  14345. itr = end;
  14346. return true;
  14347. }
  14348. template <typename Iterator, typename CaseToken>
  14349. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, CaseToken& t, lcase_type_tag)
  14350. {
  14351. if (!t(itr,end))
  14352. return false;
  14353. itr = end;
  14354. return true;
  14355. }
  14356. template <typename Iterator, typename CaseToken>
  14357. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, CaseToken& t, ucase_type_tag)
  14358. {
  14359. if (!t(itr,end))
  14360. return false;
  14361. itr = end;
  14362. return true;
  14363. }
  14364. template <typename Iterator, typename Array>
  14365. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, Array& t, fillchararray_type_tag)
  14366. {
  14367. if (!t(itr,end))
  14368. return false;
  14369. itr = end;
  14370. return true;
  14371. }
  14372. template <typename Iterator, typename T>
  14373. inline bool string_to_type_converter_impl(Iterator& itr_external, const Iterator end, T& result, unsigned_type_tag)
  14374. {
  14375. if (end == itr_external) return false;
  14376. Iterator itr = itr_external;
  14377. if ('+' == (*itr))
  14378. ++itr;
  14379. if (end == itr)
  14380. return false;
  14381. while ((end != itr) && ('0' == (*itr))) ++itr;
  14382. const std::size_t length = std::distance(itr,end);
  14383. if (length > numeric<T>::length)
  14384. return false;
  14385. static const std::size_t bound_length = numeric<T>::bound_length;
  14386. T t = 0;
  14387. if (0 != length)
  14388. {
  14389. std::size_t interim_length = std::min<std::size_t>(bound_length,length);
  14390. const Iterator interim_end = itr + interim_length;
  14391. unsigned int digit[8];
  14392. T t0 = 0;
  14393. T t1 = 0;
  14394. T t2 = 0;
  14395. T t3 = 0;
  14396. //Needed for incompetent and broken msvc compiler versions
  14397. #ifdef _MSC_VER
  14398. #pragma warning(push)
  14399. #pragma warning(disable: 4127)
  14400. #endif
  14401. while (interim_length > 7)
  14402. {
  14403. if (((digit[0] = (itr[0] - '0')) > 9) ||
  14404. ((digit[1] = (itr[1] - '0')) > 9) ||
  14405. ((digit[2] = (itr[2] - '0')) > 9) ||
  14406. ((digit[3] = (itr[3] - '0')) > 9) ||
  14407. ((digit[4] = (itr[4] - '0')) > 9) ||
  14408. ((digit[5] = (itr[5] - '0')) > 9) ||
  14409. ((digit[6] = (itr[6] - '0')) > 9) ||
  14410. ((digit[7] = (itr[7] - '0')) > 9))
  14411. return false;
  14412. else
  14413. {
  14414. t0 = static_cast<T>(digit[0] * 10000000 + digit[1] * 1000000);
  14415. t1 = static_cast<T>(digit[2] * 100000 + digit[3] * 10000);
  14416. t2 = static_cast<T>(digit[4] * 1000 + digit[5] * 100);
  14417. t3 = static_cast<T>(digit[6] * 10 + digit[7] );
  14418. t = t0 + t1 + t2 + t3 + static_cast<T>(t * 100000000);
  14419. itr += 8;
  14420. interim_length -= 8;
  14421. }
  14422. }
  14423. while (interim_length > 3)
  14424. {
  14425. if (((digit[0] = (itr[0] - '0')) > 9) ||
  14426. ((digit[1] = (itr[1] - '0')) > 9) ||
  14427. ((digit[2] = (itr[2] - '0')) > 9) ||
  14428. ((digit[3] = (itr[3] - '0')) > 9))
  14429. return false;
  14430. else
  14431. {
  14432. t1 = static_cast<T>(digit[0] * 1000 + digit[1] * 100);
  14433. t2 = static_cast<T>(digit[2] * 10 + digit[3] );
  14434. t3 = static_cast<T>(t * 10000 );
  14435. t = t1 + t2 + t3;
  14436. itr += 4;
  14437. interim_length -= 4;
  14438. }
  14439. }
  14440. while (interim_length > 1)
  14441. {
  14442. if (((digit[0] = (itr[0] - '0')) > 9) ||
  14443. ((digit[1] = (itr[1] - '0')) > 9))
  14444. return false;
  14445. else
  14446. {
  14447. t1 = static_cast<T>(digit[0] * 10 + digit[1]);
  14448. t2 = static_cast<T>(t * 100 );
  14449. t = t1 + t2;
  14450. itr += 2;
  14451. interim_length -= 2;
  14452. }
  14453. }
  14454. //Needed for incompetent and broken msvc compiler versions.
  14455. #ifdef _MSC_VER
  14456. #pragma warning(pop)
  14457. #endif
  14458. if (interim_length)
  14459. {
  14460. if ((digit[0] = (itr[0] - '0')) < 10)
  14461. {
  14462. t = static_cast<T>(digit[0] + t * 10);
  14463. ++itr;
  14464. }
  14465. else
  14466. return false;
  14467. }
  14468. if (interim_end != end)
  14469. {
  14470. if (1 == std::distance(interim_end,end))
  14471. {
  14472. typedef unsigned long long int num_type;
  14473. static const num_type max = static_cast<num_type>(std::numeric_limits<T>::max());
  14474. static const num_type penultimate_bound = static_cast<num_type>(max / 10);
  14475. static const num_type final_digit = static_cast<num_type>(max % 10);
  14476. digit[0] = static_cast<unsigned int>(*itr - '0');
  14477. if (digit[0] <= 9)
  14478. {
  14479. if (t > penultimate_bound)
  14480. return false;
  14481. else if ((penultimate_bound == t) && (final_digit < digit[0]))
  14482. return false;
  14483. t = static_cast<T>(digit[0] + t * 10);
  14484. }
  14485. else
  14486. return false;
  14487. }
  14488. else
  14489. return false;
  14490. }
  14491. }
  14492. result = static_cast<T>(t);
  14493. return true;
  14494. }
  14495. template <typename Iterator, typename T>
  14496. inline bool string_to_type_converter_impl(Iterator& itr_external, const Iterator end, T& result, signed_type_tag)
  14497. {
  14498. if (end == itr_external) return false;
  14499. Iterator itr = itr_external;
  14500. bool negative = false;
  14501. if ('+' == (*itr))
  14502. ++itr;
  14503. else if ('-' == (*itr))
  14504. {
  14505. ++itr;
  14506. negative = true;
  14507. }
  14508. if (end == itr) return false;
  14509. while ((end != itr) && ('0' == (*itr))) ++itr;
  14510. const std::size_t length = std::distance(itr,end);
  14511. if (length > numeric<T>::length)
  14512. return false;
  14513. static const std::size_t bound_length = numeric<T>::bound_length;
  14514. T t = 0;
  14515. if (0 != length)
  14516. {
  14517. std::size_t interim_length = std::min<std::size_t>(bound_length,length);
  14518. const Iterator interim_end = itr + interim_length;
  14519. unsigned int digit[8];
  14520. T t0 = 0;
  14521. T t1 = 0;
  14522. T t2 = 0;
  14523. T t3 = 0;
  14524. //Needed for incompetent and broken msvc compiler versions
  14525. #ifdef _MSC_VER
  14526. #pragma warning(push)
  14527. #pragma warning(disable: 4127)
  14528. #endif
  14529. while (interim_length > 7)
  14530. {
  14531. if (((digit[0] = (itr[0] - '0')) > 9) ||
  14532. ((digit[1] = (itr[1] - '0')) > 9) ||
  14533. ((digit[2] = (itr[2] - '0')) > 9) ||
  14534. ((digit[3] = (itr[3] - '0')) > 9) ||
  14535. ((digit[4] = (itr[4] - '0')) > 9) ||
  14536. ((digit[5] = (itr[5] - '0')) > 9) ||
  14537. ((digit[6] = (itr[6] - '0')) > 9) ||
  14538. ((digit[7] = (itr[7] - '0')) > 9) )
  14539. return false;
  14540. else
  14541. {
  14542. t0 = static_cast<T>(digit[0] * 10000000 + digit[1] * 1000000);
  14543. t1 = static_cast<T>(digit[2] * 100000 + digit[3] * 10000);
  14544. t2 = static_cast<T>(digit[4] * 1000 + digit[5] * 100);
  14545. t3 = static_cast<T>(digit[6] * 10 + digit[7] );
  14546. t = t0 + t1 + t2 + t3 + static_cast<T>(t * 100000000);
  14547. itr += 8;
  14548. interim_length -= 8;
  14549. }
  14550. }
  14551. while (interim_length > 3)
  14552. {
  14553. if (((digit[0] = (itr[0] - '0')) > 9) ||
  14554. ((digit[1] = (itr[1] - '0')) > 9) ||
  14555. ((digit[2] = (itr[2] - '0')) > 9) ||
  14556. ((digit[3] = (itr[3] - '0')) > 9) )
  14557. return false;
  14558. else
  14559. {
  14560. t0 = static_cast<T>(digit[0] * 1000 + digit[1] * 100);
  14561. t1 = static_cast<T>(digit[2] * 10 + digit[3] );
  14562. t = t0 + t1 + static_cast<T>(t * 10000);
  14563. itr += 4;
  14564. interim_length -= 4;
  14565. }
  14566. }
  14567. while (interim_length > 2)
  14568. {
  14569. if (((digit[0] = (itr[0] - '0')) > 9) ||
  14570. ((digit[1] = (itr[1] - '0')) > 9) ||
  14571. ((digit[2] = (itr[2] - '0')) > 9))
  14572. return false;
  14573. else
  14574. {
  14575. t0 = static_cast<T>(digit[0] * 100 + digit[1] * 10);
  14576. t1 = static_cast<T>(t * 1000 + digit[2] );
  14577. t = t0 + t1;
  14578. itr += 3;
  14579. interim_length -= 3;
  14580. }
  14581. }
  14582. while (interim_length > 1)
  14583. {
  14584. if (((digit[0] = (itr[0] - '0')) > 9) ||
  14585. ((digit[1] = (itr[1] - '0')) > 9))
  14586. return false;
  14587. else
  14588. {
  14589. t0 = static_cast<T>(digit[0] * 10 + digit[1]);
  14590. t = t0 + static_cast<T>(t * 100);
  14591. itr += 2;
  14592. interim_length -= 2;
  14593. }
  14594. }
  14595. //Needed for incompetent and broken msvc compiler versions.
  14596. #ifdef _MSC_VER
  14597. #pragma warning(pop)
  14598. #endif
  14599. if (interim_length)
  14600. {
  14601. if ((digit[0] = (itr[0] - '0')) < 10)
  14602. {
  14603. t = static_cast<T>(digit[0] + t * 10);
  14604. ++itr;
  14605. }
  14606. else
  14607. return false;
  14608. }
  14609. if (interim_end != end)
  14610. {
  14611. if (1 == std::distance(interim_end,end))
  14612. {
  14613. typedef unsigned long long int num_type;
  14614. static const num_type max = static_cast<num_type>(std::numeric_limits<T>::max());
  14615. static const num_type min = static_cast<num_type>(static_cast<long long>(-1) * std::numeric_limits<T>::min());
  14616. static const num_type positive_penultimate_bound = static_cast<num_type>(max / 10);
  14617. static const num_type negative_penultimate_bound = static_cast<num_type>(min / 10);
  14618. static const num_type positive_final_digit = static_cast<num_type>(max % 10);
  14619. static const num_type negative_final_digit = static_cast<num_type>(min % 10);
  14620. digit[0] = static_cast<unsigned int>(*itr - '0');
  14621. if (digit[0] < 10)
  14622. {
  14623. if (negative)
  14624. {
  14625. if (static_cast<num_type>(t) > negative_penultimate_bound)
  14626. return false;
  14627. else if (
  14628. (negative_penultimate_bound == static_cast<num_type>(t)) &&
  14629. (negative_final_digit < digit[0])
  14630. )
  14631. return false;
  14632. }
  14633. else
  14634. {
  14635. if (static_cast<num_type>(t) > positive_penultimate_bound)
  14636. return false;
  14637. else if (
  14638. (positive_penultimate_bound == static_cast<num_type>(t)) &&
  14639. (positive_final_digit < digit[0])
  14640. )
  14641. return false;
  14642. }
  14643. t = static_cast<T>(digit[0] + t * 10);
  14644. }
  14645. else
  14646. return false;
  14647. }
  14648. else
  14649. return false;
  14650. }
  14651. }
  14652. itr_external = itr;
  14653. result = static_cast<T>((negative) ? -t : t);
  14654. return true;
  14655. }
  14656. template <typename Iterator, typename T>
  14657. inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, T& result, signed_type_tag)
  14658. {
  14659. if (end == itr) return false;
  14660. T t = 0;
  14661. bool negative = false;
  14662. if ('+' == (*itr))
  14663. ++itr;
  14664. else if ('-' == (*itr))
  14665. {
  14666. ++itr;
  14667. negative = true;
  14668. }
  14669. if (end == itr)
  14670. return false;
  14671. unsigned int digit_count = 0;
  14672. while ((end != itr) && ('0' == (*itr))) ++itr;
  14673. bool return_result = true;
  14674. while (end != itr)
  14675. {
  14676. const unsigned char digit = (*itr - '0');
  14677. if (digit > 9)
  14678. {
  14679. return_result = false;
  14680. break;
  14681. }
  14682. if ((++digit_count) <= numeric<T>::bound_length)
  14683. {
  14684. t *= 10;
  14685. t += digit;
  14686. }
  14687. else
  14688. {
  14689. typedef unsigned long long int base_type;
  14690. static const base_type max_limit = +std::numeric_limits<T>::max();
  14691. static const base_type min_limit = -std::numeric_limits<T>::min();
  14692. base_type tmp = static_cast<base_type>(t) * 10 + digit;
  14693. if (negative && static_cast<base_type>(tmp) > min_limit)
  14694. return_result = false;
  14695. else if (static_cast<base_type>(tmp) > max_limit)
  14696. return_result = false;
  14697. t = static_cast<T>(tmp);
  14698. }
  14699. ++itr;
  14700. }
  14701. result = static_cast<T>((negative) ? -t : t);
  14702. return return_result;
  14703. }
  14704. template <typename Iterator, typename T>
  14705. inline bool parse_nan(Iterator& itr, const Iterator end, T& t)
  14706. {
  14707. typedef typename std::iterator_traits<Iterator>::value_type type;
  14708. static const std::size_t nan_length = 3;
  14709. if (std::distance(itr,end) != static_cast<int>(nan_length))
  14710. return false;
  14711. if (static_cast<type>('n') == (*itr))
  14712. {
  14713. if ((static_cast<type>('a') != *(itr + 1)) || (static_cast<type>('n') != *(itr + 2)))
  14714. {
  14715. return false;
  14716. }
  14717. }
  14718. else if ((static_cast<type>('A') != *(itr + 1)) || (static_cast<type>('N') != *(itr + 2)))
  14719. {
  14720. return false;
  14721. }
  14722. t = std::numeric_limits<T>::quiet_NaN();
  14723. return true;
  14724. }
  14725. template <typename Iterator, typename T>
  14726. inline bool parse_inf(Iterator& itr, const Iterator end, T& t, bool negative)
  14727. {
  14728. static const char inf_uc[] = "INFINITY";
  14729. static const char inf_lc[] = "infinity";
  14730. static const std::size_t inf_length = 8;
  14731. const std::size_t length = std::distance(itr,end);
  14732. if ((3 != length) && (inf_length != length))
  14733. return false;
  14734. const char* inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc;
  14735. while (end != itr)
  14736. {
  14737. if (*inf_itr == static_cast<char>(*itr))
  14738. {
  14739. ++itr;
  14740. ++inf_itr;
  14741. continue;
  14742. }
  14743. else
  14744. return false;
  14745. }
  14746. if (negative)
  14747. t = -std::numeric_limits<T>::infinity();
  14748. else
  14749. t = std::numeric_limits<T>::infinity();
  14750. return true;
  14751. }
  14752. template <typename Iterator, typename T>
  14753. inline bool string_to_type_converter_impl(Iterator& itr_external, const Iterator end, T& t, real_type_tag)
  14754. {
  14755. if (end == itr_external) return false;
  14756. Iterator itr = itr_external;
  14757. double d = 0.0;
  14758. bool negative = false;
  14759. if ('+' == (*itr))
  14760. ++itr;
  14761. else if ('-' == (*itr))
  14762. {
  14763. ++itr;
  14764. negative = true;
  14765. }
  14766. if (end == itr)
  14767. return false;
  14768. if (('I' <= (*itr)) && ((*itr) <= 'n'))
  14769. {
  14770. if (('i' == (*itr)) || ('I' == (*itr)))
  14771. {
  14772. return parse_inf(itr,end,t,negative);
  14773. }
  14774. else if (('n' == (*itr)) || ('N' == (*itr)))
  14775. {
  14776. return parse_nan(itr,end,t);
  14777. }
  14778. else
  14779. return false;
  14780. }
  14781. bool instate = false;
  14782. int pre_decimal = 0;
  14783. if ('.' != (*itr))
  14784. {
  14785. const Iterator curr = itr;
  14786. while ((end != itr) && ('0' == (*itr))) ++itr;
  14787. const Iterator post_zero_cull_itr = itr;
  14788. unsigned char digit = 0;
  14789. #define parse_digit_1 \
  14790. if ((digit = static_cast<unsigned char>((*itr) - '0')) < 10) { d *= 10.0; d += digit; } else break; if (end == ++itr) break; \
  14791. #define parse_digit_2 \
  14792. if ((digit = static_cast<unsigned char>((*itr) - '0')) < 10) { d *= 10.0; d += digit; } else break; ++itr;\
  14793. while (end != itr)
  14794. {
  14795. parse_digit_1
  14796. parse_digit_1
  14797. parse_digit_1
  14798. parse_digit_1
  14799. parse_digit_1
  14800. parse_digit_1
  14801. parse_digit_1
  14802. parse_digit_2
  14803. }
  14804. #undef parse_digit_1
  14805. #undef parse_digit_2
  14806. if (curr != itr) instate = true;
  14807. pre_decimal = static_cast<int>(std::distance(post_zero_cull_itr,itr));
  14808. }
  14809. int exponent = 0;
  14810. if (end != itr)
  14811. {
  14812. if ('.' == (*itr))
  14813. {
  14814. ++itr;
  14815. const Iterator curr = itr;
  14816. unsigned char digit = 0;
  14817. #define parse_digit_1 \
  14818. if ((digit = static_cast<unsigned char>((*itr) - '0')) < 10) { d *= 10.0; d += digit; } else break; if (end == ++itr) break; \
  14819. #define parse_digit_2 \
  14820. if ((digit = static_cast<unsigned char>((*itr) - '0')) < 10) { d *= 10.0; d += digit; } else break; ++itr;\
  14821. while (end != itr)
  14822. {
  14823. parse_digit_1
  14824. parse_digit_1
  14825. parse_digit_1
  14826. parse_digit_1
  14827. parse_digit_1
  14828. parse_digit_1
  14829. parse_digit_1
  14830. parse_digit_2
  14831. }
  14832. #undef parse_digit_1
  14833. #undef parse_digit_2
  14834. if (curr != itr) instate = true;
  14835. exponent -= static_cast<int>(std::distance(curr,itr));
  14836. }
  14837. if (end != itr)
  14838. {
  14839. typename std::iterator_traits<Iterator>::value_type c = (*itr);
  14840. if (('e' == c) || ('E' == c))
  14841. {
  14842. ++itr;
  14843. int exp = 0;
  14844. if (!details::string_to_type_converter_impl_ref(itr,end,exp,details::signed_type_tag()))
  14845. {
  14846. if (end == itr)
  14847. return false;
  14848. else
  14849. c = (*itr);
  14850. }
  14851. if ((exp < numeric<T>::min_exp) || (numeric<T>::max_exp < exp))
  14852. return false;
  14853. exponent += exp;
  14854. }
  14855. if (('f' == c) || ('F' == c) || ('l' == c) || ('L' == c))
  14856. ++itr;
  14857. else if ('#' == c)
  14858. {
  14859. ++itr;
  14860. if (end == itr)
  14861. return false;
  14862. if ((10.0 != d) || (exponent != -1))
  14863. return false;
  14864. if (('I' <= (*itr)) && ((*itr) <= 'n'))
  14865. {
  14866. if (('i' == (*itr)) || ('I' == (*itr)))
  14867. {
  14868. return parse_inf(itr,end,t,negative);
  14869. }
  14870. else if (('n' == (*itr)) || ('N' == (*itr)))
  14871. {
  14872. return parse_nan(itr,end,t);
  14873. }
  14874. else
  14875. return false;
  14876. }
  14877. return false;
  14878. }
  14879. }
  14880. }
  14881. if ((end != itr) || (!instate))
  14882. return false;
  14883. if (0 != exponent)
  14884. {
  14885. if (
  14886. (std::numeric_limits<T>::max_exponent10 < (exponent + pre_decimal)) ||
  14887. (std::numeric_limits<T>::min_exponent10 > (exponent + pre_decimal))
  14888. )
  14889. {
  14890. return false;
  14891. }
  14892. const int e = std::abs(exponent);
  14893. static const double fract10[] =
  14894. {
  14895. 0.0,
  14896. 1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004, 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008, 1.0E+009, 1.0E+010,
  14897. 1.0E+011, 1.0E+012, 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016, 1.0E+017, 1.0E+018, 1.0E+019, 1.0E+020,
  14898. 1.0E+021, 1.0E+022, 1.0E+023, 1.0E+024, 1.0E+025, 1.0E+026, 1.0E+027, 1.0E+028, 1.0E+029, 1.0E+030,
  14899. 1.0E+031, 1.0E+032, 1.0E+033, 1.0E+034, 1.0E+035, 1.0E+036, 1.0E+037, 1.0E+038, 1.0E+039, 1.0E+040,
  14900. 1.0E+041, 1.0E+042, 1.0E+043, 1.0E+044, 1.0E+045, 1.0E+046, 1.0E+047, 1.0E+048, 1.0E+049, 1.0E+050,
  14901. 1.0E+051, 1.0E+052, 1.0E+053, 1.0E+054, 1.0E+055, 1.0E+056, 1.0E+057, 1.0E+058, 1.0E+059, 1.0E+060,
  14902. 1.0E+061, 1.0E+062, 1.0E+063, 1.0E+064, 1.0E+065, 1.0E+066, 1.0E+067, 1.0E+068, 1.0E+069, 1.0E+070,
  14903. 1.0E+071, 1.0E+072, 1.0E+073, 1.0E+074, 1.0E+075, 1.0E+076, 1.0E+077, 1.0E+078, 1.0E+079, 1.0E+080,
  14904. 1.0E+081, 1.0E+082, 1.0E+083, 1.0E+084, 1.0E+085, 1.0E+086, 1.0E+087, 1.0E+088, 1.0E+089, 1.0E+090,
  14905. 1.0E+091, 1.0E+092, 1.0E+093, 1.0E+094, 1.0E+095, 1.0E+096, 1.0E+097, 1.0E+098, 1.0E+099, 1.0E+100,
  14906. 1.0E+101, 1.0E+102, 1.0E+103, 1.0E+104, 1.0E+105, 1.0E+106, 1.0E+107, 1.0E+108, 1.0E+109, 1.0E+110,
  14907. 1.0E+111, 1.0E+112, 1.0E+113, 1.0E+114, 1.0E+115, 1.0E+116, 1.0E+117, 1.0E+118, 1.0E+119, 1.0E+120,
  14908. 1.0E+121, 1.0E+122, 1.0E+123, 1.0E+124, 1.0E+125, 1.0E+126, 1.0E+127, 1.0E+128, 1.0E+129, 1.0E+130,
  14909. 1.0E+131, 1.0E+132, 1.0E+133, 1.0E+134, 1.0E+135, 1.0E+136, 1.0E+137, 1.0E+138, 1.0E+139, 1.0E+140,
  14910. 1.0E+141, 1.0E+142, 1.0E+143, 1.0E+144, 1.0E+145, 1.0E+146, 1.0E+147, 1.0E+148, 1.0E+149, 1.0E+150,
  14911. 1.0E+151, 1.0E+152, 1.0E+153, 1.0E+154, 1.0E+155, 1.0E+156, 1.0E+157, 1.0E+158, 1.0E+159, 1.0E+160,
  14912. 1.0E+161, 1.0E+162, 1.0E+163, 1.0E+164, 1.0E+165, 1.0E+166, 1.0E+167, 1.0E+168, 1.0E+169, 1.0E+170,
  14913. 1.0E+171, 1.0E+172, 1.0E+173, 1.0E+174, 1.0E+175, 1.0E+176, 1.0E+177, 1.0E+178, 1.0E+179, 1.0E+180,
  14914. 1.0E+181, 1.0E+182, 1.0E+183, 1.0E+184, 1.0E+185, 1.0E+186, 1.0E+187, 1.0E+188, 1.0E+189, 1.0E+190,
  14915. 1.0E+191, 1.0E+192, 1.0E+193, 1.0E+194, 1.0E+195, 1.0E+196, 1.0E+197, 1.0E+198, 1.0E+199, 1.0E+200,
  14916. 1.0E+221, 1.0E+222, 1.0E+223, 1.0E+224, 1.0E+225, 1.0E+226, 1.0E+227, 1.0E+228, 1.0E+229, 1.0E+230,
  14917. 1.0E+231, 1.0E+232, 1.0E+233, 1.0E+234, 1.0E+235, 1.0E+236, 1.0E+237, 1.0E+238, 1.0E+239, 1.0E+240,
  14918. 1.0E+241, 1.0E+242, 1.0E+243, 1.0E+244, 1.0E+245, 1.0E+246, 1.0E+247, 1.0E+248, 1.0E+249, 1.0E+250,
  14919. 1.0E+251, 1.0E+252, 1.0E+253, 1.0E+254, 1.0E+255, 1.0E+256, 1.0E+257, 1.0E+258, 1.0E+259, 1.0E+260,
  14920. 1.0E+261, 1.0E+262, 1.0E+263, 1.0E+264, 1.0E+265, 1.0E+266, 1.0E+267, 1.0E+268, 1.0E+269, 1.0E+270,
  14921. 1.0E+271, 1.0E+272, 1.0E+273, 1.0E+274, 1.0E+275, 1.0E+276, 1.0E+277, 1.0E+278, 1.0E+279, 1.0E+280,
  14922. 1.0E+281, 1.0E+282, 1.0E+283, 1.0E+284, 1.0E+285, 1.0E+286, 1.0E+287, 1.0E+288, 1.0E+289, 1.0E+290,
  14923. 1.0E+291, 1.0E+292, 1.0E+293, 1.0E+294, 1.0E+295, 1.0E+296, 1.0E+297, 1.0E+298, 1.0E+299, 1.0E+300,
  14924. 1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308
  14925. };
  14926. static const std::size_t fract10_size = sizeof(fract10) / sizeof(double);
  14927. if (d != 0.0)
  14928. {
  14929. if (static_cast<std::size_t>(e) < fract10_size)
  14930. {
  14931. if (exponent > 0)
  14932. d *= fract10[e];
  14933. else
  14934. d /= fract10[e];
  14935. }
  14936. else
  14937. d *= std::pow(10.0, 1.0 * exponent);
  14938. }
  14939. }
  14940. t = static_cast<T>((negative) ? -d : d);
  14941. return true;
  14942. }
  14943. template <typename Iterator, typename T>
  14944. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, T& t, byte_type_tag)
  14945. {
  14946. if (1 != std::distance(itr,end))
  14947. return false;
  14948. t = static_cast<T>(*itr);
  14949. itr = end;
  14950. return true;
  14951. }
  14952. template <typename Iterator>
  14953. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, bool& t, bool_type_tag)
  14954. {
  14955. if (1 != std::distance(itr,end))
  14956. return false;
  14957. t = (('0' == (*itr)) ? false : true);
  14958. itr = end;
  14959. return true;
  14960. }
  14961. template <typename Iterator, typename IgnoreTokenType>
  14962. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, IgnoreTokenType&, ignore_token_type_tag)
  14963. {
  14964. itr = end;
  14965. return true;
  14966. }
  14967. template <typename Iterator, typename HexSinkType>
  14968. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, HexSinkType& t, hex_number_type_tag)
  14969. {
  14970. t = std::pair<Iterator,Iterator>(itr,end);
  14971. if (!t.valid())
  14972. return false;
  14973. itr = end;
  14974. return true;
  14975. }
  14976. template <typename Iterator, typename HexSinkType>
  14977. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, HexSinkType& t, hex_string_type_tag)
  14978. {
  14979. t = std::pair<Iterator,Iterator>(itr,end);
  14980. if (!t.valid())
  14981. return false;
  14982. itr = end;
  14983. return true;
  14984. }
  14985. template <typename Iterator, typename Base64SinkType>
  14986. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, Base64SinkType& t, base64_type_tag)
  14987. {
  14988. t = std::pair<Iterator,Iterator>(itr,end);
  14989. if (!t.valid())
  14990. return false;
  14991. itr = end;
  14992. return true;
  14993. }
  14994. template <typename Iterator, typename SinkType>
  14995. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, SinkType& t, sink_type_tag)
  14996. {
  14997. if (!t.parse(itr,end))
  14998. return false;
  14999. itr = end;
  15000. return true;
  15001. }
  15002. template <typename T>
  15003. inline bool type_to_string_converter_impl(const T& t, std::string& s, not_supported_type_tag)
  15004. {
  15005. #ifdef strtk_enable_lexical_cast
  15006. try
  15007. {
  15008. s = boost::lexical_cast<std::string>(t);
  15009. }
  15010. catch (const boost::bad_lexical_cast&)
  15011. {
  15012. return false;
  15013. }
  15014. #else
  15015. try
  15016. {
  15017. std::stringstream ss;
  15018. precision<T>::set(ss);
  15019. ss << t;
  15020. s = ss.str();
  15021. }
  15022. catch (const std::exception&)
  15023. {
  15024. return false;
  15025. }
  15026. #endif
  15027. return true;
  15028. }
  15029. template <typename T>
  15030. inline bool type_to_string_converter_impl(T value, std::string& result, unsigned_type_tag)
  15031. {
  15032. static const std::size_t radix = 10;
  15033. static const std::size_t radix_sqr = radix * radix;
  15034. static const std::size_t radix_cube = radix * radix * radix;
  15035. unsigned char buffer[numeric<T>::size];
  15036. unsigned char* itr = buffer + (numeric<T>::size - 1);
  15037. T remainder = 0;
  15038. if (0 != value)
  15039. {
  15040. std::size_t index = 0;
  15041. T temp_v = 0;
  15042. while (value >= static_cast<T>(radix_sqr))
  15043. {
  15044. temp_v = value / radix_cube;
  15045. remainder = value - (temp_v * radix_cube);
  15046. value = temp_v;
  15047. index = static_cast<std::size_t>(remainder * 3);
  15048. *(itr ) = details::rev_3digit_lut[index ];
  15049. *(itr - 1) = details::rev_3digit_lut[index + 1];
  15050. *(itr - 2) = details::rev_3digit_lut[index + 2];
  15051. itr -= 3;
  15052. }
  15053. while (value >= static_cast<T>(radix))
  15054. {
  15055. temp_v = value / radix_sqr;
  15056. remainder = value - (temp_v * radix_sqr);
  15057. value = temp_v;
  15058. index = static_cast<std::size_t>(remainder << 1);
  15059. *(itr--) = details::rev_2digit_lut[index + 0];
  15060. *(itr--) = details::rev_2digit_lut[index + 1];
  15061. }
  15062. if (0 != value)
  15063. {
  15064. *(itr--) = strtk::details::digitr[value];
  15065. }
  15066. }
  15067. else
  15068. *(itr--) = '0';
  15069. itr++;
  15070. result.assign(reinterpret_cast<char*>(itr), (buffer + numeric<T>::size) - itr);
  15071. return true;
  15072. }
  15073. template <typename T>
  15074. inline bool type_to_string_converter_impl(T value, std::string& result, strtk::details::signed_type_tag)
  15075. {
  15076. static const std::size_t radix = 10;
  15077. static const std::size_t radix_sqr = radix * radix;
  15078. static const std::size_t radix_cube = radix * radix * radix;
  15079. unsigned char buffer[strtk::details::numeric<T>::size];
  15080. unsigned char* itr = buffer + (strtk::details::numeric<T>::size - 1);
  15081. bool negative = (value < 0);
  15082. if (negative)
  15083. value = static_cast<T>(-1 * value);
  15084. T remainder = 0;
  15085. if (0 != value)
  15086. {
  15087. std::size_t index = 0;
  15088. T temp_v = 0;
  15089. while (value >= static_cast<T>(radix_sqr))
  15090. {
  15091. temp_v = value / radix_cube;
  15092. remainder = value - (temp_v * radix_cube);
  15093. value = temp_v;
  15094. index = static_cast<std::size_t>(remainder * 3);
  15095. *(itr ) = details::rev_3digit_lut[index ];
  15096. *(itr - 1) = details::rev_3digit_lut[index + 1];
  15097. *(itr - 2) = details::rev_3digit_lut[index + 2];
  15098. itr -= 3;
  15099. }
  15100. while (value >= static_cast<T>(radix))
  15101. {
  15102. temp_v = value / radix_sqr;
  15103. remainder = value - (temp_v * radix_sqr);
  15104. value = temp_v;
  15105. index = static_cast<std::size_t>(remainder) << 1;
  15106. *(itr ) = details::rev_2digit_lut[index ];
  15107. *(itr - 1) = details::rev_2digit_lut[index + 1];
  15108. itr -= 2;
  15109. }
  15110. if (0 != value)
  15111. {
  15112. *(itr--) = strtk::details::digitr[value];
  15113. }
  15114. }
  15115. else
  15116. *(itr--) = '0';
  15117. if (negative) *(itr--) = '-';
  15118. itr++;
  15119. result.assign(reinterpret_cast<char*>(itr), (buffer + numeric<T>::size) - itr);
  15120. return true;
  15121. }
  15122. template <typename T>
  15123. inline bool type_to_string_converter_impl(const T& value, std::string& result, byte_type_tag)
  15124. {
  15125. result.resize(1);
  15126. result[0] = static_cast<char>(value);
  15127. return true;
  15128. }
  15129. inline bool type_to_string_converter_impl(const bool& value, std::string& result, bool_type_tag)
  15130. {
  15131. result.resize(1);
  15132. result[0] = value ? '1' : '0';
  15133. return true;
  15134. }
  15135. inline bool type_to_string_converter_impl(const std::string& value, std::string& result, stdstring_type_tag)
  15136. {
  15137. result = value;
  15138. return true;
  15139. }
  15140. template <typename Iterator>
  15141. inline bool type_to_string_converter_impl(const std::pair<Iterator,Iterator>& range, std::string& result, stdstring_range_type_tag)
  15142. {
  15143. result.assign(range.first,range.second);
  15144. return true;
  15145. }
  15146. template <typename SinkType>
  15147. inline bool type_to_string_converter_impl(const SinkType&, std::string&, sink_type_tag)
  15148. {
  15149. //Generic conversion not supported for sinks. Use joins or custom converters.
  15150. return false;
  15151. }
  15152. template <typename STLContainerType>
  15153. inline bool type_to_string_converter_impl(const STLContainerType&, std::string&, stl_seq_type_tag)
  15154. {
  15155. //Generic conversion not supported for stl containers. Use joins or custom converters.
  15156. return false;
  15157. }
  15158. template <typename T>
  15159. inline std::string type_name()
  15160. {
  15161. static const std::string s("Unknown");
  15162. return s;
  15163. }
  15164. #define strtk_register_type_name(Type)\
  15165. template <> inline std::string type_name<Type>() { static const std::string s(#Type); return s; }
  15166. strtk_register_type_name(signed char)
  15167. strtk_register_type_name(unsigned char)
  15168. strtk_register_type_name(short)
  15169. strtk_register_type_name(int)
  15170. strtk_register_type_name(long)
  15171. strtk_register_type_name(long long)
  15172. strtk_register_type_name(unsigned short)
  15173. strtk_register_type_name(unsigned int)
  15174. strtk_register_type_name(unsigned long)
  15175. strtk_register_type_name(unsigned long long int)
  15176. strtk_register_type_name(double)
  15177. strtk_register_type_name(float)
  15178. strtk_register_type_name(long double)
  15179. strtk_register_type_name(std::string)
  15180. #undef strtk_register_type_name
  15181. template <typename T>
  15182. inline std::string type_name(const T&)
  15183. {
  15184. static const std::string s = type_name<T>();
  15185. return s;
  15186. }
  15187. template <typename T1, typename T2>
  15188. inline std::string type_name(const std::pair<T1,T2>& p)
  15189. {
  15190. static const std::string s = std::string("std::pair<" +
  15191. type_name(p.first) +
  15192. "," +
  15193. type_name(p.second) +
  15194. ">");
  15195. return s;
  15196. }
  15197. template <typename T>
  15198. inline std::size_t type_length()
  15199. {
  15200. return numeric<T>::length;
  15201. }
  15202. template <typename T>
  15203. inline std::size_t type_length(const T&)
  15204. {
  15205. return type_length<T>();
  15206. }
  15207. inline std::size_t type_length(const std::string& s)
  15208. {
  15209. return s.size();
  15210. }
  15211. template <typename T1, typename T2>
  15212. inline std::size_t type_length(const std::pair<T1,T2>&)
  15213. {
  15214. return type_length<T1>() + type_length<T2>();
  15215. }
  15216. } // namespace details
  15217. template <typename T>
  15218. inline std::string type_name(const T& t)
  15219. {
  15220. static const std::string s = details::type_name<T>(t);
  15221. return s;
  15222. }
  15223. template <typename T, std::size_t N>
  15224. inline std::string type_name(const T(&)[N])
  15225. {
  15226. static const std::string s = details::type_name<T>() +
  15227. std::string("[") + type_to_string(N) + std::string("]");
  15228. return s;
  15229. }
  15230. template <typename T1, typename T2>
  15231. inline std::string type_name(const std::pair<T1,T2>& p)
  15232. {
  15233. static const std::string s = std::string("std::pair<" +
  15234. type_name(p.first) +
  15235. "," +
  15236. type_name(p.second) +
  15237. ">");
  15238. return s;
  15239. }
  15240. #define strtk_register_sequence_type_name(Type)\
  15241. template <typename T, typename Allocator>\
  15242. inline std::string type_name(const Type<T,Allocator>&)\
  15243. {\
  15244. static const std::string s = std::string(#Type) + std::string("<" + details::type_name<T>() + ">");\
  15245. return s;\
  15246. }
  15247. #define strtk_register_set_type_name(Type)\
  15248. template <typename T, typename Comparator, typename Allocator>\
  15249. inline std::string type_name(const Type<T,Comparator,Allocator>&)\
  15250. {\
  15251. static const std::string s = std::string(#Type) + std::string("<" + details::type_name<T>() + ">");\
  15252. return s;\
  15253. }
  15254. strtk_register_sequence_type_name(std::vector)
  15255. strtk_register_sequence_type_name(std::deque)
  15256. strtk_register_sequence_type_name(std::list)
  15257. strtk_register_set_type_name(std::set)
  15258. strtk_register_set_type_name(std::multiset)
  15259. template <typename T>
  15260. inline std::size_t type_length()
  15261. {
  15262. return details::type_length<T>();
  15263. }
  15264. template <typename T>
  15265. inline std::size_t type_length(const T&)
  15266. {
  15267. return type_length<T>();
  15268. }
  15269. class ext_string
  15270. {
  15271. public:
  15272. explicit ext_string()
  15273. {}
  15274. explicit ext_string(const std::string& s)
  15275. : s_(s)
  15276. {}
  15277. explicit ext_string(const char* s)
  15278. : s_(s)
  15279. {}
  15280. explicit ext_string(const range::adapter<char>& r)
  15281. : s_(r.begin(),r.end())
  15282. {}
  15283. ext_string(const ext_string& es)
  15284. : s_(es.s_)
  15285. {}
  15286. template <typename T>
  15287. inline ext_string& operator << (const T& t)
  15288. {
  15289. s_ += type_to_string(t);
  15290. return (*this);
  15291. }
  15292. inline operator std::string () const
  15293. {
  15294. return s_;
  15295. }
  15296. inline std::string clone() const
  15297. {
  15298. return s_;
  15299. }
  15300. inline const std::string& as_string() const
  15301. {
  15302. return s_;
  15303. }
  15304. inline std::string& as_string()
  15305. {
  15306. return s_;
  15307. }
  15308. template <typename T>
  15309. inline T as_type() const
  15310. {
  15311. return string_to_type_converter<T>(s_);
  15312. }
  15313. template <typename T>
  15314. inline bool as_type(T& t) const
  15315. {
  15316. return string_to_type_converter(s_,t);
  15317. }
  15318. inline bool imatch(const std::string& s) const
  15319. {
  15320. return strtk::imatch(s_,s);
  15321. }
  15322. inline bool imatch(const ext_string& es) const
  15323. {
  15324. return strtk::imatch(s_,es.s_);
  15325. }
  15326. inline ext_string& to_lowercase()
  15327. {
  15328. convert_to_lowercase(s_);
  15329. return (*this);
  15330. }
  15331. inline ext_string& to_uppercase()
  15332. {
  15333. convert_to_uppercase(s_);
  15334. return (*this);
  15335. }
  15336. template <typename Predicate>
  15337. inline ext_string& remove_leading(const Predicate& p)
  15338. {
  15339. if (s_.empty()) return (*this);
  15340. strtk::remove_leading(p,s_);
  15341. return (*this);
  15342. }
  15343. inline ext_string& remove_leading(const std::string& removal_set)
  15344. {
  15345. if (removal_set.empty())
  15346. return (*this);
  15347. else if (1 == removal_set.size())
  15348. strtk::remove_leading(single_delimiter_predicate<std::string::value_type>(removal_set[0]),s_);
  15349. else
  15350. strtk::remove_leading(multiple_char_delimiter_predicate(removal_set),s_);
  15351. return (*this);
  15352. }
  15353. template <typename Predicate>
  15354. inline ext_string& remove_trailing(const Predicate& p)
  15355. {
  15356. if (s_.empty()) return (*this);
  15357. strtk::remove_trailing(p,s_);
  15358. return (*this);
  15359. }
  15360. inline ext_string& remove_trailing(const std::string& removal_set)
  15361. {
  15362. if (removal_set.empty())
  15363. return (*this);
  15364. else if (1 == removal_set.size())
  15365. strtk::remove_trailing(single_delimiter_predicate<std::string::value_type>(removal_set[0]),s_);
  15366. else
  15367. strtk::remove_trailing(multiple_char_delimiter_predicate(removal_set),s_);
  15368. return (*this);
  15369. }
  15370. template <typename T>
  15371. inline ext_string& operator += (const T& t)
  15372. {
  15373. s_.append(type_to_string(t));
  15374. return (*this);
  15375. }
  15376. inline ext_string& operator -= (const std::string& pattern)
  15377. {
  15378. replace(pattern,"");
  15379. return (*this);
  15380. }
  15381. inline ext_string& operator *= (const std::size_t& n)
  15382. {
  15383. strtk::replicate_inplace(n,s_);
  15384. return (*this);
  15385. }
  15386. inline void replace(const std::string& pattern, const std::string& replace_pattern)
  15387. {
  15388. std::string result;
  15389. result.reserve(s_.size());
  15390. strtk::replace_pattern(s_,pattern,replace_pattern,result);
  15391. s_.assign(result);
  15392. }
  15393. template <typename DelimiterPredicate, typename OutputIterator>
  15394. inline std::size_t split(const DelimiterPredicate& p,
  15395. OutputIterator out,
  15396. const split_options::type split_option = split_options::default_mode) const
  15397. {
  15398. return strtk::split(p,s_,out,split_option);
  15399. }
  15400. template <typename DelimiterPredicate,
  15401. typename Allocator,
  15402. template <typename,typename> class Sequence>
  15403. inline std::size_t split(const DelimiterPredicate& p,
  15404. Sequence<std::string,Allocator>& seq,
  15405. const split_options::type split_option = split_options::default_mode) const
  15406. {
  15407. return strtk::split(p,s_,range_to_type_back_inserter(seq),split_option);
  15408. }
  15409. template <typename DelimiterPredicate, typename OutputIterator>
  15410. inline std::size_t split_n(const DelimiterPredicate& p,
  15411. const std::size_t& n,
  15412. OutputIterator out,
  15413. const split_options::type split_option = split_options::default_mode) const
  15414. {
  15415. return strtk::split_n(p,s_,n,out,split_option);
  15416. }
  15417. template <typename DelimiterPredicate,
  15418. typename Allocator,
  15419. template <typename,typename> class Sequence>
  15420. inline std::size_t split_n(const DelimiterPredicate& p,
  15421. const std::size_t& n,
  15422. Sequence<std::string,Allocator>& seq,
  15423. const split_options::type split_option = split_options::default_mode) const
  15424. {
  15425. return strtk::split_n(p,s_,n,range_to_type_back_inserter(seq),split_option);
  15426. }
  15427. template <typename T,
  15428. typename Allocator,
  15429. template <typename,typename> class Sequence>
  15430. inline std::size_t parse(const std::string& delimiters, Sequence<T,Allocator>& seq) const
  15431. {
  15432. return strtk::parse(s_,delimiters,seq);
  15433. }
  15434. template <typename T,
  15435. typename Allocator,
  15436. template <typename,typename> class Sequence>
  15437. inline std::size_t parse(const char* delimiters, Sequence<T,Allocator>& seq) const
  15438. {
  15439. return parse(std::string(delimiters),seq);
  15440. }
  15441. friend inline ext_string operator * (const std::size_t& n, const ext_string& s);
  15442. friend inline ext_string operator * (const ext_string& s, const std::size_t& n);
  15443. template <typename T>
  15444. friend inline ext_string operator + (const ext_string& s, const T& t);
  15445. template <typename T>
  15446. friend inline ext_string operator + (const T& t, const ext_string& s);
  15447. friend inline ext_string operator - (const ext_string& s, const std::string& pattern);
  15448. friend inline ext_string operator - (const ext_string& s, const char* pattern);
  15449. friend inline ext_string operator - (const ext_string& s, const ext_string& pattern);
  15450. static inline ext_string all_digits()
  15451. {
  15452. static const ext_string digits("0123456789");
  15453. return digits;
  15454. }
  15455. static inline ext_string all_letters()
  15456. {
  15457. static const ext_string letters("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
  15458. return letters;
  15459. }
  15460. static inline ext_string all_lowercase_letters()
  15461. {
  15462. static const ext_string letters("abcdefghijklmnopqrstuvwxyz");
  15463. return letters;
  15464. }
  15465. static inline ext_string all_uppercase_letters()
  15466. {
  15467. static const ext_string letters("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  15468. return letters;
  15469. }
  15470. static inline ext_string all_chars()
  15471. {
  15472. ext_string s;
  15473. s.as_string().resize(256);
  15474. strtk::iota(s.as_string().begin(),
  15475. s.as_string().end(),
  15476. static_cast<std::string::value_type>(0x00));
  15477. return s;
  15478. }
  15479. private:
  15480. std::string s_;
  15481. };
  15482. inline ext_string operator * (const std::size_t& n, const ext_string& s)
  15483. {
  15484. return ext_string(replicate(n, s.s_));
  15485. }
  15486. inline ext_string operator * (const ext_string& s, const std::size_t& n)
  15487. {
  15488. return ext_string(replicate(n, s.s_));
  15489. }
  15490. template <typename T>
  15491. inline ext_string operator + (const ext_string& s, const T& t)
  15492. {
  15493. return ext_string(s.s_ + type_to_string(t));
  15494. }
  15495. template <typename T>
  15496. inline ext_string operator + (const T& t, const ext_string& s)
  15497. {
  15498. return ext_string(type_to_string(t) + s.s_);
  15499. }
  15500. inline ext_string operator - (const ext_string& s, const std::string& pattern)
  15501. {
  15502. std::string tmp;
  15503. tmp.reserve(s.s_.size());
  15504. remove_pattern(s,pattern,tmp);
  15505. return ext_string(tmp);
  15506. }
  15507. inline ext_string operator - (const ext_string& s, const char* pattern)
  15508. {
  15509. return s - std::string(pattern);
  15510. }
  15511. inline ext_string operator - (const ext_string& s, const ext_string& pattern)
  15512. {
  15513. return s - std::string(pattern.as_string());
  15514. }
  15515. static inline std::ostream& operator<<(std::ostream& os, const ext_string& es)
  15516. {
  15517. return (os << es.as_string());
  15518. }
  15519. namespace fileio
  15520. {
  15521. inline bool file_exists(const std::string& file_name)
  15522. {
  15523. std::ifstream file(file_name.c_str(), std::ios::binary);
  15524. return ((!file) ? false : true);
  15525. }
  15526. inline std::size_t file_size(const std::string& file_name)
  15527. {
  15528. std::ifstream file(file_name.c_str(),std::ios::binary);
  15529. if (!file) return 0;
  15530. file.seekg (0, std::ios::end);
  15531. return static_cast<std::size_t>(file.tellg());
  15532. }
  15533. inline bool load_file(const std::string& file_name, char* buffer, std::size_t buffer_size)
  15534. {
  15535. std::ifstream in_stream(file_name.c_str(),std::ios::binary);
  15536. if (!in_stream) return false;
  15537. in_stream.read(buffer,static_cast<std::streamsize>(buffer_size));
  15538. in_stream.close();
  15539. return true;
  15540. }
  15541. inline bool load_file(const std::string& file_name, std::string& buffer)
  15542. {
  15543. buffer.resize(file_size(file_name));
  15544. return load_file(file_name,const_cast<char*>(buffer.data()),buffer.size());
  15545. }
  15546. inline bool write_file(const std::string& file_name, char* buffer, const std::size_t& buffer_size)
  15547. {
  15548. std::ofstream out_stream(file_name.c_str(),std::ios::binary);
  15549. if (!out_stream) return false;
  15550. out_stream.write(buffer,static_cast<std::streamsize>(buffer_size));
  15551. out_stream.close();
  15552. return true;
  15553. }
  15554. inline bool write_file(const std::string& file_name, const std::string& buffer)
  15555. {
  15556. return write_file(file_name,const_cast<char*>(buffer.data()),buffer.size());
  15557. }
  15558. inline bool copy_file(const std::string& src_file_name, const std::string& dest_file_name)
  15559. {
  15560. std::ifstream src_file(src_file_name.c_str(),std::ios::binary);
  15561. std::ofstream dest_file(dest_file_name.c_str(),std::ios::binary);
  15562. if (!src_file) return false;
  15563. if (!dest_file) return false;
  15564. static const std::size_t block_size = 16 * one_kilobyte;
  15565. char buffer[block_size];
  15566. std::size_t remaining_bytes = file_size(src_file_name);
  15567. while (remaining_bytes >= block_size)
  15568. {
  15569. src_file.read(&buffer[0],static_cast<std::streamsize>(block_size));
  15570. dest_file.write(&buffer[0],static_cast<std::streamsize>(block_size));
  15571. remaining_bytes -= block_size;
  15572. }
  15573. if (remaining_bytes > 0)
  15574. {
  15575. src_file.read(&buffer[0],static_cast<std::streamsize>(remaining_bytes));
  15576. dest_file.write(&buffer[0],static_cast<std::streamsize>(remaining_bytes));
  15577. remaining_bytes = 0;
  15578. }
  15579. src_file.close();
  15580. dest_file.close();
  15581. return true;
  15582. }
  15583. inline bool concatenate(const std::string& file_name1,
  15584. const std::string& file_name2,
  15585. const std::string& output_file_name)
  15586. {
  15587. std::ifstream file1(file_name1.c_str(),std::ios::binary);
  15588. std::ifstream file2(file_name2.c_str(),std::ios::binary);
  15589. std::ofstream out_file(output_file_name.c_str(),std::ios::binary);
  15590. if (!file1 || !file2 || !out_file) return false;
  15591. static const std::size_t block_size = 16 * one_kilobyte;
  15592. char buffer[block_size];
  15593. unsigned int round = 0;
  15594. std::size_t remaining_bytes = 0;
  15595. while (round < 2)
  15596. {
  15597. std::ifstream& input_stream = ((0 == round) ? file1 : file2);
  15598. remaining_bytes = ((0 == round) ? file_size(file_name1) : file_size(file_name2));
  15599. while (remaining_bytes >= block_size)
  15600. {
  15601. input_stream.read(&buffer[0],static_cast<std::streamsize>(block_size));
  15602. out_file.write(&buffer[0],static_cast<std::streamsize>(block_size));
  15603. remaining_bytes -= block_size;
  15604. }
  15605. if (remaining_bytes > 0)
  15606. {
  15607. input_stream.read(&buffer[0],static_cast<std::streamsize>(remaining_bytes));
  15608. out_file.write(&buffer[0],static_cast<std::streamsize>(remaining_bytes));
  15609. remaining_bytes = 0;
  15610. }
  15611. input_stream.close();
  15612. ++round;
  15613. }
  15614. out_file.close();
  15615. return true;
  15616. }
  15617. inline bool files_identical(const std::string& file_name1, const std::string& file_name2)
  15618. {
  15619. std::ifstream file1(file_name1.c_str(),std::ios::binary);
  15620. std::ifstream file2(file_name2.c_str(),std::ios::binary);
  15621. if (!file1) return false;
  15622. if (!file2) return false;
  15623. if (file_size(file_name1) != file_size(file_name2)) return false;
  15624. static const std::size_t block_size = 16 * one_kilobyte;
  15625. char buffer1[block_size];
  15626. char buffer2[block_size];
  15627. std::size_t remaining_bytes = file_size(file_name1);
  15628. while (remaining_bytes >= block_size)
  15629. {
  15630. file1.read(&buffer1[0],static_cast<std::streamsize>(block_size));
  15631. file2.read(&buffer2[0],static_cast<std::streamsize>(block_size));
  15632. if (0 != std::memcmp(buffer1,buffer2,block_size))
  15633. return false;
  15634. remaining_bytes -= block_size;
  15635. }
  15636. if (remaining_bytes > 0)
  15637. {
  15638. file1.read(&buffer1[0],static_cast<std::streamsize>(remaining_bytes));
  15639. file2.read(&buffer2[0],static_cast<std::streamsize>(remaining_bytes));
  15640. if (0 != std::memcmp(buffer1,buffer2,remaining_bytes))
  15641. return false;
  15642. remaining_bytes = 0;
  15643. }
  15644. file1.close();
  15645. file2.close();
  15646. return true;
  15647. }
  15648. namespace details
  15649. {
  15650. template <typename T>
  15651. inline bool read_pod_proxy(std::ifstream& stream, T& t)
  15652. {
  15653. return (false == stream.read(reinterpret_cast<char*>(&t),
  15654. static_cast<std::streamsize>(sizeof(T))).fail());
  15655. }
  15656. template <typename T>
  15657. inline bool write_pod_proxy(std::ofstream& stream, const T& t)
  15658. {
  15659. return (false == stream.write(reinterpret_cast<char*>(&t),
  15660. static_cast<std::streamsize>(sizeof(T))).fail());
  15661. }
  15662. }
  15663. template <typename T1, typename T2, typename T3, typename T4,
  15664. typename T5, typename T6, typename T7, typename T8,
  15665. typename T9, typename T10>
  15666. inline bool read_pod(std::ifstream& stream,
  15667. T1& t1, T2& t2, T3& t3, T4& t4,
  15668. T5& t5, T6& t6, T7& t7, T8& t8,
  15669. T9& t9, T10& t10)
  15670. {
  15671. return details::read_pod_proxy(stream, t1) &&
  15672. details::read_pod_proxy(stream, t2) &&
  15673. details::read_pod_proxy(stream, t3) &&
  15674. details::read_pod_proxy(stream, t4) &&
  15675. details::read_pod_proxy(stream, t5) &&
  15676. details::read_pod_proxy(stream, t6) &&
  15677. details::read_pod_proxy(stream, t7) &&
  15678. details::read_pod_proxy(stream, t8) &&
  15679. details::read_pod_proxy(stream, t9) &&
  15680. details::read_pod_proxy(stream,t10);
  15681. }
  15682. template <typename T1, typename T2, typename T3, typename T4,
  15683. typename T5, typename T6, typename T7, typename T8,
  15684. typename T9>
  15685. inline bool read_pod(std::ifstream& stream,
  15686. T1& t1, T2& t2, T3& t3, T4& t4,
  15687. T5& t5, T6& t6, T7& t7, T8& t8,
  15688. T9& t9)
  15689. {
  15690. return details::read_pod_proxy(stream,t1) &&
  15691. details::read_pod_proxy(stream,t2) &&
  15692. details::read_pod_proxy(stream,t3) &&
  15693. details::read_pod_proxy(stream,t4) &&
  15694. details::read_pod_proxy(stream,t5) &&
  15695. details::read_pod_proxy(stream,t6) &&
  15696. details::read_pod_proxy(stream,t7) &&
  15697. details::read_pod_proxy(stream,t8) &&
  15698. details::read_pod_proxy(stream,t9);
  15699. }
  15700. template <typename T1, typename T2, typename T3, typename T4,
  15701. typename T5, typename T6, typename T7, typename T8>
  15702. inline bool read_pod(std::ifstream& stream,
  15703. T1& t1, T2& t2, T3& t3, T4& t4,
  15704. T5& t5, T6& t6, T7& t7, T8& t8)
  15705. {
  15706. return details::read_pod_proxy(stream,t1) &&
  15707. details::read_pod_proxy(stream,t2) &&
  15708. details::read_pod_proxy(stream,t3) &&
  15709. details::read_pod_proxy(stream,t4) &&
  15710. details::read_pod_proxy(stream,t5) &&
  15711. details::read_pod_proxy(stream,t6) &&
  15712. details::read_pod_proxy(stream,t7) &&
  15713. details::read_pod_proxy(stream,t8);
  15714. }
  15715. template <typename T1, typename T2, typename T3, typename T4,
  15716. typename T5, typename T6, typename T7>
  15717. inline bool read_pod(std::ifstream& stream,
  15718. T1& t1, T2& t2, T3& t3, T4& t4,
  15719. T5& t5, T6& t6, T7& t7)
  15720. {
  15721. return details::read_pod_proxy(stream,t1) &&
  15722. details::read_pod_proxy(stream,t2) &&
  15723. details::read_pod_proxy(stream,t3) &&
  15724. details::read_pod_proxy(stream,t4) &&
  15725. details::read_pod_proxy(stream,t5) &&
  15726. details::read_pod_proxy(stream,t6) &&
  15727. details::read_pod_proxy(stream,t7);
  15728. }
  15729. template <typename T1, typename T2, typename T3, typename T4,
  15730. typename T5, typename T6>
  15731. inline bool read_pod(std::ifstream& stream,
  15732. T1& t1, T2& t2, T3& t3, T4& t4,
  15733. T5& t5, T6& t6)
  15734. {
  15735. return details::read_pod_proxy(stream,t1) &&
  15736. details::read_pod_proxy(stream,t2) &&
  15737. details::read_pod_proxy(stream,t3) &&
  15738. details::read_pod_proxy(stream,t4) &&
  15739. details::read_pod_proxy(stream,t5) &&
  15740. details::read_pod_proxy(stream,t6);
  15741. }
  15742. template <typename T1, typename T2, typename T3, typename T4,
  15743. typename T5>
  15744. inline bool read_pod(std::ifstream& stream,
  15745. T1& t1, T2& t2, T3& t3, T4& t4,
  15746. T5& t5)
  15747. {
  15748. return details::read_pod_proxy(stream,t1) &&
  15749. details::read_pod_proxy(stream,t2) &&
  15750. details::read_pod_proxy(stream,t3) &&
  15751. details::read_pod_proxy(stream,t4) &&
  15752. details::read_pod_proxy(stream,t5);
  15753. }
  15754. template <typename T1, typename T2, typename T3, typename T4>
  15755. inline bool read_pod(std::ifstream& stream,
  15756. T1& t1, T2& t2, T3& t3, T4& t4)
  15757. {
  15758. return details::read_pod_proxy(stream,t1) &&
  15759. details::read_pod_proxy(stream,t2) &&
  15760. details::read_pod_proxy(stream,t3) &&
  15761. details::read_pod_proxy(stream,t4);
  15762. }
  15763. template <typename T1, typename T2, typename T3>
  15764. inline bool read_pod(std::ifstream& stream,
  15765. T1& t1, T2& t2, T3& t3)
  15766. {
  15767. return details::read_pod_proxy(stream,t1) &&
  15768. details::read_pod_proxy(stream,t2) &&
  15769. details::read_pod_proxy(stream,t3);
  15770. }
  15771. template <typename T1, typename T2>
  15772. inline bool read_pod(std::ifstream& stream,
  15773. T1& t1, T2& t2)
  15774. {
  15775. return details::read_pod_proxy(stream,t1) &&
  15776. details::read_pod_proxy(stream,t2);
  15777. }
  15778. template <typename T>
  15779. inline bool read_pod(std::ifstream& stream, T& t)
  15780. {
  15781. return details::read_pod_proxy(stream,t);
  15782. }
  15783. template <typename T, std::size_t N>
  15784. inline bool read_pod(std::ifstream& stream, T (&t)[N])
  15785. {
  15786. return (false != stream.read(reinterpret_cast<char*>(&t[0]),sizeof(T) * N).fail());
  15787. }
  15788. template <typename T,
  15789. typename Allocator,
  15790. template <typename,typename> class Sequence>
  15791. inline bool read_pod(std::ifstream& stream,
  15792. const std::size_t& count,
  15793. Sequence<T,Allocator>& sequence)
  15794. {
  15795. T t;
  15796. for (std::size_t i = 0; i < count; ++i)
  15797. {
  15798. if (details::read_pod_proxy(stream,t))
  15799. sequence.push_back(t);
  15800. else
  15801. return false;
  15802. }
  15803. return true;
  15804. }
  15805. template <typename T,
  15806. typename Comparator,
  15807. typename Allocator>
  15808. inline bool read_pod(std::ifstream& stream,
  15809. const std::size_t& count,
  15810. std::set<T,Comparator,Allocator>& set)
  15811. {
  15812. T t;
  15813. for (std::size_t i = 0; i < count; ++i)
  15814. {
  15815. if (details::read_pod_proxy(stream,t))
  15816. set.insert(t);
  15817. else
  15818. return false;
  15819. }
  15820. return true;
  15821. }
  15822. template <typename T,
  15823. typename Comparator,
  15824. typename Allocator>
  15825. inline bool read_pod(std::ifstream& stream,
  15826. const std::size_t& count,
  15827. std::multiset<T,Comparator,Allocator>& multiset)
  15828. {
  15829. T t;
  15830. for (std::size_t i = 0; i < count; ++i)
  15831. {
  15832. if (details::read_pod_proxy(stream,t))
  15833. multiset.insert(t);
  15834. else
  15835. return false;
  15836. }
  15837. return true;
  15838. }
  15839. template <typename T1, typename T2, typename T3, typename T4,
  15840. typename T5, typename T6, typename T7, typename T8,
  15841. typename T9, typename T10>
  15842. inline bool write_pod(std::ofstream& stream,
  15843. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  15844. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  15845. const T9& t9, const T10& t10)
  15846. {
  15847. return details::write_pod_proxy(stream, t1) &&
  15848. details::write_pod_proxy(stream, t2) &&
  15849. details::write_pod_proxy(stream, t3) &&
  15850. details::write_pod_proxy(stream, t4) &&
  15851. details::write_pod_proxy(stream, t5) &&
  15852. details::write_pod_proxy(stream, t6) &&
  15853. details::write_pod_proxy(stream, t7) &&
  15854. details::write_pod_proxy(stream, t8) &&
  15855. details::write_pod_proxy(stream, t9) &&
  15856. details::write_pod_proxy(stream,t10);
  15857. }
  15858. template <typename T1, typename T2, typename T3, typename T4,
  15859. typename T5, typename T6, typename T7, typename T8,
  15860. typename T9>
  15861. inline bool write_pod(std::ofstream& stream,
  15862. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  15863. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  15864. const T9& t9)
  15865. {
  15866. return details::write_pod_proxy(stream,t1) &&
  15867. details::write_pod_proxy(stream,t2) &&
  15868. details::write_pod_proxy(stream,t3) &&
  15869. details::write_pod_proxy(stream,t4) &&
  15870. details::write_pod_proxy(stream,t5) &&
  15871. details::write_pod_proxy(stream,t6) &&
  15872. details::write_pod_proxy(stream,t7) &&
  15873. details::write_pod_proxy(stream,t8) &&
  15874. details::write_pod_proxy(stream,t9);
  15875. }
  15876. template <typename T1, typename T2, typename T3, typename T4,
  15877. typename T5, typename T6, typename T7, typename T8>
  15878. inline bool write_pod(std::ofstream& stream,
  15879. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  15880. const T5& t5, const T6& t6, const T7& t7, const T8& t8)
  15881. {
  15882. return details::write_pod_proxy(stream,t1) &&
  15883. details::write_pod_proxy(stream,t2) &&
  15884. details::write_pod_proxy(stream,t3) &&
  15885. details::write_pod_proxy(stream,t4) &&
  15886. details::write_pod_proxy(stream,t5) &&
  15887. details::write_pod_proxy(stream,t6) &&
  15888. details::write_pod_proxy(stream,t7) &&
  15889. details::write_pod_proxy(stream,t8);
  15890. }
  15891. template <typename T1, typename T2, typename T3, typename T4,
  15892. typename T5, typename T6, typename T7>
  15893. inline bool write_pod(std::ofstream& stream,
  15894. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  15895. const T5& t5, const T6& t6, const T7& t7)
  15896. {
  15897. return details::write_pod_proxy(stream,t1) &&
  15898. details::write_pod_proxy(stream,t2) &&
  15899. details::write_pod_proxy(stream,t3) &&
  15900. details::write_pod_proxy(stream,t4) &&
  15901. details::write_pod_proxy(stream,t5) &&
  15902. details::write_pod_proxy(stream,t6) &&
  15903. details::write_pod_proxy(stream,t7);
  15904. }
  15905. template <typename T1, typename T2, typename T3, typename T4,
  15906. typename T5, typename T6>
  15907. inline bool write_pod(std::ofstream& stream,
  15908. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  15909. const T5& t5, const T6& t6)
  15910. {
  15911. return details::write_pod_proxy(stream,t1) &&
  15912. details::write_pod_proxy(stream,t2) &&
  15913. details::write_pod_proxy(stream,t3) &&
  15914. details::write_pod_proxy(stream,t4) &&
  15915. details::write_pod_proxy(stream,t5) &&
  15916. details::write_pod_proxy(stream,t6);
  15917. }
  15918. template <typename T1, typename T2, typename T3, typename T4,
  15919. typename T5>
  15920. inline bool write_pod(std::ofstream& stream,
  15921. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  15922. const T5& t5)
  15923. {
  15924. return details::write_pod_proxy(stream,t1) &&
  15925. details::write_pod_proxy(stream,t2) &&
  15926. details::write_pod_proxy(stream,t3) &&
  15927. details::write_pod_proxy(stream,t4) &&
  15928. details::write_pod_proxy(stream,t5);
  15929. }
  15930. template <typename T1, typename T2, typename T3, typename T4>
  15931. inline bool write_pod(std::ofstream& stream,
  15932. const T1& t1, const T2& t2, const T3& t3, const T4& t4)
  15933. {
  15934. return details::write_pod_proxy(stream,t1) &&
  15935. details::write_pod_proxy(stream,t2) &&
  15936. details::write_pod_proxy(stream,t3) &&
  15937. details::write_pod_proxy(stream,t4);
  15938. }
  15939. template <typename T1, typename T2, typename T3>
  15940. inline bool write_pod(std::ofstream& stream,
  15941. const T1& t1, const T2& t2, const T3& t3)
  15942. {
  15943. return details::write_pod_proxy(stream,t1) &&
  15944. details::write_pod_proxy(stream,t2) &&
  15945. details::write_pod_proxy(stream,t3);
  15946. }
  15947. template <typename T1, typename T2>
  15948. inline bool write_pod(std::ofstream& stream,
  15949. const T1& t1, const T2& t2)
  15950. {
  15951. return details::write_pod_proxy(stream,t1) &&
  15952. details::write_pod_proxy(stream,t2);
  15953. }
  15954. template <typename T>
  15955. inline bool write_pod(std::ofstream& stream, const T& t)
  15956. {
  15957. return details::write_pod_proxy(stream,t);
  15958. }
  15959. template <typename T, std::size_t N>
  15960. inline bool write_pod(std::ofstream& stream, T (&t)[N])
  15961. {
  15962. return (false != stream.write(reinterpret_cast<char*>(&t[0]),sizeof(T) * N).fail());
  15963. }
  15964. template <typename T,
  15965. typename Allocator,
  15966. template <typename,typename> class Sequence>
  15967. inline bool write_pod(std::ofstream& stream,
  15968. const Sequence<T,Allocator>& sequence)
  15969. {
  15970. typename Sequence<T,Allocator>::iterator itr = sequence.begin();
  15971. typename Sequence<T,Allocator>::iterator end = sequence.end();
  15972. while (end != itr)
  15973. {
  15974. if (details::write_pod_proxy(stream,*itr))
  15975. ++itr;
  15976. else
  15977. return false;
  15978. }
  15979. }
  15980. template <typename T,
  15981. typename Comparator,
  15982. typename Allocator>
  15983. inline bool write_pod(std::ofstream& stream,
  15984. const std::set<T,Comparator,Allocator>& set)
  15985. {
  15986. typename std::set<T,Comparator,Allocator>::iterator itr = set.begin();
  15987. typename std::set<T,Comparator,Allocator>::iterator end = set.end();
  15988. while (end != itr)
  15989. {
  15990. if (details::write_pod_proxy(stream,*itr))
  15991. ++itr;
  15992. else
  15993. return false;
  15994. }
  15995. }
  15996. template <typename T,
  15997. typename Comparator,
  15998. typename Allocator>
  15999. inline bool write_pod(std::ofstream& stream,
  16000. const std::multiset<T,Comparator,Allocator>& multiset)
  16001. {
  16002. typename std::multiset<T,Comparator,Allocator>::iterator itr = multiset.begin();
  16003. typename std::multiset<T,Comparator,Allocator>::iterator end = multiset.end();
  16004. while (end != itr)
  16005. {
  16006. if (details::write_pod_proxy(stream,*itr))
  16007. ++itr;
  16008. else
  16009. return false;
  16010. }
  16011. }
  16012. inline bool read_at_offset(std::ifstream& stream,
  16013. const std::size_t& offset,
  16014. char* buffer,
  16015. const std::size_t& buffer_size)
  16016. {
  16017. if (!stream) return false;
  16018. stream.seekg(static_cast<std::ifstream::off_type>(offset),std::ios_base::beg);
  16019. if (stream.fail()) return false;
  16020. stream.read(buffer,static_cast<std::streamsize>(buffer_size));
  16021. if (stream.fail()) return false;
  16022. stream.close();
  16023. return true;
  16024. }
  16025. inline bool read_at_offset(const std::string& file_name,
  16026. const std::size_t& offset,
  16027. char* buffer,
  16028. const std::size_t& buffer_size)
  16029. {
  16030. std::ifstream stream(file_name.c_str(), std::ios::in | std::ios::binary);
  16031. if (!stream) return false;
  16032. return read_at_offset(stream,offset,buffer,buffer_size);
  16033. }
  16034. inline bool read_at_offset(const std::string& file_name,
  16035. const std::size_t& offset,
  16036. std::string& buffer,
  16037. const std::size_t& buffer_size)
  16038. {
  16039. std::ifstream stream(file_name.c_str(), std::ios::in | std::ios::binary);
  16040. if (!stream) return false;
  16041. buffer.resize(buffer_size);
  16042. return read_at_offset(stream,
  16043. offset,
  16044. const_cast<char*>(buffer.data()),
  16045. buffer_size);
  16046. }
  16047. } // namespace fileio
  16048. template <typename T1, typename T2, typename T3, typename T4,
  16049. typename T5, typename T6, typename T7, typename T8,
  16050. typename T9, typename T10, typename T11, typename T12>
  16051. inline unsigned char* read_pod(unsigned char* data,
  16052. T1& t1, T2& t2, T3& t3, T4& t4,
  16053. T5& t5, T6& t6, T7& t7, T8& t8,
  16054. T9& t9, T10& t10, T11& t11, T12& t12)
  16055. {
  16056. t1 = (*reinterpret_cast< T1*>(data)); data += sizeof( T1);
  16057. t2 = (*reinterpret_cast< T2*>(data)); data += sizeof( T2);
  16058. t3 = (*reinterpret_cast< T3*>(data)); data += sizeof( T3);
  16059. t4 = (*reinterpret_cast< T4*>(data)); data += sizeof( T4);
  16060. t5 = (*reinterpret_cast< T5*>(data)); data += sizeof( T5);
  16061. t6 = (*reinterpret_cast< T6*>(data)); data += sizeof( T6);
  16062. t7 = (*reinterpret_cast< T7*>(data)); data += sizeof( T7);
  16063. t8 = (*reinterpret_cast< T8*>(data)); data += sizeof( T8);
  16064. t9 = (*reinterpret_cast< T9*>(data)); data += sizeof( T9);
  16065. t10 = (*reinterpret_cast<T10*>(data)); data += sizeof(T10);
  16066. t11 = (*reinterpret_cast<T11*>(data)); data += sizeof(T11);
  16067. t12 = (*reinterpret_cast<T12*>(data)); data += sizeof(T12);
  16068. return data;
  16069. }
  16070. template <typename T1, typename T2, typename T3, typename T4,
  16071. typename T5, typename T6, typename T7, typename T8,
  16072. typename T9, typename T10, typename T11>
  16073. inline unsigned char* read_pod(unsigned char* data,
  16074. T1& t1, T2& t2, T3& t3, T4& t4,
  16075. T5& t5, T6& t6, T7& t7, T8& t8,
  16076. T9& t9, T10& t10, T11& t11)
  16077. {
  16078. t1 = (*reinterpret_cast< T1*>(data)); data += sizeof( T1);
  16079. t2 = (*reinterpret_cast< T2*>(data)); data += sizeof( T2);
  16080. t3 = (*reinterpret_cast< T3*>(data)); data += sizeof( T3);
  16081. t4 = (*reinterpret_cast< T4*>(data)); data += sizeof( T4);
  16082. t5 = (*reinterpret_cast< T5*>(data)); data += sizeof( T5);
  16083. t6 = (*reinterpret_cast< T6*>(data)); data += sizeof( T6);
  16084. t7 = (*reinterpret_cast< T7*>(data)); data += sizeof( T7);
  16085. t8 = (*reinterpret_cast< T8*>(data)); data += sizeof( T8);
  16086. t9 = (*reinterpret_cast< T9*>(data)); data += sizeof( T9);
  16087. t10 = (*reinterpret_cast<T10*>(data)); data += sizeof(T10);
  16088. t11 = (*reinterpret_cast<T11*>(data)); data += sizeof(T11);
  16089. return data;
  16090. }
  16091. template <typename T1, typename T2, typename T3, typename T4,
  16092. typename T5, typename T6, typename T7, typename T8,
  16093. typename T9, typename T10>
  16094. inline unsigned char* read_pod(unsigned char* data,
  16095. T1& t1, T2& t2, T3& t3, T4& t4,
  16096. T5& t5, T6& t6, T7& t7, T8& t8,
  16097. T9& t9, T10& t10)
  16098. {
  16099. t1 = (*reinterpret_cast< T1*>(data)); data += sizeof( T1);
  16100. t2 = (*reinterpret_cast< T2*>(data)); data += sizeof( T2);
  16101. t3 = (*reinterpret_cast< T3*>(data)); data += sizeof( T3);
  16102. t4 = (*reinterpret_cast< T4*>(data)); data += sizeof( T4);
  16103. t5 = (*reinterpret_cast< T5*>(data)); data += sizeof( T5);
  16104. t6 = (*reinterpret_cast< T6*>(data)); data += sizeof( T6);
  16105. t7 = (*reinterpret_cast< T7*>(data)); data += sizeof( T7);
  16106. t8 = (*reinterpret_cast< T8*>(data)); data += sizeof( T8);
  16107. t9 = (*reinterpret_cast< T9*>(data)); data += sizeof( T9);
  16108. t10 = (*reinterpret_cast<T10*>(data)); data += sizeof(T10);
  16109. return data;
  16110. }
  16111. template <typename T1, typename T2, typename T3, typename T4,
  16112. typename T5, typename T6, typename T7, typename T8,
  16113. typename T9>
  16114. inline unsigned char* read_pod(unsigned char* data,
  16115. T1& t1, T2& t2, T3& t3, T4& t4,
  16116. T5& t5, T6& t6, T7& t7, T8& t8,
  16117. T9& t9)
  16118. {
  16119. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16120. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16121. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16122. t4 = (*reinterpret_cast<T4*>(data)); data += sizeof(T4);
  16123. t5 = (*reinterpret_cast<T5*>(data)); data += sizeof(T5);
  16124. t6 = (*reinterpret_cast<T6*>(data)); data += sizeof(T6);
  16125. t7 = (*reinterpret_cast<T7*>(data)); data += sizeof(T7);
  16126. t8 = (*reinterpret_cast<T8*>(data)); data += sizeof(T8);
  16127. t9 = (*reinterpret_cast<T9*>(data)); data += sizeof(T9);
  16128. return data;
  16129. }
  16130. template <typename T1, typename T2, typename T3, typename T4,
  16131. typename T5, typename T6, typename T7, typename T8>
  16132. inline unsigned char* read_pod(unsigned char* data,
  16133. T1& t1, T2& t2, T3& t3, T4& t4,
  16134. T5& t5, T6& t6, T7& t7, T8& t8)
  16135. {
  16136. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16137. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16138. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16139. t4 = (*reinterpret_cast<T4*>(data)); data += sizeof(T4);
  16140. t5 = (*reinterpret_cast<T5*>(data)); data += sizeof(T5);
  16141. t6 = (*reinterpret_cast<T6*>(data)); data += sizeof(T6);
  16142. t7 = (*reinterpret_cast<T7*>(data)); data += sizeof(T7);
  16143. t8 = (*reinterpret_cast<T8*>(data)); data += sizeof(T8);
  16144. return data;
  16145. }
  16146. template <typename T1, typename T2, typename T3, typename T4,
  16147. typename T5, typename T6, typename T7>
  16148. inline unsigned char* read_pod(unsigned char* data,
  16149. T1& t1, T2& t2, T3& t3, T4& t4,
  16150. T5& t5, T6& t6, T7& t7)
  16151. {
  16152. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16153. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16154. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16155. t4 = (*reinterpret_cast<T4*>(data)); data += sizeof(T4);
  16156. t5 = (*reinterpret_cast<T5*>(data)); data += sizeof(T5);
  16157. t6 = (*reinterpret_cast<T6*>(data)); data += sizeof(T6);
  16158. t7 = (*reinterpret_cast<T7*>(data)); data += sizeof(T7);
  16159. return data;
  16160. }
  16161. template <typename T1, typename T2, typename T3, typename T4,
  16162. typename T5, typename T6>
  16163. inline unsigned char* read_pod(unsigned char* data,
  16164. T1& t1, T2& t2, T3& t3, T4& t4,
  16165. T5& t5, T6& t6)
  16166. {
  16167. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16168. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16169. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16170. t4 = (*reinterpret_cast<T4*>(data)); data += sizeof(T4);
  16171. t5 = (*reinterpret_cast<T5*>(data)); data += sizeof(T5);
  16172. t6 = (*reinterpret_cast<T6*>(data)); data += sizeof(T6);
  16173. return data;
  16174. }
  16175. template <typename T1, typename T2, typename T3, typename T4,
  16176. typename T5>
  16177. inline unsigned char* read_pod(unsigned char* data,
  16178. T1& t1, T2& t2, T3& t3, T4& t4,
  16179. T5& t5)
  16180. {
  16181. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16182. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16183. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16184. t4 = (*reinterpret_cast<T4*>(data)); data += sizeof(T4);
  16185. t5 = (*reinterpret_cast<T5*>(data)); data += sizeof(T5);
  16186. return data;
  16187. }
  16188. template <typename T1, typename T2, typename T3, typename T4>
  16189. inline unsigned char* read_pod(unsigned char* data,
  16190. T1& t1, T2& t2, T3& t3, T4& t4)
  16191. {
  16192. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16193. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16194. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16195. t4 = (*reinterpret_cast<T4*>(data)); data += sizeof(T4);
  16196. return data;
  16197. }
  16198. template <typename T1, typename T2, typename T3>
  16199. inline unsigned char* read_pod(unsigned char* data,
  16200. T1& t1, T2& t2, T3& t3)
  16201. {
  16202. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16203. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16204. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16205. return data;
  16206. }
  16207. template <typename T1, typename T2>
  16208. inline unsigned char* read_pod(unsigned char* data,
  16209. T1& t1, T2& t2)
  16210. {
  16211. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16212. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16213. return data;
  16214. }
  16215. template <typename T1>
  16216. inline unsigned char* read_pod(unsigned char* data,
  16217. T1& t1)
  16218. {
  16219. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16220. return data;
  16221. }
  16222. template <typename T, std::size_t N>
  16223. inline unsigned char* read_pod(unsigned char* data, T (&t)[N])
  16224. {
  16225. T* begin = reinterpret_cast<T*>(data);
  16226. T* end = begin + N;
  16227. std::copy(begin,end,&t[0]);
  16228. return data + (N * sizeof(T));
  16229. }
  16230. template <typename T,
  16231. typename Allocator,
  16232. template <typename,typename> class Sequence>
  16233. inline unsigned char* read_pod(unsigned char* data,
  16234. const std::size_t& n,
  16235. const Sequence<T,Allocator>& sequence)
  16236. {
  16237. T* ptr = reinterpret_cast<T>(data);
  16238. std::copy(ptr, ptr + n, std::back_inserter(sequence));
  16239. return data + (sequence.size() * sizeof(T));
  16240. }
  16241. template <typename T,
  16242. typename Comparator,
  16243. typename Allocator>
  16244. inline unsigned char* read_pod(unsigned char* data,
  16245. const std::size_t& n,
  16246. const std::set<T,Comparator,Allocator>& set)
  16247. {
  16248. T* ptr = reinterpret_cast<T>(data);
  16249. std::copy(ptr, ptr + n, std::inserter(set,set.begin()));
  16250. return data + (set.size() * sizeof(T));
  16251. }
  16252. template <typename T,
  16253. typename Comparator,
  16254. typename Allocator>
  16255. inline unsigned char* read_pod(unsigned char* data,
  16256. const std::size_t& n,
  16257. const std::multiset<T,Comparator,Allocator>& multiset)
  16258. {
  16259. T* ptr = reinterpret_cast<T>(data);
  16260. std::copy(ptr, ptr + n, std::inserter(multiset,multiset.begin()));
  16261. return data + (multiset.size() * sizeof(T));
  16262. }
  16263. template <typename T1, typename T2, typename T3, typename T4,
  16264. typename T5, typename T6, typename T7, typename T8,
  16265. typename T9, typename T10, typename T11, typename T12>
  16266. inline unsigned char* write_pod(unsigned char* data,
  16267. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16268. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  16269. const T9& t9, const T10& t10, const T11& t11, const T12& t12)
  16270. {
  16271. (*reinterpret_cast< T1*>(data)) = t1; data += sizeof( T1);
  16272. (*reinterpret_cast< T2*>(data)) = t2; data += sizeof( T2);
  16273. (*reinterpret_cast< T3*>(data)) = t3; data += sizeof( T3);
  16274. (*reinterpret_cast< T4*>(data)) = t4; data += sizeof( T4);
  16275. (*reinterpret_cast< T5*>(data)) = t5; data += sizeof( T5);
  16276. (*reinterpret_cast< T6*>(data)) = t6; data += sizeof( T6);
  16277. (*reinterpret_cast< T7*>(data)) = t7; data += sizeof( T7);
  16278. (*reinterpret_cast< T8*>(data)) = t8; data += sizeof( T8);
  16279. (*reinterpret_cast< T9*>(data)) = t9; data += sizeof( T9);
  16280. (*reinterpret_cast<T10*>(data)) = t10; data += sizeof(T10);
  16281. (*reinterpret_cast<T11*>(data)) = t11; data += sizeof(T11);
  16282. (*reinterpret_cast<T12*>(data)) = t12; data += sizeof(T12);
  16283. return data;
  16284. }
  16285. template <typename T1, typename T2, typename T3, typename T4,
  16286. typename T5, typename T6, typename T7, typename T8,
  16287. typename T9, typename T10, typename T11>
  16288. inline unsigned char* write_pod(unsigned char* data,
  16289. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16290. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  16291. const T9& t9, const T10& t10, const T11& t11)
  16292. {
  16293. (*reinterpret_cast< T1*>(data)) = t1; data += sizeof( T1);
  16294. (*reinterpret_cast< T2*>(data)) = t2; data += sizeof( T2);
  16295. (*reinterpret_cast< T3*>(data)) = t3; data += sizeof( T3);
  16296. (*reinterpret_cast< T4*>(data)) = t4; data += sizeof( T4);
  16297. (*reinterpret_cast< T5*>(data)) = t5; data += sizeof( T5);
  16298. (*reinterpret_cast< T6*>(data)) = t6; data += sizeof( T6);
  16299. (*reinterpret_cast< T7*>(data)) = t7; data += sizeof( T7);
  16300. (*reinterpret_cast< T8*>(data)) = t8; data += sizeof( T8);
  16301. (*reinterpret_cast< T9*>(data)) = t9; data += sizeof( T9);
  16302. (*reinterpret_cast<T10*>(data)) = t10; data += sizeof(T10);
  16303. (*reinterpret_cast<T11*>(data)) = t11; data += sizeof(T11);
  16304. return data;
  16305. }
  16306. template <typename T1, typename T2, typename T3, typename T4,
  16307. typename T5, typename T6, typename T7, typename T8,
  16308. typename T9, typename T10>
  16309. inline unsigned char* write_pod(unsigned char* data,
  16310. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16311. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  16312. const T9& t9, const T10& t10)
  16313. {
  16314. (*reinterpret_cast< T1*>(data)) = t1; data += sizeof( T1);
  16315. (*reinterpret_cast< T2*>(data)) = t2; data += sizeof( T2);
  16316. (*reinterpret_cast< T3*>(data)) = t3; data += sizeof( T3);
  16317. (*reinterpret_cast< T4*>(data)) = t4; data += sizeof( T4);
  16318. (*reinterpret_cast< T5*>(data)) = t5; data += sizeof( T5);
  16319. (*reinterpret_cast< T6*>(data)) = t6; data += sizeof( T6);
  16320. (*reinterpret_cast< T7*>(data)) = t7; data += sizeof( T7);
  16321. (*reinterpret_cast< T8*>(data)) = t8; data += sizeof( T8);
  16322. (*reinterpret_cast< T9*>(data)) = t9; data += sizeof( T9);
  16323. (*reinterpret_cast<T10*>(data)) = t10; data += sizeof(T10);
  16324. return data;
  16325. }
  16326. template <typename T1, typename T2, typename T3, typename T4,
  16327. typename T5, typename T6, typename T7, typename T8,
  16328. typename T9>
  16329. inline unsigned char* write_pod(unsigned char* data,
  16330. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16331. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  16332. const T9& t9)
  16333. {
  16334. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16335. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16336. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16337. (*reinterpret_cast<T4*>(data)) = t4; data += sizeof(T4);
  16338. (*reinterpret_cast<T5*>(data)) = t5; data += sizeof(T5);
  16339. (*reinterpret_cast<T6*>(data)) = t6; data += sizeof(T6);
  16340. (*reinterpret_cast<T7*>(data)) = t7; data += sizeof(T7);
  16341. (*reinterpret_cast<T8*>(data)) = t8; data += sizeof(T8);
  16342. (*reinterpret_cast<T9*>(data)) = t9; data += sizeof(T9);
  16343. return data;
  16344. }
  16345. template <typename T1, typename T2, typename T3, typename T4,
  16346. typename T5, typename T6, typename T7, typename T8>
  16347. inline unsigned char* write_pod(unsigned char* data,
  16348. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16349. const T5& t5, const T6& t6, const T7& t7, const T8& t8)
  16350. {
  16351. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16352. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16353. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16354. (*reinterpret_cast<T4*>(data)) = t4; data += sizeof(T4);
  16355. (*reinterpret_cast<T5*>(data)) = t5; data += sizeof(T5);
  16356. (*reinterpret_cast<T6*>(data)) = t6; data += sizeof(T6);
  16357. (*reinterpret_cast<T7*>(data)) = t7; data += sizeof(T7);
  16358. (*reinterpret_cast<T8*>(data)) = t8; data += sizeof(T8);
  16359. return data;
  16360. }
  16361. template <typename T1, typename T2, typename T3, typename T4,
  16362. typename T5, typename T6, typename T7>
  16363. inline unsigned char* write_pod(unsigned char* data,
  16364. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16365. const T5& t5, const T6& t6, const T7& t7)
  16366. {
  16367. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16368. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16369. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16370. (*reinterpret_cast<T4*>(data)) = t4; data += sizeof(T4);
  16371. (*reinterpret_cast<T5*>(data)) = t5; data += sizeof(T5);
  16372. (*reinterpret_cast<T6*>(data)) = t6; data += sizeof(T6);
  16373. (*reinterpret_cast<T7*>(data)) = t7; data += sizeof(T7);
  16374. return data;
  16375. }
  16376. template <typename T1, typename T2, typename T3, typename T4,
  16377. typename T5, typename T6>
  16378. inline unsigned char* write_pod(unsigned char* data,
  16379. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16380. const T5& t5, const T6& t6)
  16381. {
  16382. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16383. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16384. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16385. (*reinterpret_cast<T4*>(data)) = t4; data += sizeof(T4);
  16386. (*reinterpret_cast<T5*>(data)) = t5; data += sizeof(T5);
  16387. (*reinterpret_cast<T6*>(data)) = t6; data += sizeof(T6);
  16388. return data;
  16389. }
  16390. template <typename T1, typename T2, typename T3, typename T4,
  16391. typename T5>
  16392. inline unsigned char* write_pod(unsigned char* data,
  16393. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16394. const T5& t5)
  16395. {
  16396. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16397. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16398. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16399. (*reinterpret_cast<T4*>(data)) = t4; data += sizeof(T4);
  16400. (*reinterpret_cast<T5*>(data)) = t5; data += sizeof(T5);
  16401. return data;
  16402. }
  16403. template <typename T1, typename T2, typename T3, typename T4>
  16404. inline unsigned char* write_pod(unsigned char* data,
  16405. const T1& t1, const T2& t2, const T3& t3, const T4& t4)
  16406. {
  16407. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16408. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16409. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16410. (*reinterpret_cast<T4*>(data)) = t4; data += sizeof(T4);
  16411. return data;
  16412. }
  16413. template <typename T1, typename T2, typename T3>
  16414. inline unsigned char* write_pod(unsigned char* data,
  16415. const T1& t1, const T2& t2, const T3& t3)
  16416. {
  16417. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16418. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16419. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16420. return data;
  16421. }
  16422. template <typename T1, typename T2>
  16423. inline unsigned char* write_pod(unsigned char* data,
  16424. const T1& t1, const T2& t2)
  16425. {
  16426. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16427. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16428. return data;
  16429. }
  16430. template <typename T1>
  16431. inline unsigned char* write_pod(unsigned char* data,
  16432. const T1& t1)
  16433. {
  16434. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16435. return data;
  16436. }
  16437. template <typename T, std::size_t N>
  16438. inline unsigned char* write_pod(unsigned char* data, const T (&t)[N])
  16439. {
  16440. T* ptr = reinterpret_cast<T*>(data);
  16441. std::copy(t,t + N,ptr);
  16442. return data + (N * sizeof(T));
  16443. }
  16444. template <typename T,
  16445. typename Allocator,
  16446. template <typename,typename> class Sequence>
  16447. inline unsigned char* write_pod(unsigned char* data,
  16448. const Sequence<T,Allocator>& sequence)
  16449. {
  16450. T* ptr = reinterpret_cast<T>(data);
  16451. std::copy(sequence.begin(),sequence.end(),ptr);
  16452. return data + (sequence.size() * sizeof(T));
  16453. }
  16454. template <typename T,
  16455. typename Comparator,
  16456. typename Allocator>
  16457. inline unsigned char* write_pod(unsigned char* data,
  16458. const std::set<T,Comparator,Allocator>& set)
  16459. {
  16460. T* ptr = reinterpret_cast<T>(data);
  16461. std::copy(set.begin(),set.end(),ptr);
  16462. return data + (set.size() * sizeof(T));
  16463. }
  16464. template <typename T,
  16465. typename Comparator,
  16466. typename Allocator>
  16467. inline unsigned char* write_pod(unsigned char* data,
  16468. const std::multiset<T,Comparator,Allocator>& multiset)
  16469. {
  16470. T* ptr = reinterpret_cast<T>(data);
  16471. std::copy(multiset.begin(),multiset.end(),ptr);
  16472. return data + (multiset.size() * sizeof(T));
  16473. }
  16474. class string_condition
  16475. {
  16476. private:
  16477. typedef const unsigned char* itr_type;
  16478. inline bool condition_equal(const itr_type begin, const itr_type end) const
  16479. {
  16480. if (s.size() == static_cast<std::size_t>(std::distance(begin,end)))
  16481. {
  16482. return std::equal(s_begin,s_end,begin);
  16483. }
  16484. else
  16485. return false;
  16486. }
  16487. inline bool condition_notequal(const itr_type begin, const itr_type end) const
  16488. {
  16489. if (s.size() == static_cast<std::size_t>(std::distance(begin,end)))
  16490. {
  16491. return !std::equal(s_begin,s_end,begin);
  16492. }
  16493. else
  16494. return true;
  16495. }
  16496. inline bool condition_like(const itr_type begin, const itr_type end) const
  16497. {
  16498. return match(s_begin,s_end,begin,end,(unsigned char)'*',(unsigned char)'?');
  16499. }
  16500. inline bool condition_begins_with(const itr_type begin, const itr_type end) const
  16501. {
  16502. if (s.size() == static_cast<std::size_t>(std::distance(begin,end)))
  16503. {
  16504. return strtk::begins_with(s_begin,s_end,begin,end);
  16505. }
  16506. else
  16507. return false;
  16508. }
  16509. inline bool condition_ends_with(const itr_type begin, const itr_type end) const
  16510. {
  16511. if (s.size() == static_cast<std::size_t>(std::distance(begin,end)))
  16512. {
  16513. return strtk::ends_with(s_begin,s_end,begin,end);
  16514. }
  16515. else
  16516. return false;
  16517. }
  16518. inline bool condition_within(const itr_type begin, const itr_type end) const
  16519. {
  16520. if (s.size() <= static_cast<std::size_t>(std::distance(begin,end)))
  16521. {
  16522. return (end != std::search(begin,end,s_begin,s_end));
  16523. }
  16524. else
  16525. return false;
  16526. }
  16527. inline bool condition_notwithin(const itr_type begin, const itr_type end) const
  16528. {
  16529. if (s.size() <= static_cast<std::size_t>(std::distance(begin,end)))
  16530. {
  16531. return (end == std::search(begin,end,s_begin,s_end));
  16532. }
  16533. else
  16534. return true;
  16535. }
  16536. typedef bool (string_condition::*condition_method)(const itr_type begin, const itr_type end) const;
  16537. public:
  16538. enum condition_type
  16539. {
  16540. equal = 0,
  16541. notequal = 1,
  16542. like = 2,
  16543. begins_with = 4,
  16544. ends_with = 8,
  16545. within = 16,
  16546. notwithin = 32
  16547. };
  16548. inline explicit string_condition(condition_type cond_type, const std::string& str)
  16549. : cond_type_(cond_type),
  16550. s(str),
  16551. s_begin(reinterpret_cast<const unsigned char*>(s.data())),
  16552. s_end(reinterpret_cast<const unsigned char*>(s.data() + str.size())),
  16553. condition_method_(0)
  16554. {
  16555. switch (cond_type)
  16556. {
  16557. case equal : condition_method_ = &string_condition::condition_equal;
  16558. break;
  16559. case notequal : condition_method_ = &string_condition::condition_notequal;
  16560. break;
  16561. case like : condition_method_ = &string_condition::condition_like;
  16562. break;
  16563. case begins_with : condition_method_ = &string_condition::condition_begins_with;
  16564. break;
  16565. case ends_with : condition_method_ = &string_condition::condition_ends_with;
  16566. break;
  16567. case within : condition_method_ = &string_condition::condition_within;
  16568. break;
  16569. case notwithin : condition_method_ = &string_condition::condition_notwithin;
  16570. break;
  16571. }
  16572. }
  16573. template <typename Iterator>
  16574. bool operator()(const Iterator begin, const Iterator end)
  16575. {
  16576. return ((*this).*condition_method_)(begin,end);
  16577. }
  16578. bool operator()(const std::string& str)
  16579. {
  16580. return operator()(reinterpret_cast<const unsigned char*>(str.data()),
  16581. reinterpret_cast<const unsigned char*>(str.data() + str.size()));
  16582. }
  16583. private:
  16584. condition_type cond_type_;
  16585. std::string s;
  16586. const unsigned char* s_begin;
  16587. const unsigned char* s_end;
  16588. condition_method condition_method_;
  16589. };
  16590. namespace trie
  16591. {
  16592. template <typename KeyIterator, typename ValueType>
  16593. class prefix
  16594. {
  16595. template <typename Iterator,
  16596. typename Value,
  16597. typename KeyValue = typename std::iterator_traits<Iterator>::value_type>
  16598. struct node
  16599. {
  16600. public:
  16601. typedef KeyValue key_value_t;
  16602. typedef Value value_t;
  16603. typedef node<Iterator,Value,KeyValue> node_t;
  16604. typedef node_t* node_ptr;
  16605. typedef const node_ptr const_node_ptr;
  16606. typedef std::vector<node_ptr> node_list_t;
  16607. typedef typename node_list_t::const_iterator node_list_iterator;
  16608. explicit node(const key_value_t& key_value)
  16609. : key_value_(key_value),
  16610. value_holder_(false)
  16611. {}
  16612. node(const key_value_t& key_value, const value_t& v)
  16613. : key_value_(key_value),
  16614. value_holder_(true),
  16615. value_(v)
  16616. {}
  16617. ~node()
  16618. {
  16619. if (!node_list_.empty())
  16620. {
  16621. node_list_iterator itr = node_list_.begin();
  16622. node_list_iterator end = node_list_.end();
  16623. while (end != itr)
  16624. {
  16625. delete (*itr);
  16626. ++itr;
  16627. }
  16628. }
  16629. }
  16630. inline node_ptr get_node(const key_value_t& key_value)
  16631. {
  16632. if (node_list_.empty())
  16633. return 0;
  16634. node_list_iterator itr = node_list_.begin();
  16635. const node_list_iterator end = node_list_.end();
  16636. while (end != itr)
  16637. {
  16638. if (key_value == (*itr)->key_value_)
  16639. return (*itr);
  16640. else
  16641. ++itr;
  16642. }
  16643. return 0;
  16644. }
  16645. inline void assign_value(const value_t& v)
  16646. {
  16647. value_ = v;
  16648. value_holder_ = true;
  16649. }
  16650. inline void add_node(node_ptr n)
  16651. {
  16652. node_list_.push_back(n);
  16653. }
  16654. inline bool value_holder() const
  16655. {
  16656. return value_holder_;
  16657. }
  16658. inline const value_t& value() const
  16659. {
  16660. return value_;
  16661. }
  16662. inline const key_value_t& key() const
  16663. {
  16664. return key_value_;
  16665. }
  16666. private:
  16667. node(const node_t& n);
  16668. node_t& operator=(const node_t& n);
  16669. key_value_t key_value_;
  16670. bool value_holder_;
  16671. value_t value_;
  16672. node_list_t node_list_;
  16673. };
  16674. public:
  16675. //typedef KeyIterator key_iterator_t;
  16676. typedef typename std::iterator_traits<KeyIterator>::value_type key_value_t;
  16677. typedef ValueType value_t;
  16678. typedef node<KeyIterator,value_t> node_t;
  16679. typedef node_t* node_ptr;
  16680. prefix()
  16681. : head_(0)
  16682. {}
  16683. template <typename key_iterator_t>
  16684. inline void insert(const key_iterator_t begin,
  16685. const key_iterator_t end,
  16686. const value_t& v)
  16687. {
  16688. if (0 == std::distance(begin,end))
  16689. return;
  16690. key_iterator_t itr = begin;
  16691. key_value_t key = (*itr);
  16692. node_ptr parent = 0;
  16693. node_ptr next_node = 0;
  16694. node_ptr n = head_ = ((0 == head_) ? new node_t(*itr) : head_);
  16695. while (end != itr)
  16696. {
  16697. key = (*itr);
  16698. if (0 == (next_node = n->get_node(key)))
  16699. {
  16700. n->add_node(next_node = new node_t(key));
  16701. }
  16702. parent = n;
  16703. n = next_node;
  16704. ++itr;
  16705. }
  16706. parent->assign_value(v);
  16707. }
  16708. template <typename key_iterator_t>
  16709. inline bool find(const key_iterator_t begin,
  16710. const key_iterator_t end,
  16711. value_t& v) const
  16712. {
  16713. if ((0 == head_) || (0 == std::distance(begin,end)))
  16714. return false;
  16715. key_iterator_t itr = begin;
  16716. node_ptr parent = head_;
  16717. node_ptr n = head_;
  16718. while (end != itr)
  16719. {
  16720. node_ptr next_node = n->get_node(*itr);
  16721. if (0 == next_node)
  16722. return false;
  16723. parent = n;
  16724. n = next_node;
  16725. ++itr;
  16726. }
  16727. if (!parent->value_holder())
  16728. return false;
  16729. v = parent->value();
  16730. return true;
  16731. }
  16732. template <typename key_iterator_t>
  16733. inline bool find_prefix(const key_iterator_t begin, const key_iterator_t end) const
  16734. {
  16735. if ((0 == head_) || (0 == std::distance(begin,end)))
  16736. return false;
  16737. key_iterator_t itr = begin;
  16738. node_ptr n = head_;
  16739. while (end != itr)
  16740. {
  16741. if (0 == (n = n->get_node(*itr)))
  16742. return false;
  16743. ++itr;
  16744. }
  16745. return true;
  16746. }
  16747. ~prefix()
  16748. {
  16749. delete head_;
  16750. }
  16751. private:
  16752. node_ptr head_;
  16753. };
  16754. template <typename Value>
  16755. inline void insert(prefix<std::string::const_iterator,Value>& trie,
  16756. const std::string& key,
  16757. const Value& value = Value(0))
  16758. {
  16759. trie.insert(key.begin(),key.end(),value);
  16760. }
  16761. template <typename Value>
  16762. inline void insert(prefix<std::string::iterator,Value>& trie,
  16763. const char* key,
  16764. const Value& value = Value(0))
  16765. {
  16766. insert_into_trie(trie,std::string(key),value);
  16767. }
  16768. template <typename Value>
  16769. inline bool find(prefix<std::string::const_iterator,Value>& trie,
  16770. const std::string& key,
  16771. Value& v)
  16772. {
  16773. return trie.find(key.begin(),key.end(),v);
  16774. }
  16775. template <typename Value>
  16776. inline bool find(prefix<std::string::const_iterator,Value>& trie,
  16777. const char* key,
  16778. Value& v)
  16779. {
  16780. return find_prefix(trie,std::string(key),v);
  16781. }
  16782. template <typename Value>
  16783. inline bool find_prefix(prefix<std::string::const_iterator,Value>& trie,
  16784. const std::string& key)
  16785. {
  16786. return trie.find_prefix(key.begin(),key.end());
  16787. }
  16788. template <typename Value>
  16789. inline bool find_prefix(prefix<std::string::const_iterator,Value>& trie,
  16790. const char* key)
  16791. {
  16792. return find_prefix(trie,std::string(key));
  16793. }
  16794. } // namespace trie
  16795. template <typename ValueType, typename KeyIterator = std::string::const_iterator>
  16796. struct prefix_trie
  16797. {
  16798. typedef trie::prefix<KeyIterator,ValueType> type;
  16799. typedef trie::prefix<KeyIterator,ValueType> std_string;
  16800. typedef trie::prefix<char*,ValueType> char_ptr;
  16801. typedef trie::prefix<const char*,ValueType> const_char_ptr;
  16802. typedef trie::prefix<unsigned char*,ValueType> uchar_ptr;
  16803. typedef trie::prefix<const unsigned char*,ValueType> const_uchar_ptr;
  16804. };
  16805. namespace bloom
  16806. {
  16807. static const std::size_t bits_per_char = 0x08; // 8 bits in 1 char(unsigned)
  16808. static const unsigned char bit_mask[bits_per_char] = {
  16809. 0x01, //00000001
  16810. 0x02, //00000010
  16811. 0x04, //00000100
  16812. 0x08, //00001000
  16813. 0x10, //00010000
  16814. 0x20, //00100000
  16815. 0x40, //01000000
  16816. 0x80 //10000000
  16817. };
  16818. class parameters
  16819. {
  16820. public:
  16821. parameters()
  16822. : minimum_size(1),
  16823. maximum_size(std::numeric_limits<unsigned long long int>::max()),
  16824. minimum_number_of_hashes(1),
  16825. maximum_number_of_hashes(std::numeric_limits<unsigned int>::max()),
  16826. projected_element_count(10000),
  16827. false_positive_probability(1.0 / projected_element_count),
  16828. random_seed(0xA5A5A5A55A5A5A5AULL)
  16829. {}
  16830. virtual ~parameters()
  16831. {}
  16832. inline bool operator!()
  16833. {
  16834. return (minimum_size > maximum_size) ||
  16835. (minimum_number_of_hashes > maximum_number_of_hashes) ||
  16836. (minimum_number_of_hashes < 1) ||
  16837. (0 == maximum_number_of_hashes) ||
  16838. (0 == projected_element_count) ||
  16839. (false_positive_probability < 0.0) ||
  16840. (std::numeric_limits<double>::infinity() == std::abs(false_positive_probability)) ||
  16841. (0 == random_seed) ||
  16842. (0xFFFFFFFFFFFFFFFFULL == random_seed);
  16843. }
  16844. //Allowed min/max size of the bloom filter in bits
  16845. unsigned long long int minimum_size;
  16846. unsigned long long int maximum_size;
  16847. //Allowed min/max number of hash functions
  16848. unsigned int minimum_number_of_hashes;
  16849. unsigned int maximum_number_of_hashes;
  16850. //The approximate number of elements to be inserted
  16851. //into the bloom filter, should be within one order
  16852. //of magnitude. The default is 10000.
  16853. unsigned long long int projected_element_count;
  16854. //The approximate false positive probability expected
  16855. //from the bloom filter. The default is the reciprocal
  16856. //of the projected_element_count.
  16857. double false_positive_probability;
  16858. unsigned long long int random_seed;
  16859. inline bool operator()(strtk::binary::reader& reader)
  16860. {
  16861. return reader(minimum_size) &&
  16862. reader(maximum_size) &&
  16863. reader(minimum_number_of_hashes) &&
  16864. reader(maximum_number_of_hashes) &&
  16865. reader(projected_element_count) &&
  16866. reader(false_positive_probability) &&
  16867. reader(random_seed);
  16868. }
  16869. inline bool operator()(strtk::binary::writer& writer)
  16870. {
  16871. return writer(minimum_size) &&
  16872. writer(maximum_size) &&
  16873. writer(minimum_number_of_hashes) &&
  16874. writer(maximum_number_of_hashes) &&
  16875. writer(projected_element_count) &&
  16876. writer(false_positive_probability) &&
  16877. writer(random_seed);
  16878. }
  16879. struct optimal_parameters_t
  16880. {
  16881. optimal_parameters_t()
  16882. : number_of_hashes(0),
  16883. table_size(0)
  16884. {}
  16885. unsigned int number_of_hashes;
  16886. unsigned long long int table_size;
  16887. };
  16888. optimal_parameters_t optimal_parameters;
  16889. virtual bool compute_optimal_parameters()
  16890. {
  16891. /*
  16892. Note:
  16893. The following will attempt to find the number of hash functions
  16894. and minimum amount of storage bits required to construct a bloom
  16895. filter consistent with the user defined false positive probability
  16896. and estimated element insertion count.
  16897. */
  16898. if (!(*this))
  16899. return false;
  16900. double min_m = std::numeric_limits<double>::infinity();
  16901. double min_k = 0.0;
  16902. double curr_m = 0.0;
  16903. double k = 1.0;
  16904. while (k < 1000.0)
  16905. {
  16906. double numerator = -k * projected_element_count;
  16907. double denominator = std::log(1.0 - std::pow(false_positive_probability, 1.0 / k));
  16908. curr_m = numerator / denominator;
  16909. if (curr_m < min_m)
  16910. {
  16911. min_m = curr_m;
  16912. min_k = k;
  16913. }
  16914. k += 1.0;
  16915. }
  16916. optimal_parameters_t& optp = optimal_parameters;
  16917. optp.number_of_hashes = static_cast<unsigned int>(min_k);
  16918. optp.table_size = static_cast<unsigned long long int>(min_m);
  16919. optp.table_size += (((optp.table_size % bits_per_char) != 0) ? (bits_per_char - (optp.table_size % bits_per_char)) : 0);
  16920. if (optp.number_of_hashes < minimum_number_of_hashes)
  16921. optp.number_of_hashes = minimum_number_of_hashes;
  16922. else if (optp.number_of_hashes > maximum_number_of_hashes)
  16923. optp.number_of_hashes = maximum_number_of_hashes;
  16924. if (optp.table_size < minimum_size)
  16925. optp.table_size = minimum_size;
  16926. else if (optp.table_size > maximum_size)
  16927. optp.table_size = maximum_size;
  16928. return true;
  16929. }
  16930. };
  16931. class filter
  16932. {
  16933. protected:
  16934. typedef unsigned int bloom_type;
  16935. typedef unsigned char cell_type;
  16936. public:
  16937. filter()
  16938. : bit_table_(0),
  16939. salt_count_(0),
  16940. table_size_(0),
  16941. raw_table_size_(0),
  16942. projected_element_count_(0),
  16943. inserted_element_count_(0),
  16944. random_seed_(0),
  16945. desired_false_positive_probability_(0.0)
  16946. {}
  16947. filter(const parameters& p)
  16948. : bit_table_(0),
  16949. projected_element_count_(p.projected_element_count),
  16950. inserted_element_count_(0),
  16951. random_seed_((p.random_seed * 0xA5A5A5A5) + 1),
  16952. desired_false_positive_probability_(p.false_positive_probability)
  16953. {
  16954. salt_count_ = p.optimal_parameters.number_of_hashes;
  16955. table_size_ = p.optimal_parameters.table_size;
  16956. generate_unique_salt();
  16957. raw_table_size_ = table_size_ / bits_per_char;
  16958. bit_table_ = new cell_type[static_cast<std::size_t>(raw_table_size_)];
  16959. std::fill_n(bit_table_,raw_table_size_,0x00);
  16960. }
  16961. filter(const filter& filter)
  16962. {
  16963. this->operator=(filter);
  16964. }
  16965. inline bool operator == (const filter& f) const
  16966. {
  16967. if (this != &f)
  16968. {
  16969. return
  16970. (salt_count_ == f.salt_count_) &&
  16971. (table_size_ == f.table_size_) &&
  16972. (raw_table_size_ == f.raw_table_size_) &&
  16973. (projected_element_count_ == f.projected_element_count_) &&
  16974. (inserted_element_count_ == f.inserted_element_count_) &&
  16975. (random_seed_ == f.random_seed_) &&
  16976. (desired_false_positive_probability_ == f.desired_false_positive_probability_) &&
  16977. (salt_ == f.salt_) &&
  16978. std::equal(f.bit_table_,f.bit_table_ + raw_table_size_,bit_table_);
  16979. }
  16980. else
  16981. return true;
  16982. }
  16983. inline bool operator != (const filter& f) const
  16984. {
  16985. return !operator==(f);
  16986. }
  16987. inline filter& operator = (const filter& f)
  16988. {
  16989. if (this != &f)
  16990. {
  16991. salt_count_ = f.salt_count_;
  16992. table_size_ = f.table_size_;
  16993. raw_table_size_ = f.raw_table_size_;
  16994. projected_element_count_ = f.projected_element_count_;
  16995. inserted_element_count_ = f.inserted_element_count_;
  16996. random_seed_ = f.random_seed_;
  16997. desired_false_positive_probability_ = f.desired_false_positive_probability_;
  16998. delete[] bit_table_;
  16999. bit_table_ = new cell_type[static_cast<std::size_t>(raw_table_size_)];
  17000. std::copy(f.bit_table_,f.bit_table_ + raw_table_size_,bit_table_);
  17001. salt_ = f.salt_;
  17002. }
  17003. return *this;
  17004. }
  17005. virtual ~filter()
  17006. {
  17007. delete[] bit_table_;
  17008. }
  17009. inline bool operator!() const
  17010. {
  17011. return (0 == table_size_);
  17012. }
  17013. inline void clear()
  17014. {
  17015. std::fill_n(bit_table_,raw_table_size_,0x00);
  17016. inserted_element_count_ = 0;
  17017. }
  17018. inline void insert(const unsigned char* key_begin, const std::size_t& length)
  17019. {
  17020. std::size_t bit_index = 0;
  17021. std::size_t bit = 0;
  17022. for (std::size_t i = 0; i < salt_.size(); ++i)
  17023. {
  17024. compute_indices(hash_ap(key_begin,length,salt_[i]),bit_index,bit);
  17025. bit_table_[bit_index / bits_per_char] |= bit_mask[bit];
  17026. }
  17027. ++inserted_element_count_;
  17028. }
  17029. template <typename T>
  17030. inline void insert(const T& t)
  17031. {
  17032. // Note: T must be a C++ POD type.
  17033. insert(reinterpret_cast<const unsigned char*>(&t),sizeof(T));
  17034. }
  17035. inline void insert(const std::string& key)
  17036. {
  17037. insert(reinterpret_cast<const unsigned char*>(key.data()),key.size());
  17038. }
  17039. inline void insert(const char* data, const std::size_t& length)
  17040. {
  17041. insert(reinterpret_cast<const unsigned char*>(data),length);
  17042. }
  17043. template <typename InputIterator>
  17044. inline void insert(const InputIterator begin, const InputIterator end)
  17045. {
  17046. InputIterator itr = begin;
  17047. while (end != itr)
  17048. {
  17049. insert(*(itr++));
  17050. }
  17051. }
  17052. inline virtual bool contains(const unsigned char* key_begin, const std::size_t length) const
  17053. {
  17054. std::size_t bit_index = 0;
  17055. std::size_t bit = 0;
  17056. for (std::size_t i = 0; i < salt_.size(); ++i)
  17057. {
  17058. compute_indices(hash_ap(key_begin,length,salt_[i]),bit_index,bit);
  17059. if ((bit_table_[bit_index / bits_per_char] & bit_mask[bit]) != bit_mask[bit])
  17060. {
  17061. return false;
  17062. }
  17063. }
  17064. return true;
  17065. }
  17066. template <typename T>
  17067. inline bool contains(const T& t) const
  17068. {
  17069. return contains(reinterpret_cast<const unsigned char*>(&t),static_cast<std::size_t>(sizeof(T)));
  17070. }
  17071. inline bool contains(const std::string& key) const
  17072. {
  17073. return contains(reinterpret_cast<const unsigned char*>(key.data()),key.size());
  17074. }
  17075. inline bool contains(const char* data, const std::size_t& length) const
  17076. {
  17077. return contains(reinterpret_cast<const unsigned char*>(data),length);
  17078. }
  17079. template <typename InputIterator>
  17080. inline InputIterator contains_all(const InputIterator begin, const InputIterator end) const
  17081. {
  17082. InputIterator itr = begin;
  17083. while (end != itr)
  17084. {
  17085. if (!contains(*itr))
  17086. {
  17087. return itr;
  17088. }
  17089. ++itr;
  17090. }
  17091. return end;
  17092. }
  17093. template <typename InputIterator>
  17094. inline InputIterator contains_none(const InputIterator begin, const InputIterator end) const
  17095. {
  17096. InputIterator itr = begin;
  17097. while (end != itr)
  17098. {
  17099. if (contains(*itr))
  17100. {
  17101. return itr;
  17102. }
  17103. ++itr;
  17104. }
  17105. return end;
  17106. }
  17107. inline virtual unsigned long long int size() const
  17108. {
  17109. return table_size_;
  17110. }
  17111. inline std::size_t element_count() const
  17112. {
  17113. return inserted_element_count_;
  17114. }
  17115. inline double effective_fpp() const
  17116. {
  17117. /*
  17118. Note:
  17119. The effective false positive probability is calculated using the
  17120. designated table size and hash function count in conjunction with
  17121. the current number of inserted elements - not the user defined
  17122. predicated/expected number of inserted elements.
  17123. */
  17124. return std::pow(1.0 - std::exp(-1.0 * salt_.size() * inserted_element_count_ / size()), 1.0 * salt_.size());
  17125. }
  17126. inline filter& operator &= (const filter& f)
  17127. {
  17128. /* intersection */
  17129. if (
  17130. (salt_count_ == f.salt_count_) &&
  17131. (table_size_ == f.table_size_) &&
  17132. (random_seed_ == f.random_seed_)
  17133. )
  17134. {
  17135. for (std::size_t i = 0; i < raw_table_size_; ++i)
  17136. {
  17137. bit_table_[i] &= f.bit_table_[i];
  17138. }
  17139. }
  17140. return *this;
  17141. }
  17142. inline filter& operator |= (const filter& f)
  17143. {
  17144. /* union */
  17145. if (
  17146. (salt_count_ == f.salt_count_) &&
  17147. (table_size_ == f.table_size_) &&
  17148. (random_seed_ == f.random_seed_)
  17149. )
  17150. {
  17151. for (std::size_t i = 0; i < raw_table_size_; ++i)
  17152. {
  17153. bit_table_[i] |= f.bit_table_[i];
  17154. }
  17155. }
  17156. return *this;
  17157. }
  17158. inline filter& operator ^= (const filter& f)
  17159. {
  17160. /* difference */
  17161. if (
  17162. (salt_count_ == f.salt_count_) &&
  17163. (table_size_ == f.table_size_) &&
  17164. (random_seed_ == f.random_seed_)
  17165. )
  17166. {
  17167. for (std::size_t i = 0; i < raw_table_size_; ++i)
  17168. {
  17169. bit_table_[i] ^= f.bit_table_[i];
  17170. }
  17171. }
  17172. return *this;
  17173. }
  17174. inline const cell_type* table() const
  17175. {
  17176. return bit_table_;
  17177. }
  17178. inline bool write_to_file(const std::string& file_name) const
  17179. {
  17180. if (0 == table_size_)
  17181. return false;
  17182. const std::size_t buffer_size = sizeof( salt_count_) +
  17183. sizeof( table_size_) +
  17184. sizeof( raw_table_size_) +
  17185. sizeof( projected_element_count_) +
  17186. sizeof( inserted_element_count_) +
  17187. sizeof( random_seed_) +
  17188. sizeof(desired_false_positive_probability_) +
  17189. salt_count_ * sizeof( bloom_type) +
  17190. static_cast<std::size_t>(raw_table_size_) *
  17191. sizeof(cell_type) +
  17192. 64; // handle array sizes etc.
  17193. std::ofstream ostream(file_name.c_str(),std::ios::binary);
  17194. if (!ostream)
  17195. return false;
  17196. unsigned char* buffer = new unsigned char[buffer_size];
  17197. strtk::binary::writer writer(buffer,buffer_size);
  17198. writer.reset(true);
  17199. bool result = writer(salt_count_) &&
  17200. writer(table_size_) &&
  17201. writer(raw_table_size_) &&
  17202. writer(projected_element_count_) &&
  17203. writer(inserted_element_count_) &&
  17204. writer(random_seed_) &&
  17205. writer(desired_false_positive_probability_) &&
  17206. writer(salt_) &&
  17207. writer(bit_table_,raw_table_size_);
  17208. if (result)
  17209. {
  17210. writer(ostream);
  17211. }
  17212. ostream.close();
  17213. delete[] buffer;
  17214. return result;
  17215. }
  17216. inline bool read_from_file(const std::string& file_name)
  17217. {
  17218. std::ifstream istream(file_name.c_str(),std::ios::binary);
  17219. if (!istream)
  17220. return false;
  17221. salt_count_ = 0;
  17222. table_size_ = 0;
  17223. raw_table_size_ = 0;
  17224. projected_element_count_ = 0;
  17225. inserted_element_count_ = 0;
  17226. random_seed_ = 0;
  17227. desired_false_positive_probability_ = 0.0;
  17228. salt_.clear();
  17229. if (0 != bit_table_)
  17230. delete [] bit_table_;
  17231. bit_table_= 0;
  17232. const std::size_t buffer_size = strtk::fileio::file_size(file_name);
  17233. unsigned char* buffer = new unsigned char[buffer_size];
  17234. strtk::binary::reader reader(buffer,buffer_size);
  17235. reader.reset(true);
  17236. reader(istream,buffer_size);
  17237. istream.close();
  17238. bool result = reader(salt_count_) &&
  17239. reader(table_size_) &&
  17240. reader(raw_table_size_) &&
  17241. reader(projected_element_count_) &&
  17242. reader(inserted_element_count_) &&
  17243. reader(random_seed_) &&
  17244. reader(desired_false_positive_probability_) &&
  17245. reader(salt_) &&
  17246. reader(bit_table_,raw_table_size_);
  17247. delete[] buffer;
  17248. return result;
  17249. }
  17250. inline std::size_t hash_count()
  17251. {
  17252. return salt_.size();
  17253. }
  17254. protected:
  17255. inline virtual void compute_indices(const bloom_type& hash, std::size_t& bit_index, std::size_t& bit) const
  17256. {
  17257. bit_index = static_cast<std::size_t>(hash % table_size_);
  17258. bit = bit_index % bits_per_char;
  17259. }
  17260. void generate_unique_salt()
  17261. {
  17262. /*
  17263. Note:
  17264. A distinct hash function need not be implementation-wise
  17265. distinct. In the current implementation "seeding" a common
  17266. hash function with different values seems to be adequate.
  17267. */
  17268. const unsigned int predef_salt_count = 128;
  17269. static const bloom_type predef_salt[predef_salt_count] =
  17270. {
  17271. 0xAAAAAAAA, 0x55555555, 0x33333333, 0xCCCCCCCC,
  17272. 0x66666666, 0x99999999, 0xB5B5B5B5, 0x4B4B4B4B,
  17273. 0xAA55AA55, 0x55335533, 0x33CC33CC, 0xCC66CC66,
  17274. 0x66996699, 0x99B599B5, 0xB54BB54B, 0x4BAA4BAA,
  17275. 0xAA33AA33, 0x55CC55CC, 0x33663366, 0xCC99CC99,
  17276. 0x66B566B5, 0x994B994B, 0xB5AAB5AA, 0xAAAAAA33,
  17277. 0x555555CC, 0x33333366, 0xCCCCCC99, 0x666666B5,
  17278. 0x9999994B, 0xB5B5B5AA, 0xFFFFFFFF, 0xFFFF0000,
  17279. 0xB823D5EB, 0xC1191CDF, 0xF623AEB3, 0xDB58499F,
  17280. 0xC8D42E70, 0xB173F616, 0xA91A5967, 0xDA427D63,
  17281. 0xB1E8A2EA, 0xF6C0D155, 0x4909FEA3, 0xA68CC6A7,
  17282. 0xC395E782, 0xA26057EB, 0x0CD5DA28, 0x467C5492,
  17283. 0xF15E6982, 0x61C6FAD3, 0x9615E352, 0x6E9E355A,
  17284. 0x689B563E, 0x0C9831A8, 0x6753C18B, 0xA622689B,
  17285. 0x8CA63C47, 0x42CC2884, 0x8E89919B, 0x6EDBD7D3,
  17286. 0x15B6796C, 0x1D6FDFE4, 0x63FF9092, 0xE7401432,
  17287. 0xEFFE9412, 0xAEAEDF79, 0x9F245A31, 0x83C136FC,
  17288. 0xC3DA4A8C, 0xA5112C8C, 0x5271F491, 0x9A948DAB,
  17289. 0xCEE59A8D, 0xB5F525AB, 0x59D13217, 0x24E7C331,
  17290. 0x697C2103, 0x84B0A460, 0x86156DA9, 0xAEF2AC68,
  17291. 0x23243DA5, 0x3F649643, 0x5FA495A8, 0x67710DF8,
  17292. 0x9A6C499E, 0xDCFB0227, 0x46A43433, 0x1832B07A,
  17293. 0xC46AFF3C, 0xB9C8FFF0, 0xC9500467, 0x34431BDF,
  17294. 0xB652432B, 0xE367F12B, 0x427F4C1B, 0x224C006E,
  17295. 0x2E7E5A89, 0x96F99AA5, 0x0BEB452A, 0x2FD87C39,
  17296. 0x74B2E1FB, 0x222EFD24, 0xF357F60C, 0x440FCB1E,
  17297. 0x8BBE030F, 0x6704DC29, 0x1144D12F, 0x948B1355,
  17298. 0x6D8FD7E9, 0x1C11A014, 0xADD1592F, 0xFB3C712E,
  17299. 0xFC77642F, 0xF9C4CE8C, 0x31312FB9, 0x08B0DD79,
  17300. 0x318FA6E7, 0xC040D23D, 0xC0589AA7, 0x0CA5C075,
  17301. 0xF874B172, 0x0CF914D5, 0x784D3280, 0x4E8CFEBC,
  17302. 0xC569F575, 0xCDB2A091, 0x2CC016B4, 0x5C5F4421
  17303. };
  17304. if (salt_count_ <= predef_salt_count)
  17305. {
  17306. std::copy(predef_salt,
  17307. predef_salt + salt_count_,
  17308. std::back_inserter(salt_));
  17309. for (unsigned int i = 0; i < salt_.size(); ++i)
  17310. {
  17311. /*
  17312. Note:
  17313. This is done to integrate the user defined random seed,
  17314. so as to allow for the generation of unique bloom filter
  17315. instances.
  17316. */
  17317. salt_[i] = salt_[i] * salt_[(i + 3) % salt_.size()] + static_cast<bloom_type>(random_seed_);
  17318. }
  17319. }
  17320. else
  17321. {
  17322. std::copy(predef_salt,predef_salt + predef_salt_count,std::back_inserter(salt_));
  17323. srand(static_cast<unsigned int>(random_seed_));
  17324. while (salt_.size() < salt_count_)
  17325. {
  17326. bloom_type current_salt = static_cast<bloom_type>(rand()) * static_cast<bloom_type>(rand());
  17327. if (0 == current_salt) continue;
  17328. if (salt_.end() == std::find(salt_.begin(), salt_.end(), current_salt))
  17329. {
  17330. salt_.push_back(current_salt);
  17331. }
  17332. }
  17333. }
  17334. }
  17335. inline bloom_type hash_ap(const unsigned char* begin, std::size_t remaining_length, bloom_type hash) const
  17336. {
  17337. const unsigned char* itr = begin;
  17338. unsigned int loop = 0;
  17339. while (remaining_length >= 8)
  17340. {
  17341. const unsigned int& i1 = *(reinterpret_cast<const unsigned int*>(itr)); itr += sizeof(unsigned int);
  17342. const unsigned int& i2 = *(reinterpret_cast<const unsigned int*>(itr)); itr += sizeof(unsigned int);
  17343. hash ^= (hash << 7) ^ i1 * (hash >> 3) ^
  17344. (~((hash << 11) + (i2 ^ (hash >> 5))));
  17345. remaining_length -= 8;
  17346. }
  17347. while (remaining_length >= 4)
  17348. {
  17349. const unsigned int& i = *(reinterpret_cast<const unsigned int*>(itr));
  17350. if (loop & 0x01)
  17351. hash ^= (hash << 7) ^ i * (hash >> 3);
  17352. else
  17353. hash ^= (~((hash << 11) + (i ^ (hash >> 5))));
  17354. ++loop;
  17355. remaining_length -= 4;
  17356. itr += sizeof(unsigned int);
  17357. }
  17358. while (remaining_length >= 2)
  17359. {
  17360. const unsigned short& i = *(reinterpret_cast<const unsigned short*>(itr));
  17361. if (loop & 0x01)
  17362. hash ^= (hash << 7) ^ i * (hash >> 3);
  17363. else
  17364. hash ^= (~((hash << 11) + (i ^ (hash >> 5))));
  17365. ++loop;
  17366. remaining_length -= 2;
  17367. itr += sizeof(unsigned short);
  17368. }
  17369. if (remaining_length)
  17370. hash += ((*itr) ^ (hash * 0x5A5A5A5A));
  17371. else if (loop < 2)
  17372. hash += ((hash + 1) * 0x5A5A5A5A);
  17373. return hash;
  17374. }
  17375. std::vector<bloom_type> salt_;
  17376. unsigned char* bit_table_;
  17377. unsigned int salt_count_;
  17378. unsigned long long int table_size_;
  17379. unsigned long long int raw_table_size_;
  17380. unsigned long long int projected_element_count_;
  17381. unsigned int inserted_element_count_;
  17382. unsigned long long int random_seed_;
  17383. double desired_false_positive_probability_;
  17384. };
  17385. inline filter operator & (const filter& a, const filter& b)
  17386. {
  17387. filter result = a;
  17388. result &= b;
  17389. return result;
  17390. }
  17391. inline filter operator | (const filter& a, const filter& b)
  17392. {
  17393. filter result = a;
  17394. result |= b;
  17395. return result;
  17396. }
  17397. inline filter operator ^ (const filter& a, const filter& b)
  17398. {
  17399. filter result = a;
  17400. result ^= b;
  17401. return result;
  17402. }
  17403. class compressible_filter : public filter
  17404. {
  17405. public:
  17406. compressible_filter(const parameters& p)
  17407. : filter(p)
  17408. {
  17409. size_list.push_back(table_size_);
  17410. }
  17411. inline virtual unsigned long long int size() const
  17412. {
  17413. return size_list.back();
  17414. }
  17415. inline bool compress(const double& percentage)
  17416. {
  17417. if ((0.0 >= percentage) || (percentage >= 100.0))
  17418. {
  17419. return false;
  17420. }
  17421. unsigned long long int original_table_size = size_list.back();
  17422. unsigned long long int new_table_size = static_cast<unsigned long long int>((size_list.back() * (1.0 - (percentage / 100.0))));
  17423. new_table_size -= (((new_table_size % bits_per_char) != 0) ? (new_table_size % bits_per_char) : 0);
  17424. if ((bits_per_char > new_table_size) || (new_table_size >= original_table_size))
  17425. {
  17426. return false;
  17427. }
  17428. desired_false_positive_probability_ = effective_fpp();
  17429. cell_type* tmp = new cell_type[static_cast<std::size_t>(new_table_size / bits_per_char)];
  17430. std::copy(bit_table_, bit_table_ + (new_table_size / bits_per_char), tmp);
  17431. cell_type* itr = bit_table_ + (new_table_size / bits_per_char);
  17432. cell_type* end = bit_table_ + (original_table_size / bits_per_char);
  17433. cell_type* itr_tmp = tmp;
  17434. while (end != itr)
  17435. {
  17436. *(itr_tmp++) |= (*itr++);
  17437. }
  17438. delete[] bit_table_;
  17439. bit_table_ = tmp;
  17440. size_list.push_back(new_table_size);
  17441. return true;
  17442. }
  17443. private:
  17444. inline virtual void compute_indices(const bloom_type& hash, std::size_t& bit_index, std::size_t& bit) const
  17445. {
  17446. bit_index = hash;
  17447. for (std::size_t i = 0; i < size_list.size(); ++i)
  17448. {
  17449. bit_index %= size_list[i];
  17450. }
  17451. bit = bit_index % bits_per_char;
  17452. }
  17453. std::vector<unsigned long long int> size_list;
  17454. };
  17455. }
  17456. namespace details
  17457. {
  17458. inline void compute_pod_hash(const char data[], unsigned int& hash)
  17459. {
  17460. hash ^= ((hash << 7) ^ data[0] * (hash >> 3));
  17461. hash ^= ~((hash << 11) + (data[1] ^ (hash >> 5)));
  17462. }
  17463. inline void compute_pod_hash(const unsigned char data[], unsigned int& hash)
  17464. {
  17465. hash ^= ((hash << 7) ^ data[0] * (hash >> 3));
  17466. hash ^= ~((hash << 11) + (data[1] ^ (hash >> 5)));
  17467. }
  17468. inline void compute_pod_hash(const int& data, unsigned int& hash)
  17469. {
  17470. const unsigned char* itr = reinterpret_cast<const unsigned char*>(&data);
  17471. hash ^= ((hash << 7) ^ itr[0] * (hash >> 3));
  17472. hash ^= ~((hash << 11) + (itr[1] ^ (hash >> 5)));
  17473. hash ^= ((hash << 7) ^ itr[2] * (hash >> 3));
  17474. hash ^= ~((hash << 11) + (itr[3] ^ (hash >> 5)));
  17475. }
  17476. inline void compute_pod_hash(const unsigned int& data, unsigned int& hash)
  17477. {
  17478. compute_pod_hash(static_cast<int>(data),hash);
  17479. }
  17480. inline void compute_pod_hash(const unsigned long long int& data, unsigned int& hash)
  17481. {
  17482. const unsigned char* itr = reinterpret_cast<const unsigned char*>(&data);
  17483. hash ^= ((hash << 7) ^ itr[0] * (hash >> 3));
  17484. hash ^= ~((hash << 11) + (itr[1] ^ (hash >> 5)));
  17485. hash ^= ((hash << 7) ^ itr[2] * (hash >> 3));
  17486. hash ^= ~((hash << 11) + (itr[3] ^ (hash >> 5)));
  17487. hash ^= ((hash << 7) ^ itr[4] * (hash >> 3));
  17488. hash ^= ~((hash << 11) + (itr[5] ^ (hash >> 5)));
  17489. hash ^= ((hash << 7) ^ itr[6] * (hash >> 3));
  17490. hash ^= ~((hash << 11) + (itr[7] ^ (hash >> 5)));
  17491. }
  17492. inline void compute_pod_hash(const double& data, unsigned int& hash)
  17493. {
  17494. const unsigned char* itr = reinterpret_cast<const unsigned char*>(&data);
  17495. hash ^= ((hash << 7) ^ itr[0] * (hash >> 3));
  17496. hash ^= ~((hash << 11) + (itr[1] ^ (hash >> 5)));
  17497. hash ^= ((hash << 7) ^ itr[2] * (hash >> 3));
  17498. hash ^= ~((hash << 11) + (itr[3] ^ (hash >> 5)));
  17499. hash ^= ((hash << 7) ^ itr[4] * (hash >> 3));
  17500. hash ^= ~((hash << 11) + (itr[5] ^ (hash >> 5)));
  17501. hash ^= ((hash << 7) ^ itr[6] * (hash >> 3));
  17502. hash ^= ~((hash << 11) + (itr[7] ^ (hash >> 5)));
  17503. }
  17504. template <std::size_t block_size, typename Iterator>
  17505. inline void compute_block(Iterator itr, std::size_t& length, unsigned int& hash)
  17506. {
  17507. while (length >= block_size)
  17508. {
  17509. for (std::size_t i = 0; i < block_size; ++i, ++itr)
  17510. {
  17511. compute_pod_hash((*itr),hash);
  17512. }
  17513. length -= block_size;
  17514. }
  17515. }
  17516. template <std::size_t block_size>
  17517. inline void compute_block(unsigned char* itr, std::size_t& length, unsigned int& hash)
  17518. {
  17519. unsigned int local_hash = hash;
  17520. while (length >= block_size)
  17521. {
  17522. for (std::size_t i = 0; i < block_size; ++i, ++itr)
  17523. {
  17524. compute_pod_hash((*itr),local_hash);
  17525. }
  17526. length -= block_size;
  17527. }
  17528. hash = local_hash;
  17529. }
  17530. template <std::size_t block_size>
  17531. inline void compute_block(char* itr, std::size_t& length, unsigned int& hash)
  17532. {
  17533. compute_block<block_size>(reinterpret_cast<unsigned char*>(itr),length,hash);
  17534. }
  17535. static const unsigned int hash_seed = 0xAAAAAAAA;
  17536. template <typename Iterator>
  17537. inline void hash(const Iterator itr, std::size_t length, unsigned int& hash_value)
  17538. {
  17539. if (length >= 64) compute_block<64>(itr,length,hash_value);
  17540. if (length >= 32) compute_block<32>(itr,length,hash_value);
  17541. if (length >= 16) compute_block<16>(itr,length,hash_value);
  17542. if (length >= 8) compute_block< 8>(itr,length,hash_value);
  17543. if (length >= 4) compute_block< 4>(itr,length,hash_value);
  17544. if (length >= 2) compute_block< 2>(itr,length,hash_value);
  17545. if (length == 0) compute_block< 1>(itr,length,hash_value);
  17546. }
  17547. } // namespace details
  17548. template <typename Iterator>
  17549. inline unsigned int hash(const Iterator itr,
  17550. std::size_t length,
  17551. unsigned int seed = details::hash_seed)
  17552. {
  17553. unsigned int hash_value = seed;
  17554. details::hash(itr,length,hash_value);
  17555. return hash_value;
  17556. }
  17557. inline unsigned int hash(const std::string& s, unsigned int seed = details::hash_seed)
  17558. {
  17559. unsigned int hash_value = seed;
  17560. return hash(s.begin(),s.size(),hash_value);
  17561. }
  17562. template <typename T,
  17563. typename Allocator,
  17564. template <typename,typename> class Sequence>
  17565. inline unsigned int hash(const Sequence<T,Allocator>& sequence, unsigned int seed = details::hash_seed)
  17566. {
  17567. unsigned int hash_value = seed;
  17568. return hash(sequence.begin(),sequence.size(),hash_value);
  17569. }
  17570. namespace util
  17571. {
  17572. template <typename T>
  17573. class scoped_restore
  17574. {
  17575. public:
  17576. scoped_restore(T& t, const bool restore = true)
  17577. : restore_(restore),
  17578. reference_(t),
  17579. copy_(t)
  17580. {}
  17581. ~scoped_restore()
  17582. {
  17583. if (restore_)
  17584. {
  17585. reference_ = copy_;
  17586. }
  17587. }
  17588. inline bool& restore()
  17589. {
  17590. return restore_;
  17591. }
  17592. private:
  17593. bool restore_;
  17594. T& reference_;
  17595. T copy_;
  17596. };
  17597. template <typename T>
  17598. class attribute
  17599. {
  17600. public:
  17601. attribute()
  17602. : initialised_(false)
  17603. {}
  17604. attribute(const T& t)
  17605. {
  17606. assign(t);
  17607. prev_t_ = t;
  17608. }
  17609. inline attribute& operator=(const T& t)
  17610. {
  17611. prev_t_ = t_;
  17612. assign(t);
  17613. return *this;
  17614. }
  17615. inline bool operator==(const T& t)
  17616. {
  17617. return initialised_ && (t_ == t);
  17618. }
  17619. template <typename TConvertibleType>
  17620. inline bool operator!=(const TConvertibleType& t)
  17621. {
  17622. return !(operator==(t));
  17623. }
  17624. inline T& operator()()
  17625. {
  17626. return t_;
  17627. }
  17628. inline const T& operator()() const
  17629. {
  17630. return t_;
  17631. }
  17632. inline operator T() const
  17633. {
  17634. return t_;
  17635. }
  17636. inline operator T()
  17637. {
  17638. return t_;
  17639. }
  17640. inline bool initialised() const
  17641. {
  17642. return initialised_;
  17643. }
  17644. inline bool& initialised()
  17645. {
  17646. return initialised_;
  17647. }
  17648. inline bool changed() const
  17649. {
  17650. return (initialised_ && (t_ != prev_t_));
  17651. }
  17652. inline const T& value() const
  17653. {
  17654. return t_;
  17655. }
  17656. inline T& value()
  17657. {
  17658. return t_;
  17659. }
  17660. inline const T& previous() const
  17661. {
  17662. return prev_t_;
  17663. }
  17664. inline T& previous()
  17665. {
  17666. return prev_t_;
  17667. }
  17668. private:
  17669. inline void assign(const T& t)
  17670. {
  17671. t_ = t;
  17672. initialised_ = true;
  17673. }
  17674. T t_;
  17675. T prev_t_;
  17676. bool initialised_;
  17677. };
  17678. inline bool operator==(const char* s, const attribute<std::string>& attrib)
  17679. {
  17680. return attrib.value() == s;
  17681. }
  17682. inline bool operator!=(const char* s, const attribute<std::string>& attrib)
  17683. {
  17684. return !(s == attrib.value());
  17685. }
  17686. template <typename T>
  17687. static inline std::ostream& operator<<(std::ostream& os, const attribute<T>& attrib)
  17688. {
  17689. return (os << attrib.value());
  17690. }
  17691. class semantic_action_impl
  17692. {
  17693. private:
  17694. class function_holder_base
  17695. {
  17696. public:
  17697. typedef const unsigned char* itr_type;
  17698. virtual ~function_holder_base(){}
  17699. virtual bool operator()(itr_type begin, itr_type end) const = 0;
  17700. inline bool operator()(const char* begin, const char* end) const
  17701. {
  17702. return operator()(reinterpret_cast<itr_type>(begin),
  17703. reinterpret_cast<itr_type>(end));
  17704. }
  17705. template <typename Iterator>
  17706. inline bool operator()(const std::pair<Iterator,Iterator>& p) const
  17707. {
  17708. return operator()(p.first,p.second);
  17709. }
  17710. };
  17711. template <typename Function>
  17712. class function_holder : public function_holder_base
  17713. {
  17714. public:
  17715. explicit function_holder(Function& f)
  17716. : function_(&f)
  17717. {}
  17718. inline virtual bool operator()(itr_type begin, itr_type end) const
  17719. {
  17720. return (*function_)(begin,end);
  17721. }
  17722. private:
  17723. Function* function_;
  17724. };
  17725. public:
  17726. semantic_action_impl()
  17727. : function_holder_(0)
  17728. {
  17729. std::fill_n(function_holder_buffer_,sizeof(function_holder_buffer_),0x00);
  17730. }
  17731. template <typename Function>
  17732. inline explicit semantic_action_impl(const Function& f)
  17733. {
  17734. std::fill_n(function_holder_buffer_,sizeof(function_holder_buffer_),0x00);
  17735. assign(f);
  17736. }
  17737. inline bool operator!() const
  17738. {
  17739. return (0 == function_holder_);
  17740. }
  17741. inline bool operator==(const semantic_action_impl& sa) const
  17742. {
  17743. return (0 != function_holder_) &&
  17744. (0 != sa.function_holder_) &&
  17745. (function_holder_ == sa.function_holder_);
  17746. }
  17747. template <typename InputIterator>
  17748. inline bool operator()(InputIterator begin, InputIterator end) const
  17749. {
  17750. if (0 != function_holder_)
  17751. return (*function_holder_).operator()(begin,end);
  17752. else
  17753. return false;
  17754. }
  17755. template <typename InputIterator>
  17756. inline bool operator()(const std::pair<InputIterator,InputIterator>& r) const
  17757. {
  17758. return operator()(r.first,r.second);
  17759. }
  17760. inline bool operator()(const std::string& s) const
  17761. {
  17762. return operator()(s.data(),s.data() + s.size());
  17763. }
  17764. template <typename Function>
  17765. inline void assign(Function& f)
  17766. {
  17767. static const std::size_t type_size = sizeof(function_holder<Function>(f));
  17768. function_holder_ = construct<Function,type_size <= function_holder_buffer_size>::type(f,function_holder_buffer_);
  17769. }
  17770. inline semantic_action_impl& ref()
  17771. {
  17772. return (*this);
  17773. }
  17774. private:
  17775. typedef function_holder_base* function_holder_ptr;
  17776. inline semantic_action_impl& operator=(const semantic_action_impl&);
  17777. template <typename Function, bool b>
  17778. struct construct
  17779. {
  17780. inline static function_holder_ptr type(Function&, unsigned char*)
  17781. {
  17782. return reinterpret_cast<function_holder_ptr>(0);
  17783. }
  17784. };
  17785. template <typename Function>
  17786. struct construct<Function,true>
  17787. {
  17788. inline static function_holder_ptr type(Function& f, unsigned char* buffer)
  17789. {
  17790. return new(buffer)function_holder<Function>(f);
  17791. }
  17792. };
  17793. function_holder_ptr function_holder_;
  17794. enum { function_holder_buffer_size = 64 };
  17795. unsigned char function_holder_buffer_[function_holder_buffer_size];
  17796. };
  17797. template <typename Function>
  17798. inline semantic_action_impl semantic_action(Function& f)
  17799. {
  17800. return semantic_action_impl(f);
  17801. }
  17802. } // namespace util
  17803. namespace details
  17804. {
  17805. #define strtk_register_attribute_type_tag(T)\
  17806. template<> struct supported_conversion_to_type< strtk::util::attribute<T> >{ typedef attribute_type_tag type; };\
  17807. template<> struct supported_conversion_from_type< strtk::util::attribute<T> > { typedef attribute_type_tag type; };
  17808. strtk_register_attribute_type_tag(unsigned short)
  17809. strtk_register_attribute_type_tag(unsigned int)
  17810. strtk_register_attribute_type_tag(unsigned long)
  17811. strtk_register_attribute_type_tag(unsigned long long int)
  17812. strtk_register_attribute_type_tag(short)
  17813. strtk_register_attribute_type_tag(int)
  17814. strtk_register_attribute_type_tag(long)
  17815. strtk_register_attribute_type_tag(long long)
  17816. strtk_register_attribute_type_tag(float)
  17817. strtk_register_attribute_type_tag(double)
  17818. strtk_register_attribute_type_tag(long double)
  17819. strtk_register_attribute_type_tag(unsigned char)
  17820. strtk_register_attribute_type_tag(signed char)
  17821. strtk_register_attribute_type_tag(char)
  17822. strtk_register_attribute_type_tag(std::string)
  17823. template <typename Iterator, typename T>
  17824. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, strtk::util::attribute<T>& result, attribute_type_tag)
  17825. {
  17826. if (strtk::string_to_type_converter(itr,end,result.value()))
  17827. {
  17828. result.initialised() = true;
  17829. return true;
  17830. }
  17831. else
  17832. return false;
  17833. }
  17834. template <typename T>
  17835. inline bool type_to_string_converter_impl(const strtk::util::attribute<T>& attrib, std::string& result, attribute_type_tag)
  17836. {
  17837. if (!attrib.initialised())
  17838. return false;
  17839. return strtk::type_to_string(attrib.value(),result);
  17840. }
  17841. #undef strtk_register_attribute_type_tag
  17842. template<> struct supported_conversion_to_type < strtk::util::semantic_action_impl > { typedef semantic_action_type_tag type; };
  17843. template<> struct supported_conversion_from_type< strtk::util::semantic_action_impl > { typedef semantic_action_type_tag type; };
  17844. template <typename Iterator>
  17845. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, strtk::util::semantic_action_impl& result, semantic_action_type_tag)
  17846. {
  17847. return result(itr,end);
  17848. }
  17849. inline bool type_to_string_converter_impl(const strtk::util::semantic_action_impl&, std::string& result, semantic_action_type_tag)
  17850. {
  17851. static std::string result_str = "semantic_action";
  17852. result = result_str;
  17853. return true;
  17854. }
  17855. } // namespace details
  17856. namespace util
  17857. {
  17858. class value
  17859. {
  17860. private:
  17861. class type_holder_base
  17862. {
  17863. public:
  17864. typedef const unsigned char* itr_type;
  17865. virtual ~type_holder_base(){}
  17866. virtual bool operator()(itr_type begin, itr_type end) const = 0;
  17867. virtual bool to_string(std::string& s) const = 0;
  17868. inline bool operator()(const char* begin, const char* end) const
  17869. {
  17870. return operator()(reinterpret_cast<itr_type>(begin),
  17871. reinterpret_cast<itr_type>(end));
  17872. }
  17873. template <typename Iterator>
  17874. inline bool operator()(const std::pair<Iterator,Iterator>& p) const
  17875. {
  17876. return operator()(p.first,p.second);
  17877. }
  17878. };
  17879. template <typename T>
  17880. class type_holder : public type_holder_base
  17881. {
  17882. public:
  17883. typedef T* type_ptr;
  17884. explicit type_holder(T& t)
  17885. : value_ptr_(&t)
  17886. {}
  17887. inline virtual bool operator()(itr_type begin, itr_type end) const
  17888. {
  17889. return strtk::string_to_type_converter(begin,end,(*value_ptr_));
  17890. }
  17891. inline virtual bool to_string(std::string& s) const
  17892. {
  17893. return strtk::type_to_string((*value_ptr_),s);
  17894. }
  17895. inline operator T() const
  17896. {
  17897. return (*value_ptr_);
  17898. }
  17899. private:
  17900. type_ptr value_ptr_;
  17901. };
  17902. public:
  17903. value()
  17904. : type_holder_(0)
  17905. {
  17906. std::fill_n(type_holder_buffer_,sizeof(type_holder_buffer_),0x00);
  17907. }
  17908. template <typename T>
  17909. inline explicit value(T& t)
  17910. {
  17911. std::fill_n(type_holder_buffer_,sizeof(type_holder_buffer_),0x00);
  17912. assign(t);
  17913. }
  17914. inline bool operator!() const
  17915. {
  17916. return (0 == type_holder_);
  17917. }
  17918. inline bool operator==(const value& v) const
  17919. {
  17920. return (0 != type_holder_) &&
  17921. (0 != v.type_holder_) &&
  17922. (type_holder_ == v.type_holder_);
  17923. }
  17924. inline value& operator=(const value& v)
  17925. {
  17926. if (&v != this)
  17927. {
  17928. if (0 != v.type_holder_)
  17929. {
  17930. std::copy(v.type_holder_buffer_,
  17931. v.type_holder_buffer_ + type_holder_buffer_size,
  17932. type_holder_buffer_);
  17933. type_holder_ = reinterpret_cast<type_holder_base*>(type_holder_buffer_);
  17934. }
  17935. }
  17936. return *this;
  17937. }
  17938. template <typename InputIterator>
  17939. inline bool operator()(InputIterator begin, InputIterator end) const
  17940. {
  17941. if (0 != type_holder_)
  17942. return (*type_holder_).operator()(begin,end);
  17943. else
  17944. return false;
  17945. }
  17946. template <typename InputIterator>
  17947. inline bool operator()(const std::pair<InputIterator,InputIterator>& r) const
  17948. {
  17949. return operator()(r.first,r.second);
  17950. }
  17951. inline bool operator()(const std::string& s) const
  17952. {
  17953. return operator()(s.data(),s.data() + s.size());
  17954. }
  17955. template <typename T>
  17956. inline void assign(T& t)
  17957. {
  17958. static const std::size_t type_size = sizeof(type_holder<T>(t));
  17959. type_holder_ = construct<T,type_size <= type_holder_buffer_size>::type(t,type_holder_buffer_);
  17960. }
  17961. inline bool to_string(std::string& s) const
  17962. {
  17963. if (0 != type_holder_)
  17964. return (*type_holder_).to_string(s);
  17965. else
  17966. return false;
  17967. }
  17968. template <typename T>
  17969. inline operator T() const
  17970. {
  17971. if (0 != type_holder_)
  17972. return (*type_holder_);
  17973. else
  17974. return T();
  17975. }
  17976. private:
  17977. typedef type_holder_base* type_holder_ptr;
  17978. template <typename T, bool b>
  17979. struct construct
  17980. {
  17981. inline static type_holder_ptr type(T&, unsigned char*)
  17982. {
  17983. return reinterpret_cast<type_holder_ptr>(0);
  17984. }
  17985. };
  17986. template <typename T>
  17987. struct construct<T,true>
  17988. {
  17989. inline static type_holder_ptr type(T& t, unsigned char* buffer)
  17990. {
  17991. return new(buffer)type_holder<T>(t);
  17992. }
  17993. };
  17994. type_holder_ptr type_holder_;
  17995. enum { type_holder_buffer_size = 2 * sizeof(type_holder<unsigned long long int>) };
  17996. unsigned char type_holder_buffer_[type_holder_buffer_size];
  17997. };
  17998. template <typename Key,
  17999. typename T,
  18000. typename Comparator,
  18001. typename MapAllocator,
  18002. typename OutputIterator>
  18003. inline void make_key_list(const std::map<Key,T,Comparator,MapAllocator>& map,
  18004. OutputIterator out)
  18005. {
  18006. if (map.empty()) return;
  18007. typedef typename std::map<Key,T,Comparator,MapAllocator> map_type;
  18008. typename map_type::const_iterator itr = map.begin();
  18009. typename map_type::const_iterator end = map.end();
  18010. while (end != itr)
  18011. {
  18012. *out++ = (itr++)->first;
  18013. }
  18014. }
  18015. template <typename Key,
  18016. typename T,
  18017. typename Comparator,
  18018. typename MapAllocator,
  18019. typename SetAllocator>
  18020. inline void make_key_list(const std::map<Key,T,Comparator,MapAllocator>& map,
  18021. std::set<Key,Comparator,SetAllocator>& set)
  18022. {
  18023. make_key_list(map,std::inserter(set,set.begin()));
  18024. }
  18025. template <typename Key,
  18026. typename T,
  18027. typename Comparator,
  18028. typename MapAllocator,
  18029. typename SetAllocator>
  18030. inline void make_key_list(const std::map<Key,T,Comparator,MapAllocator>& map,
  18031. std::multiset<Key,Comparator,SetAllocator>& multiset)
  18032. {
  18033. make_key_list(map,std::inserter(multiset,multiset.begin()));
  18034. }
  18035. template <typename Key,
  18036. typename T,
  18037. typename Comparator,
  18038. typename MapAllocator,
  18039. typename SequenceAllocator,
  18040. template <typename,typename> class Sequence>
  18041. inline void make_key_list(const std::map<Key,T,Comparator,MapAllocator>& map,
  18042. Sequence<Key,SequenceAllocator>& sequence)
  18043. {
  18044. make_key_list(map,std::back_inserter(sequence));
  18045. }
  18046. template <typename Key,
  18047. typename T,
  18048. typename Comparator,
  18049. typename MapAllocator,
  18050. typename OutputIterator>
  18051. inline void make_value_list(const std::multimap<Key,T,Comparator,MapAllocator>& map,
  18052. const Key& key,
  18053. OutputIterator out)
  18054. {
  18055. if (map.empty()) return;
  18056. typedef typename std::multimap<Key,T,Comparator,MapAllocator> map_type;
  18057. typename map_type::const_iterator itr = map.find(key);
  18058. typename map_type::const_iterator end = map.end();
  18059. while ((end != itr) && (key == itr->first))
  18060. {
  18061. *out++ = (itr++)->second;
  18062. }
  18063. }
  18064. template <typename Key,
  18065. typename T,
  18066. typename Comparator,
  18067. typename MapAllocator,
  18068. typename SequenceAllocator,
  18069. template <typename,typename> class Sequence>
  18070. inline void make_value_list(const std::multimap<Key,T,Comparator,MapAllocator>& map,
  18071. const Key& key,
  18072. Sequence<T,SequenceAllocator>& sequence)
  18073. {
  18074. make_value_list(map,key,std::back_inserter(sequence));
  18075. }
  18076. template <typename T,
  18077. typename Allocator,
  18078. template <typename,typename> class Sequence>
  18079. inline void delete_all(Sequence<T*,Allocator>& sequence)
  18080. {
  18081. typename Sequence<T*,Allocator>::iterator itr = sequence.begin();
  18082. typename Sequence<T*,Allocator>::iterator end = sequence.end();
  18083. while (end != itr)
  18084. {
  18085. delete (*itr);
  18086. ++itr;
  18087. }
  18088. sequence.clear();
  18089. }
  18090. template <typename Key,
  18091. typename T,
  18092. typename Comparator,
  18093. typename Allocator>
  18094. inline void delete_all(std::map<Key,T*,Comparator,Allocator>& cont)
  18095. {
  18096. typename std::map<Key,T*,Comparator,Allocator>::iterator itr = cont.begin();
  18097. typename std::map<Key,T*,Comparator,Allocator>::iterator end = cont.end();
  18098. while (end != itr)
  18099. {
  18100. delete (*itr).second;
  18101. ++itr;
  18102. }
  18103. cont.clear();
  18104. }
  18105. template <typename Key,
  18106. typename T,
  18107. typename Comparator,
  18108. typename Allocator>
  18109. inline void delete_all(std::multimap<Key,T*,Comparator,Allocator>& cont)
  18110. {
  18111. typename std::multimap<Key,T*,Comparator,Allocator>::iterator itr = cont.begin();
  18112. typename std::multimap<Key,T*,Comparator,Allocator>::iterator end = cont.end();
  18113. while (end != itr)
  18114. {
  18115. delete (*itr).second;
  18116. ++itr;
  18117. }
  18118. cont.clear();
  18119. }
  18120. template <typename T,
  18121. typename Comparator,
  18122. typename Allocator>
  18123. inline void delete_all(std::set<T*,Comparator,Allocator>& cont)
  18124. {
  18125. typename std::set<T*,Comparator,Allocator>::iterator itr = cont.begin();
  18126. typename std::set<T*,Comparator,Allocator>::iterator end = cont.end();
  18127. while (end != itr)
  18128. {
  18129. delete (*itr);
  18130. ++itr;
  18131. }
  18132. cont.clear();
  18133. }
  18134. template <typename T,
  18135. typename Comparator,
  18136. typename Allocator>
  18137. inline void delete_all(std::multiset<T*,Comparator,Allocator>& cont)
  18138. {
  18139. typename std::multiset<T*,Comparator,Allocator>::iterator itr = cont.begin();
  18140. typename std::multiset<T*,Comparator,Allocator>::iterator end = cont.end();
  18141. while (end != itr)
  18142. {
  18143. delete (*itr);
  18144. ++itr;
  18145. }
  18146. cont.clear();
  18147. }
  18148. template <typename Predicate,
  18149. typename T,
  18150. typename Allocator,
  18151. template <typename,typename> class Sequence>
  18152. inline void delete_if(const Predicate& p,
  18153. Sequence<T*,Allocator>& sequence)
  18154. {
  18155. typename Sequence<T*,Allocator>::iterator itr = sequence.begin();
  18156. while (sequence.end() != itr)
  18157. {
  18158. if (p(*itr))
  18159. {
  18160. delete (*itr);
  18161. itr = sequence.erase(itr);
  18162. }
  18163. else
  18164. ++itr;
  18165. }
  18166. }
  18167. template <typename Predicate,
  18168. typename Key,
  18169. typename T,
  18170. typename Comparator,
  18171. typename Allocator>
  18172. inline void delete_if(const Predicate& p,
  18173. std::map<Key,T*,Comparator,Allocator>& cont)
  18174. {
  18175. typename std::map<Key,T*,Comparator,Allocator>::iterator itr = cont.begin();
  18176. while (cont.end() != itr)
  18177. {
  18178. if (p(*itr))
  18179. {
  18180. delete (*itr).second;
  18181. itr = cont.erase(itr);
  18182. }
  18183. else
  18184. ++itr;
  18185. }
  18186. }
  18187. template <typename Predicate,
  18188. typename Key,
  18189. typename T,
  18190. typename Comparator,
  18191. typename Allocator>
  18192. inline void delete_if(const Predicate& p,
  18193. std::multimap<Key,T*,Comparator,Allocator>& cont)
  18194. {
  18195. typename std::multimap<Key,T*,Comparator,Allocator>::iterator itr = cont.begin();
  18196. while (cont.end() != itr)
  18197. {
  18198. if (p(*itr))
  18199. {
  18200. delete (*itr).second;
  18201. itr = cont.erase(itr);
  18202. }
  18203. else
  18204. ++itr;
  18205. }
  18206. }
  18207. template <typename Predicate,
  18208. typename T,
  18209. typename Comparator,
  18210. typename Allocator>
  18211. inline void delete_if(const Predicate& p,
  18212. std::set<T*,Comparator,Allocator>& cont)
  18213. {
  18214. typename std::set<T*,Comparator,Allocator>::iterator itr = cont.begin();
  18215. while (cont.end() != itr)
  18216. {
  18217. if (p(*itr))
  18218. {
  18219. delete (*itr).second;
  18220. itr = cont.erase(itr);
  18221. }
  18222. else
  18223. ++itr;
  18224. }
  18225. }
  18226. template <typename Predicate,
  18227. typename T,
  18228. typename Comparator,
  18229. typename Allocator>
  18230. inline void delete_if(const Predicate& p,
  18231. std::multiset<T*,Comparator,Allocator>& cont)
  18232. {
  18233. typename std::multiset<T*,Comparator,Allocator>::iterator itr = cont.begin();
  18234. while (cont.end() != itr)
  18235. {
  18236. if (p(*itr))
  18237. {
  18238. delete (*itr).second;
  18239. itr = cont.erase(itr);
  18240. }
  18241. else
  18242. ++itr;
  18243. }
  18244. }
  18245. template <typename T,
  18246. typename Allocator,
  18247. template <typename,typename> class Sequence>
  18248. inline void push_back(Sequence<T,Allocator>& sequence,
  18249. const T& v1, const T& v2, const T& v3, const T& v4,
  18250. const T& v5, const T& v6, const T& v7, const T& v8,
  18251. const T& v9, const T& v10, const T& v11)
  18252. {
  18253. sequence.push_back(v1); sequence.push_back(v2);
  18254. sequence.push_back(v3); sequence.push_back(v4);
  18255. sequence.push_back(v5); sequence.push_back(v6);
  18256. sequence.push_back(v7); sequence.push_back(v8);
  18257. sequence.push_back(v9); sequence.push_back(v10);
  18258. sequence.push_back(v11);
  18259. }
  18260. template <typename T,
  18261. typename Allocator,
  18262. template <typename,typename> class Sequence>
  18263. inline void push_back(Sequence<T,Allocator>& sequence,
  18264. const T& v1, const T& v2, const T& v3, const T& v4,
  18265. const T& v5, const T& v6, const T& v7, const T& v8,
  18266. const T& v9, const T& v10)
  18267. {
  18268. sequence.push_back(v1); sequence.push_back(v2);
  18269. sequence.push_back(v3); sequence.push_back(v4);
  18270. sequence.push_back(v5); sequence.push_back(v6);
  18271. sequence.push_back(v7); sequence.push_back(v8);
  18272. sequence.push_back(v9); sequence.push_back(v10);
  18273. }
  18274. template <typename T,
  18275. typename Allocator,
  18276. template <typename,typename> class Sequence>
  18277. inline void push_back(Sequence<T,Allocator>& sequence,
  18278. const T& v1, const T& v2, const T& v3, const T& v4,
  18279. const T& v5, const T& v6, const T& v7, const T& v8,
  18280. const T& v9)
  18281. {
  18282. sequence.push_back(v1); sequence.push_back(v2);
  18283. sequence.push_back(v3); sequence.push_back(v4);
  18284. sequence.push_back(v5); sequence.push_back(v6);
  18285. sequence.push_back(v7); sequence.push_back(v8);
  18286. sequence.push_back(v9);
  18287. }
  18288. template <typename T,
  18289. typename Allocator,
  18290. template <typename,typename> class Sequence>
  18291. inline void push_back(Sequence<T,Allocator>& sequence,
  18292. const T& v1, const T& v2, const T& v3, const T& v4,
  18293. const T& v5, const T& v6, const T& v7, const T& v8)
  18294. {
  18295. sequence.push_back(v1); sequence.push_back(v2);
  18296. sequence.push_back(v3); sequence.push_back(v4);
  18297. sequence.push_back(v5); sequence.push_back(v6);
  18298. sequence.push_back(v7); sequence.push_back(v8);
  18299. }
  18300. template <typename T,
  18301. typename Allocator,
  18302. template <typename,typename> class Sequence>
  18303. inline void push_back(Sequence<T,Allocator>& sequence,
  18304. const T& v1, const T& v2, const T& v3, const T& v4,
  18305. const T& v5, const T& v6, const T& v7)
  18306. {
  18307. sequence.push_back(v1); sequence.push_back(v2);
  18308. sequence.push_back(v3); sequence.push_back(v4);
  18309. sequence.push_back(v5); sequence.push_back(v6);
  18310. sequence.push_back(v7);
  18311. }
  18312. template <typename T,
  18313. typename Allocator,
  18314. template <typename,typename> class Sequence>
  18315. inline void push_back(Sequence<T,Allocator>& sequence,
  18316. const T& v1, const T& v2, const T& v3, const T& v4,
  18317. const T& v5, const T& v6)
  18318. {
  18319. sequence.push_back(v1); sequence.push_back(v2);
  18320. sequence.push_back(v3); sequence.push_back(v4);
  18321. sequence.push_back(v5); sequence.push_back(v6);
  18322. }
  18323. template <typename T,
  18324. typename Allocator,
  18325. template <typename,typename> class Sequence>
  18326. inline void push_back(Sequence<T,Allocator>& sequence,
  18327. const T& v1, const T& v2, const T& v3, const T& v4,
  18328. const T& v5)
  18329. {
  18330. sequence.push_back(v1); sequence.push_back(v2);
  18331. sequence.push_back(v3); sequence.push_back(v4);
  18332. sequence.push_back(v5);
  18333. }
  18334. template <typename T,
  18335. typename Allocator,
  18336. template <typename,typename> class Sequence>
  18337. inline void push_back(Sequence<T,Allocator>& sequence,
  18338. const T& v1, const T& v2, const T& v3, const T& v4)
  18339. {
  18340. sequence.push_back(v1); sequence.push_back(v2);
  18341. sequence.push_back(v3); sequence.push_back(v4);
  18342. }
  18343. template <typename T,
  18344. typename Allocator,
  18345. template <typename,typename> class Sequence>
  18346. inline void push_back(Sequence<T,Allocator>& sequence,
  18347. const T& v1, const T& v2, const T& v3)
  18348. {
  18349. sequence.push_back(v1); sequence.push_back(v2);
  18350. sequence.push_back(v3);
  18351. }
  18352. template <typename T,
  18353. typename Allocator,
  18354. template <typename,typename> class Sequence>
  18355. inline void push_back(Sequence<T,Allocator>& sequence,
  18356. const T& v1, const T& v2)
  18357. {
  18358. sequence.push_back(v1); sequence.push_back(v2);
  18359. }
  18360. template <typename T,
  18361. typename Allocator,
  18362. template <typename,typename> class Sequence>
  18363. inline void push_back(Sequence<T,Allocator>& sequence,
  18364. const T& v1)
  18365. {
  18366. sequence.push_back(v1);
  18367. }
  18368. template <typename T, typename Comparator, typename Allocator>
  18369. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18370. const T& v1, const T& v2, const T& v3, const T& v4,
  18371. const T& v5, const T& v6, const T& v7, const T& v8,
  18372. const T& v9, const T& v10)
  18373. {
  18374. set.insert(v1); set.insert(v2);
  18375. set.insert(v3); set.insert(v4);
  18376. set.insert(v5); set.insert(v6);
  18377. set.insert(v7); set.insert(v8);
  18378. set.insert(v9); set.insert(v10);
  18379. }
  18380. template <typename T, typename Comparator, typename Allocator>
  18381. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18382. const T& v1, const T& v2, const T& v3, const T& v4,
  18383. const T& v5, const T& v6, const T& v7, const T& v8,
  18384. const T& v9)
  18385. {
  18386. set.insert(v1); set.insert(v2);
  18387. set.insert(v3); set.insert(v4);
  18388. set.insert(v5); set.insert(v6);
  18389. set.insert(v7); set.insert(v8);
  18390. set.insert(v9);
  18391. }
  18392. template <typename T, typename Comparator, typename Allocator>
  18393. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18394. const T& v1, const T& v2, const T& v3, const T& v4,
  18395. const T& v5, const T& v6, const T& v7, const T& v8)
  18396. {
  18397. set.insert(v1); set.insert(v2);
  18398. set.insert(v3); set.insert(v4);
  18399. set.insert(v5); set.insert(v6);
  18400. set.insert(v7); set.insert(v8);
  18401. }
  18402. template <typename T, typename Comparator, typename Allocator>
  18403. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18404. const T& v1, const T& v2, const T& v3, const T& v4,
  18405. const T& v5, const T& v6, const T& v7)
  18406. {
  18407. set.insert(v1); set.insert(v2);
  18408. set.insert(v3); set.insert(v4);
  18409. set.insert(v5); set.insert(v6);
  18410. set.insert(v7);
  18411. }
  18412. template <typename T, typename Comparator, typename Allocator>
  18413. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18414. const T& v1, const T& v2, const T& v3, const T& v4,
  18415. const T& v5, const T& v6)
  18416. {
  18417. set.insert(v1); set.insert(v2);
  18418. set.insert(v3); set.insert(v4);
  18419. set.insert(v5); set.insert(v6);
  18420. }
  18421. template <typename T, typename Comparator, typename Allocator>
  18422. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18423. const T& v1, const T& v2, const T& v3, const T& v4,
  18424. const T& v5)
  18425. {
  18426. set.insert(v1); set.insert(v2);
  18427. set.insert(v3); set.insert(v4);
  18428. set.insert(v5);
  18429. }
  18430. template <typename T, typename Comparator, typename Allocator>
  18431. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18432. const T& v1, const T& v2, const T& v3, const T& v4)
  18433. {
  18434. set.insert(v1); set.insert(v2);
  18435. set.insert(v3); set.insert(v4);
  18436. }
  18437. template <typename T, typename Comparator, typename Allocator>
  18438. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18439. const T& v1, const T& v2, const T& v3)
  18440. {
  18441. set.insert(v1); set.insert(v2);
  18442. set.insert(v3);
  18443. }
  18444. template <typename T, typename Comparator, typename Allocator>
  18445. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18446. const T& v1, const T& v2)
  18447. {
  18448. set.insert(v1); set.insert(v2);
  18449. }
  18450. template <typename T, typename Comparator, typename Allocator>
  18451. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18452. const T& v1)
  18453. {
  18454. set.insert(v1);
  18455. }
  18456. template <typename T, typename Comparator, typename Allocator>
  18457. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18458. const T& v1, const T& v2, const T& v3, const T& v4,
  18459. const T& v5, const T& v6, const T& v7, const T& v8,
  18460. const T& v9, const T& v10)
  18461. {
  18462. set.insert(v1); set.insert(v2);
  18463. set.insert(v3); set.insert(v4);
  18464. set.insert(v5); set.insert(v6);
  18465. set.insert(v7); set.insert(v8);
  18466. set.insert(v9); set.insert(v10);
  18467. }
  18468. template <typename T, typename Comparator, typename Allocator>
  18469. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18470. const T& v1, const T& v2, const T& v3, const T& v4,
  18471. const T& v5, const T& v6, const T& v7, const T& v8,
  18472. const T& v9)
  18473. {
  18474. set.insert(v1); set.insert(v2);
  18475. set.insert(v3); set.insert(v4);
  18476. set.insert(v5); set.insert(v6);
  18477. set.insert(v7); set.insert(v8);
  18478. set.insert(v9);
  18479. }
  18480. template <typename T, typename Comparator, typename Allocator>
  18481. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18482. const T& v1, const T& v2, const T& v3, const T& v4,
  18483. const T& v5, const T& v6, const T& v7, const T& v8)
  18484. {
  18485. set.insert(v1); set.insert(v2);
  18486. set.insert(v3); set.insert(v4);
  18487. set.insert(v5); set.insert(v6);
  18488. set.insert(v7); set.insert(v8);
  18489. }
  18490. template <typename T, typename Comparator, typename Allocator>
  18491. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18492. const T& v1, const T& v2, const T& v3, const T& v4,
  18493. const T& v5, const T& v6, const T& v7)
  18494. {
  18495. set.insert(v1); set.insert(v2);
  18496. set.insert(v3); set.insert(v4);
  18497. set.insert(v5); set.insert(v6);
  18498. set.insert(v7);
  18499. }
  18500. template <typename T, typename Comparator, typename Allocator>
  18501. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18502. const T& v1, const T& v2, const T& v3, const T& v4,
  18503. const T& v5, const T& v6)
  18504. {
  18505. set.insert(v1); set.insert(v2);
  18506. set.insert(v3); set.insert(v4);
  18507. set.insert(v5); set.insert(v6);
  18508. }
  18509. template <typename T, typename Comparator, typename Allocator>
  18510. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18511. const T& v1, const T& v2, const T& v3, const T& v4,
  18512. const T& v5)
  18513. {
  18514. set.insert(v1); set.insert(v2);
  18515. set.insert(v3); set.insert(v4);
  18516. set.insert(v5);
  18517. }
  18518. template <typename T, typename Comparator, typename Allocator>
  18519. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18520. const T& v1, const T& v2, const T& v3, const T& v4)
  18521. {
  18522. set.insert(v1); set.insert(v2);
  18523. set.insert(v3); set.insert(v4);
  18524. }
  18525. template <typename T, typename Comparator, typename Allocator>
  18526. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18527. const T& v1, const T& v2, const T& v3)
  18528. {
  18529. set.insert(v1); set.insert(v2);
  18530. set.insert(v3);
  18531. }
  18532. template <typename T, typename Comparator, typename Allocator>
  18533. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18534. const T& v1, const T& v2)
  18535. {
  18536. set.insert(v1); set.insert(v2);
  18537. }
  18538. template <typename T, typename Comparator, typename Allocator>
  18539. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18540. const T& v1)
  18541. {
  18542. set.insert(v1);
  18543. }
  18544. template <typename T,
  18545. typename Allocator,
  18546. template <typename,typename> class Sequence>
  18547. inline void clear(Sequence<T,Allocator>& sequence)
  18548. {
  18549. sequence.clear();
  18550. }
  18551. template <typename T,
  18552. typename Comparator,
  18553. typename Allocator>
  18554. inline void clear(std::set<T,Comparator,Allocator>& set)
  18555. {
  18556. std::set<T> null_set;
  18557. std::swap(set,null_set);
  18558. }
  18559. template <typename T,
  18560. typename Comparator,
  18561. typename Allocator>
  18562. inline void clear(std::multiset<T,Comparator,Allocator>& multiset)
  18563. {
  18564. std::multiset<T> null_set;
  18565. std::swap(multiset,null_set);
  18566. }
  18567. template <typename T, typename Container>
  18568. inline void clear(std::queue<T,Container>& queue)
  18569. {
  18570. std::queue<T> null_que;
  18571. std::swap(queue,null_que);
  18572. }
  18573. template <typename T, typename Container>
  18574. inline void clear(std::stack<T,Container>& stack)
  18575. {
  18576. std::stack<T> null_stack;
  18577. std::swap(stack,null_stack);
  18578. }
  18579. template <typename T,
  18580. typename Container,
  18581. typename Comparator>
  18582. inline void clear(std::priority_queue<T,Container,Comparator>& priority_queue)
  18583. {
  18584. std::priority_queue<T> null_pqueue;
  18585. std::swap(priority_queue,null_pqueue);
  18586. }
  18587. } // namespace util
  18588. namespace details
  18589. {
  18590. template <std::size_t N>
  18591. struct column_list_impl
  18592. {
  18593. enum { size = N };
  18594. std::size_t index_list[N];
  18595. };
  18596. template <typename Cli, std::size_t N>
  18597. class column_selector_base
  18598. {
  18599. public:
  18600. typedef column_selector_base<Cli,N> csb_t;
  18601. typedef column_list_impl<N> column_list_t;
  18602. column_selector_base(const column_list_t& column_list)
  18603. : column_list_(column_list),
  18604. current_index_(0),
  18605. target_index_(column_list_.index_list[0]),
  18606. col_list_index_(0),
  18607. error_count_(0)
  18608. {}
  18609. inline csb_t& operator*()
  18610. {
  18611. return (*this);
  18612. }
  18613. inline csb_t& operator++()
  18614. {
  18615. return (*this);
  18616. }
  18617. inline csb_t operator++(int)
  18618. {
  18619. return (*this);
  18620. }
  18621. template <typename Iterator>
  18622. inline csb_t& operator=(const std::pair<Iterator,Iterator>& r)
  18623. {
  18624. process(r);
  18625. return (*this);
  18626. }
  18627. void reset()
  18628. {
  18629. current_index_ = 0;
  18630. col_list_index_ = 0;
  18631. target_index_ = column_list_.index_list[0];
  18632. error_count_ = 0;
  18633. }
  18634. protected:
  18635. class colsel_value_list
  18636. {
  18637. public:
  18638. typedef std::pair<strtk::util::value,bool> value_t;
  18639. colsel_value_list()
  18640. : current_index(0)
  18641. {
  18642. static const value_t null_value(strtk::util::value(),false);
  18643. std::fill_n(value_list,N,null_value);
  18644. }
  18645. template <typename T>
  18646. inline void register_value(T& t)
  18647. {
  18648. if (current_index < N)
  18649. {
  18650. value_list[current_index].first.assign(t);
  18651. value_list[current_index].second = false;
  18652. ++current_index;
  18653. }
  18654. }
  18655. std::size_t current_index;
  18656. value_t value_list[N];
  18657. };
  18658. template <typename Iterator>
  18659. inline void process(const std::pair<Iterator,Iterator>& r)
  18660. {
  18661. if (current_index_ > target_index_)
  18662. return;
  18663. else if (current_index_ == target_index_)
  18664. {
  18665. typename colsel_value_list::value_t& v = cvl_.value_list[col_list_index_];
  18666. if (true != (v.second = v.first(r.first,r.second)))
  18667. {
  18668. ++error_count_;
  18669. }
  18670. ++col_list_index_;
  18671. if (col_list_index_ < column_list_t::size)
  18672. target_index_ = column_list_.index_list[col_list_index_];
  18673. else
  18674. target_index_ = std::numeric_limits<std::size_t>::max();
  18675. }
  18676. ++current_index_;
  18677. }
  18678. inline colsel_value_list& cvl()
  18679. {
  18680. return cvl_;
  18681. }
  18682. const column_list_t& column_list_;
  18683. std::size_t current_index_;
  18684. std::size_t target_index_;
  18685. std::size_t col_list_index_;
  18686. std::size_t error_count_;
  18687. colsel_value_list cvl_;
  18688. private:
  18689. csb_t& operator=(const csb_t& csb);
  18690. };
  18691. template <typename T0 = void, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void,
  18692. typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void, typename T9 = void,
  18693. typename T10 = void, typename T11 = void>
  18694. class column_selector_impl
  18695. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>,12>
  18696. {
  18697. public:
  18698. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>,12> csb_t;
  18699. typedef column_list_impl<12> column_list_t;
  18700. column_selector_impl(const column_list_t& column_list,
  18701. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  18702. T5& t5, T6& t6, T7& t7, T8& t8, T9& t9,
  18703. T10& t10, T11& t11)
  18704. : csb_t(column_list)
  18705. {
  18706. csb_t::cvl().register_value( t0); csb_t::cvl().register_value( t1);
  18707. csb_t::cvl().register_value( t2); csb_t::cvl().register_value( t3);
  18708. csb_t::cvl().register_value( t4); csb_t::cvl().register_value( t5);
  18709. csb_t::cvl().register_value( t6); csb_t::cvl().register_value( t7);
  18710. csb_t::cvl().register_value( t8); csb_t::cvl().register_value( t9);
  18711. csb_t::cvl().register_value(t10); csb_t::cvl().register_value(t11);
  18712. }
  18713. };
  18714. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  18715. typename T5, typename T6, typename T7, typename T8, typename T9,
  18716. typename T10>
  18717. class column_selector_impl <T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>
  18718. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>,11>
  18719. {
  18720. public:
  18721. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>,11> csb_t;
  18722. typedef column_list_impl<11> column_list_t;
  18723. column_selector_impl(const column_list_t& column_list,
  18724. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  18725. T5& t5, T6& t6, T7& t7, T8& t8, T9& t9,
  18726. T10& t10)
  18727. : csb_t(column_list)
  18728. {
  18729. csb_t::cvl().register_value( t0); csb_t::cvl().register_value( t1);
  18730. csb_t::cvl().register_value( t2); csb_t::cvl().register_value( t3);
  18731. csb_t::cvl().register_value( t4); csb_t::cvl().register_value( t5);
  18732. csb_t::cvl().register_value( t6); csb_t::cvl().register_value( t7);
  18733. csb_t::cvl().register_value( t8); csb_t::cvl().register_value( t9);
  18734. csb_t::cvl().register_value(t10);
  18735. }
  18736. };
  18737. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  18738. typename T5, typename T6, typename T7, typename T8, typename T9>
  18739. class column_selector_impl <T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
  18740. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>,10>
  18741. {
  18742. public:
  18743. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>,10> csb_t;
  18744. typedef column_list_impl<10> column_list_t;
  18745. column_selector_impl(const column_list_t& column_list,
  18746. T1& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  18747. T5& t5, T6& t6, T7& t7, T8& t8, T9& t9)
  18748. : csb_t(column_list)
  18749. {
  18750. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  18751. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  18752. csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5);
  18753. csb_t::cvl().register_value(t6); csb_t::cvl().register_value(t7);
  18754. csb_t::cvl().register_value(t8); csb_t::cvl().register_value(t9);
  18755. }
  18756. };
  18757. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  18758. typename T5, typename T6, typename T7, typename T8>
  18759. class column_selector_impl <T0,T1,T2,T3,T4,T5,T6,T7,T8>
  18760. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8>,9>
  18761. {
  18762. public:
  18763. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8>,9> csb_t;
  18764. typedef column_list_impl<9> column_list_t;
  18765. column_selector_impl(const column_list_t& column_list,
  18766. T1& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  18767. T5& t5, T6& t6, T7& t7, T8& t8)
  18768. : csb_t(column_list)
  18769. {
  18770. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  18771. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  18772. csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5);
  18773. csb_t::cvl().register_value(t6); csb_t::cvl().register_value(t7);
  18774. csb_t::cvl().register_value(t8);
  18775. }
  18776. };
  18777. template <typename T0, typename T1, typename T2, typename T3,
  18778. typename T4, typename T5, typename T6, typename T7>
  18779. class column_selector_impl <T0,T1,T2,T3,T4,T5,T6,T7>
  18780. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7>,8>
  18781. {
  18782. public:
  18783. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7>,8> csb_t;
  18784. typedef column_list_impl<8> column_list_t;
  18785. column_selector_impl(const column_list_t& column_list,
  18786. T1& t0, T1& t1, T2& t2, T3& t3,
  18787. T4& t4, T5& t5, T6& t6, T7& t7)
  18788. : csb_t(column_list)
  18789. {
  18790. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  18791. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  18792. csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5);
  18793. csb_t::cvl().register_value(t6); csb_t::cvl().register_value(t7);
  18794. }
  18795. };
  18796. template <typename T0, typename T1, typename T2, typename T3,
  18797. typename T4, typename T5, typename T6>
  18798. class column_selector_impl <T0,T1,T2,T3,T4,T5,T6>
  18799. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6>,7>
  18800. {
  18801. public:
  18802. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6>,7> csb_t;
  18803. typedef column_list_impl<7> column_list_t;
  18804. column_selector_impl(const column_list_t& column_list,
  18805. T1& t0, T1& t1, T2& t2, T3& t3,
  18806. T4& t4, T5& t5, T6& t6)
  18807. : csb_t(column_list)
  18808. {
  18809. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  18810. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  18811. csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5);
  18812. csb_t::cvl().register_value(t6);
  18813. }
  18814. };
  18815. template <typename T0, typename T1, typename T2,
  18816. typename T3, typename T4, typename T5>
  18817. class column_selector_impl <T0,T1,T2,T3,T4,T5>
  18818. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5>,6>
  18819. {
  18820. public:
  18821. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5>,6> csb_t;
  18822. typedef column_list_impl<6> column_list_t;
  18823. column_selector_impl(const column_list_t& column_list,
  18824. T1& t0, T1& t1, T2& t2,
  18825. T3& t3, T4& t4, T5& t5)
  18826. : csb_t(column_list)
  18827. {
  18828. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  18829. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  18830. csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5);
  18831. }
  18832. };
  18833. template <typename T0, typename T1, typename T2,
  18834. typename T3, typename T4>
  18835. class column_selector_impl <T0,T1,T2,T3,T4>
  18836. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4>,5>
  18837. {
  18838. public:
  18839. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4>,5> csb_t;
  18840. typedef column_list_impl<5> column_list_t;
  18841. column_selector_impl(const column_list_t& column_list,
  18842. T1& t0, T1& t1, T2& t2,
  18843. T3& t3, T4& t4)
  18844. : csb_t(column_list)
  18845. {
  18846. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  18847. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  18848. csb_t::cvl().register_value(t4);
  18849. }
  18850. };
  18851. template <typename T0, typename T1, typename T2, typename T3>
  18852. class column_selector_impl <T0,T1,T2,T3>
  18853. : public column_selector_base<column_selector_impl<T0,T1,T2,T3>,4>
  18854. {
  18855. public:
  18856. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3>,4> csb_t;
  18857. typedef column_list_impl<4> column_list_t;
  18858. column_selector_impl(const column_list_t& column_list,
  18859. T1& t0, T1& t1, T2& t2, T3& t3)
  18860. : csb_t(column_list)
  18861. {
  18862. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  18863. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  18864. }
  18865. };
  18866. template <typename T0, typename T1, typename T2>
  18867. class column_selector_impl <T0,T1,T2>
  18868. : public column_selector_base<column_selector_impl<T0,T1,T2>,3>
  18869. {
  18870. public:
  18871. typedef column_selector_base<column_selector_impl<T0,T1,T2>,3> csb_t;
  18872. typedef column_list_impl<3> column_list_t;
  18873. column_selector_impl(const column_list_t& column_list,
  18874. T1& t0, T1& t1, T2& t2)
  18875. : csb_t(column_list)
  18876. {
  18877. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  18878. csb_t::cvl().register_value(t2);
  18879. }
  18880. };
  18881. template <typename T0, typename T1>
  18882. class column_selector_impl <T0,T1>
  18883. : public column_selector_base<column_selector_impl<T0,T1>,2>
  18884. {
  18885. public:
  18886. typedef column_selector_base<column_selector_impl<T0,T1>,2> csb_t;
  18887. typedef column_list_impl<2> column_list_t;
  18888. column_selector_impl(const column_list_t& column_list,
  18889. T1& t0, T1& t1)
  18890. : csb_t(column_list)
  18891. {
  18892. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  18893. }
  18894. };
  18895. template <typename T0>
  18896. class column_selector_impl <T0>
  18897. : public column_selector_base<column_selector_impl<T0>,1>
  18898. {
  18899. public:
  18900. typedef column_selector_base<column_selector_impl<T0>,1> csb_t;
  18901. typedef column_list_impl<1> column_list_t;
  18902. column_selector_impl(const column_list_t& column_list, T0& t0)
  18903. : csb_t(column_list)
  18904. {
  18905. csb_t::cvl().register_value(t0);
  18906. }
  18907. };
  18908. }
  18909. inline details::column_list_impl<12>
  18910. column_list(const std::size_t& idx0, const std::size_t& idx1,
  18911. const std::size_t& idx2, const std::size_t& idx3,
  18912. const std::size_t& idx4, const std::size_t& idx5,
  18913. const std::size_t& idx6, const std::size_t& idx7,
  18914. const std::size_t& idx8, const std::size_t& idx9,
  18915. const std::size_t& idx10, const std::size_t& idx11)
  18916. {
  18917. details::column_list_impl<12> cli;
  18918. cli.index_list[ 0] = idx0; cli.index_list[ 1] = idx1;
  18919. cli.index_list[ 2] = idx2; cli.index_list[ 3] = idx3;
  18920. cli.index_list[ 4] = idx4; cli.index_list[ 5] = idx5;
  18921. cli.index_list[ 6] = idx6; cli.index_list[ 7] = idx7;
  18922. cli.index_list[ 8] = idx8; cli.index_list[ 9] = idx9;
  18923. cli.index_list[10] = idx10; cli.index_list[11] = idx11;
  18924. return cli;
  18925. }
  18926. inline details::column_list_impl<11>
  18927. column_list(const std::size_t& idx0, const std::size_t& idx1,
  18928. const std::size_t& idx2, const std::size_t& idx3,
  18929. const std::size_t& idx4, const std::size_t& idx5,
  18930. const std::size_t& idx6, const std::size_t& idx7,
  18931. const std::size_t& idx8, const std::size_t& idx9,
  18932. const std::size_t& idx10)
  18933. {
  18934. details::column_list_impl<11> cli;
  18935. cli.index_list[ 0] = idx0; cli.index_list[1] = idx1;
  18936. cli.index_list[ 2] = idx2; cli.index_list[3] = idx3;
  18937. cli.index_list[ 4] = idx4; cli.index_list[5] = idx5;
  18938. cli.index_list[ 6] = idx6; cli.index_list[7] = idx7;
  18939. cli.index_list[ 8] = idx8; cli.index_list[9] = idx9;
  18940. cli.index_list[10] = idx10;
  18941. return cli;
  18942. }
  18943. inline details::column_list_impl<10>
  18944. column_list(const std::size_t& idx0, const std::size_t& idx1,
  18945. const std::size_t& idx2, const std::size_t& idx3,
  18946. const std::size_t& idx4, const std::size_t& idx5,
  18947. const std::size_t& idx6, const std::size_t& idx7,
  18948. const std::size_t& idx8, const std::size_t& idx9)
  18949. {
  18950. details::column_list_impl<10> cli;
  18951. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  18952. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  18953. cli.index_list[4] = idx4; cli.index_list[5] = idx5;
  18954. cli.index_list[6] = idx6; cli.index_list[7] = idx7;
  18955. cli.index_list[8] = idx8; cli.index_list[9] = idx9;
  18956. return cli;
  18957. }
  18958. inline details::column_list_impl<9>
  18959. column_list(const std::size_t& idx0, const std::size_t& idx1,
  18960. const std::size_t& idx2, const std::size_t& idx3,
  18961. const std::size_t& idx4, const std::size_t& idx5,
  18962. const std::size_t& idx6, const std::size_t& idx7,
  18963. const std::size_t& idx8)
  18964. {
  18965. details::column_list_impl<9> cli;
  18966. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  18967. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  18968. cli.index_list[4] = idx4; cli.index_list[5] = idx5;
  18969. cli.index_list[6] = idx6; cli.index_list[7] = idx7;
  18970. cli.index_list[8] = idx8;
  18971. return cli;
  18972. }
  18973. inline details::column_list_impl<8>
  18974. column_list(const std::size_t& idx0, const std::size_t& idx1,
  18975. const std::size_t& idx2, const std::size_t& idx3,
  18976. const std::size_t& idx4, const std::size_t& idx5,
  18977. const std::size_t& idx6, const std::size_t& idx7)
  18978. {
  18979. details::column_list_impl<8> cli;
  18980. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  18981. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  18982. cli.index_list[4] = idx4; cli.index_list[5] = idx5;
  18983. cli.index_list[6] = idx6; cli.index_list[7] = idx7;
  18984. return cli;
  18985. }
  18986. inline details::column_list_impl<7>
  18987. column_list(const std::size_t& idx0, const std::size_t& idx1,
  18988. const std::size_t& idx2, const std::size_t& idx3,
  18989. const std::size_t& idx4, const std::size_t& idx5,
  18990. const std::size_t& idx6)
  18991. {
  18992. details::column_list_impl<7> cli;
  18993. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  18994. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  18995. cli.index_list[4] = idx4; cli.index_list[5] = idx5;
  18996. cli.index_list[6] = idx6;
  18997. return cli;
  18998. }
  18999. inline details::column_list_impl<6>
  19000. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19001. const std::size_t& idx2, const std::size_t& idx3,
  19002. const std::size_t& idx4, const std::size_t& idx5)
  19003. {
  19004. details::column_list_impl<6> cli;
  19005. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19006. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  19007. cli.index_list[4] = idx4; cli.index_list[5] = idx5;
  19008. return cli;
  19009. }
  19010. inline details::column_list_impl<5>
  19011. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19012. const std::size_t& idx2, const std::size_t& idx3,
  19013. const std::size_t& idx4)
  19014. {
  19015. details::column_list_impl<5> cli;
  19016. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19017. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  19018. cli.index_list[4] = idx4;
  19019. return cli;
  19020. }
  19021. inline details::column_list_impl<4>
  19022. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19023. const std::size_t& idx2, const std::size_t& idx3)
  19024. {
  19025. details::column_list_impl<4> cli;
  19026. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19027. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  19028. return cli;
  19029. }
  19030. inline details::column_list_impl<3>
  19031. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19032. const std::size_t& idx2)
  19033. {
  19034. details::column_list_impl<3> cli;
  19035. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19036. cli.index_list[2] = idx2;
  19037. return cli;
  19038. }
  19039. inline details::column_list_impl<2>
  19040. column_list(const std::size_t& idx0, const std::size_t& idx1)
  19041. {
  19042. details::column_list_impl<2> cli;
  19043. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19044. return cli;
  19045. }
  19046. inline details::column_list_impl<1>
  19047. column_list(const std::size_t& idx0)
  19048. {
  19049. details::column_list_impl<1> cli;
  19050. cli.index_list[0] = idx0;
  19051. return cli;
  19052. }
  19053. inline details::column_list_impl<12> column_list(const std::size_t (&idx)[12])
  19054. {
  19055. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],
  19056. idx[6],idx[7],idx[8],idx[9],idx[10],idx[11]);
  19057. }
  19058. inline details::column_list_impl<11> column_list(const std::size_t (&idx)[11])
  19059. {
  19060. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],
  19061. idx[6],idx[7],idx[8],idx[9],idx[10]);
  19062. }
  19063. inline details::column_list_impl<10> column_list(const std::size_t (&idx)[10])
  19064. {
  19065. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],
  19066. idx[6],idx[7],idx[8],idx[9]);
  19067. }
  19068. inline details::column_list_impl<9> column_list(const std::size_t (&idx)[9])
  19069. {
  19070. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],
  19071. idx[6],idx[7],idx[8]);
  19072. }
  19073. inline details::column_list_impl<8> column_list(const std::size_t (&idx)[8])
  19074. {
  19075. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],
  19076. idx[6],idx[7]);
  19077. }
  19078. inline details::column_list_impl<7> column_list(const std::size_t (&idx)[7])
  19079. {
  19080. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],idx[6]);
  19081. }
  19082. inline details::column_list_impl<6> column_list(const std::size_t (&idx)[6])
  19083. {
  19084. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5]);
  19085. }
  19086. inline details::column_list_impl<5> column_list(const std::size_t (&idx)[5])
  19087. {
  19088. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4]);
  19089. }
  19090. inline details::column_list_impl<4> column_list(const std::size_t (&idx)[4])
  19091. {
  19092. return column_list(idx[0],idx[1],idx[2],idx[3]);
  19093. }
  19094. inline details::column_list_impl<3> column_list(const std::size_t (&idx)[3])
  19095. {
  19096. return column_list(idx[0],idx[1],idx[2]);
  19097. }
  19098. inline details::column_list_impl<2> column_list(const std::size_t (&idx)[2])
  19099. {
  19100. return column_list(idx[0],idx[1]);
  19101. }
  19102. inline details::column_list_impl<1> column_list(const std::size_t (&idx)[1])
  19103. {
  19104. return column_list(idx[0]);
  19105. }
  19106. template <typename T0, typename T1, typename T2, typename T3,
  19107. typename T4, typename T5, typename T6, typename T7,
  19108. typename T8, typename T9, typename T10, typename T11>
  19109. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
  19110. column_selector(const details::column_list_impl<11>& col_list,
  19111. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19112. T6& t6, T7& t7, T8& t8, T9& t9, T10& t10, T11& t11)
  19113. {
  19114. return
  19115. details::column_selector_impl
  19116. <T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>
  19117. (col_list,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11);
  19118. }
  19119. template <typename T0, typename T1, typename T2, typename T3,
  19120. typename T4, typename T5, typename T6, typename T7,
  19121. typename T8, typename T9, typename T10>
  19122. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
  19123. column_selector(const details::column_list_impl<11>& col_list,
  19124. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19125. T6& t6, T7& t7, T8& t8, T9& t9, T10& t10)
  19126. {
  19127. return
  19128. details::column_selector_impl
  19129. <T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>
  19130. (col_list,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10);
  19131. }
  19132. template <typename T0, typename T1, typename T2, typename T3,
  19133. typename T4, typename T5, typename T6, typename T7,
  19134. typename T8, typename T9>
  19135. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
  19136. column_selector(const details::column_list_impl<10>& col_list,
  19137. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19138. T6& t6, T7& t7, T8& t8, T9& t9)
  19139. {
  19140. return
  19141. details::column_selector_impl
  19142. <T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
  19143. (col_list,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9);
  19144. }
  19145. template <typename T0, typename T1, typename T2, typename T3,
  19146. typename T4, typename T5, typename T6, typename T7,
  19147. typename T8>
  19148. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8>
  19149. column_selector(const details::column_list_impl<9>& col_list,
  19150. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19151. T6& t6, T7& t7, T8& t8)
  19152. {
  19153. return
  19154. details::column_selector_impl
  19155. <T0,T1,T2,T3,T4,T5,T6,T7,T8>
  19156. (col_list,t0,t1,t2,t3,t4,t5,t6,t7,t8);
  19157. }
  19158. template <typename T0, typename T1, typename T2, typename T3,
  19159. typename T4, typename T5, typename T6, typename T7>
  19160. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7>
  19161. column_selector(const details::column_list_impl<8>& col_list,
  19162. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19163. T6& t6, T7& t7)
  19164. {
  19165. return
  19166. details::column_selector_impl
  19167. <T0,T1,T2,T3,T4,T5,T6,T7>
  19168. (col_list,t0,t1,t2,t3,t4,t5,t6,t7);
  19169. }
  19170. template <typename T0, typename T1, typename T2, typename T3,
  19171. typename T4, typename T5, typename T6>
  19172. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5,T6>
  19173. column_selector(const details::column_list_impl<7>& col_list,
  19174. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6)
  19175. {
  19176. return
  19177. details::column_selector_impl
  19178. <T0,T1,T2,T3,T4,T5,T6>
  19179. (col_list,t0,t1,t2,t3,t4,t5,t6);
  19180. }
  19181. template <typename T0, typename T1, typename T2, typename T3,
  19182. typename T4, typename T5>
  19183. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5>
  19184. column_selector(const details::column_list_impl<6>& col_list,
  19185. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5)
  19186. {
  19187. return
  19188. details::column_selector_impl
  19189. <T0,T1,T2,T3,T4,T5>
  19190. (col_list,t0,t1,t2,t3,t4,t5);
  19191. }
  19192. template <typename T0, typename T1, typename T2,
  19193. typename T3, typename T4>
  19194. inline typename details::column_selector_impl<T0,T1,T2,T3,T4>
  19195. column_selector(const details::column_list_impl<5>& col_list,
  19196. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4)
  19197. {
  19198. return
  19199. details::column_selector_impl
  19200. <T0,T1,T2,T3,T4>
  19201. (col_list,t0,t1,t2,t3,t4);
  19202. }
  19203. template <typename T0, typename T1, typename T2, typename T3>
  19204. inline typename details::column_selector_impl<T0,T1,T2,T3>
  19205. column_selector(const details::column_list_impl<4>& col_list,
  19206. T0& t0, T1& t1, T2& t2, T3& t3)
  19207. {
  19208. return
  19209. details::column_selector_impl
  19210. <T0,T1,T2,T3>
  19211. (col_list,t0,t1,t2,t3);
  19212. }
  19213. template <typename T0, typename T1, typename T2>
  19214. inline typename details::column_selector_impl<T0,T1,T2>
  19215. column_selector(const details::column_list_impl<3>& col_list,
  19216. T0& t0, T1& t1, T2& t2)
  19217. {
  19218. return
  19219. details::column_selector_impl
  19220. <T0,T1,T2>
  19221. (col_list,t0,t1,t2);
  19222. }
  19223. template <typename T0, typename T1>
  19224. inline typename details::column_selector_impl<T0,T1>
  19225. column_selector(const details::column_list_impl<2>& col_list,
  19226. T0& t0, T1& t1)
  19227. {
  19228. return
  19229. details::column_selector_impl
  19230. <T0,T1>
  19231. (col_list,t0,t1);
  19232. }
  19233. template <typename T0>
  19234. inline typename details::column_selector_impl<T0>
  19235. column_selector(const details::column_list_impl<1>& col_list, T0& t0)
  19236. {
  19237. return
  19238. details::column_selector_impl
  19239. <T0>
  19240. (col_list,t0);
  19241. }
  19242. namespace details
  19243. {
  19244. template <typename Iterator>
  19245. inline Iterator inc(Iterator itr, const std::size_t& n)
  19246. {
  19247. std::advance(itr,n);
  19248. return itr;
  19249. }
  19250. //Single type column selectors
  19251. template <typename T, std::size_t N>
  19252. struct compose_st_selector_impl
  19253. {};
  19254. template <typename T>
  19255. struct compose_st_selector_impl <T,1>
  19256. {
  19257. typedef column_selector_impl<T> type;
  19258. typedef column_list_impl<1> column_list_t;
  19259. template <typename Allocator,
  19260. template <typename,typename> class Sequence>
  19261. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19262. {
  19263. return type(col_list,seq[0]);
  19264. }
  19265. template <typename Allocator>
  19266. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19267. {
  19268. typename std::list<T,Allocator>::iterator b = list.begin();
  19269. return type(col_list,*(b));
  19270. }
  19271. };
  19272. template <typename T>
  19273. struct compose_st_selector_impl <T,2>
  19274. {
  19275. typedef column_selector_impl<T,T> type;
  19276. typedef column_list_impl<2> column_list_t;
  19277. template <typename Allocator,
  19278. template <typename,typename> class Sequence>
  19279. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19280. {
  19281. return type(col_list,seq[0],seq[1]);
  19282. }
  19283. template <typename Allocator>
  19284. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19285. {
  19286. typename std::list<T,Allocator>::iterator b = list.begin();
  19287. return type(col_list,*(b),*inc(b,1));
  19288. }
  19289. };
  19290. template <typename T>
  19291. struct compose_st_selector_impl <T,3>
  19292. {
  19293. typedef column_selector_impl<T,T,T> type;
  19294. typedef column_list_impl<3> column_list_t;
  19295. template <typename Allocator,
  19296. template <typename,typename> class Sequence>
  19297. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19298. {
  19299. return type(col_list,seq[0],seq[1],seq[2]);
  19300. }
  19301. template <typename Allocator>
  19302. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19303. {
  19304. typename std::list<T,Allocator>::iterator b = list.begin();
  19305. return type(col_list,*(b),*inc(b,1),*inc(b,2));
  19306. }
  19307. };
  19308. template <typename T>
  19309. struct compose_st_selector_impl <T,4>
  19310. {
  19311. typedef column_selector_impl<T,T,T,T> type;
  19312. typedef column_list_impl<4> column_list_t;
  19313. template <typename Allocator,
  19314. template <typename,typename> class Sequence>
  19315. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19316. {
  19317. return type(col_list,seq[0],seq[1],seq[2],seq[3]);
  19318. }
  19319. template <typename Allocator>
  19320. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19321. {
  19322. typename std::list<T,Allocator>::iterator b = list.begin();
  19323. return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3));
  19324. }
  19325. };
  19326. template <typename T>
  19327. struct compose_st_selector_impl <T,5>
  19328. {
  19329. typedef column_selector_impl<T,T,T,T,T> type;
  19330. typedef column_list_impl<5> column_list_t;
  19331. template <typename Allocator,
  19332. template <typename,typename> class Sequence>
  19333. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19334. {
  19335. return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4]);
  19336. }
  19337. template <typename Allocator>
  19338. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19339. {
  19340. typename std::list<T,Allocator>::iterator b = list.begin();
  19341. return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4));
  19342. }
  19343. };
  19344. template <typename T>
  19345. struct compose_st_selector_impl <T,6>
  19346. {
  19347. typedef column_selector_impl<T,T,T,T,T,T> type;
  19348. typedef column_list_impl<6> column_list_t;
  19349. template <typename Allocator,
  19350. template <typename,typename> class Sequence>
  19351. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19352. {
  19353. return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5]);
  19354. }
  19355. template <typename Allocator>
  19356. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19357. {
  19358. typename std::list<T,Allocator>::iterator b = list.begin();
  19359. return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4),*inc(b,5));
  19360. }
  19361. };
  19362. template <typename T>
  19363. struct compose_st_selector_impl <T,7>
  19364. {
  19365. typedef column_selector_impl<T,T,T,T,T,T,T> type;
  19366. typedef column_list_impl<7> column_list_t;
  19367. template <typename Allocator,
  19368. template <typename,typename> class Sequence>
  19369. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19370. {
  19371. return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5],seq[6]);
  19372. }
  19373. template <typename Allocator>
  19374. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19375. {
  19376. typename std::list<T,Allocator>::iterator b = list.begin();
  19377. return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4),*inc(b,5),*inc(b,6));
  19378. }
  19379. };
  19380. template <typename T>
  19381. struct compose_st_selector_impl <T,8>
  19382. {
  19383. typedef column_selector_impl<T,T,T,T,T,T,T,T> type;
  19384. typedef column_list_impl<8> column_list_t;
  19385. template <typename Allocator,
  19386. template <typename,typename> class Sequence>
  19387. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19388. {
  19389. return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5],seq[6],seq[7]);
  19390. }
  19391. template <typename Allocator>
  19392. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19393. {
  19394. typename std::list<T,Allocator>::iterator b = list.begin();
  19395. return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4),*inc(b,5),*inc(b,6),*inc(b,7));
  19396. }
  19397. };
  19398. template <typename T>
  19399. struct compose_st_selector_impl <T,9>
  19400. {
  19401. typedef column_selector_impl<T,T,T,T,T,T,T,T,T> type;
  19402. typedef column_list_impl<9> column_list_t;
  19403. template <typename Allocator,
  19404. template <typename,typename> class Sequence>
  19405. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19406. {
  19407. return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5],seq[6],seq[7],seq[8]);
  19408. }
  19409. template <typename Allocator>
  19410. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19411. {
  19412. typename std::list<T,Allocator>::iterator b = list.begin();
  19413. return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4),*inc(b,5),*inc(b,6),*inc(b,7),*inc(b,8));
  19414. }
  19415. };
  19416. template <typename T>
  19417. struct compose_st_selector_impl <T,10>
  19418. {
  19419. typedef column_selector_impl<T,T,T,T,T,T,T,T,T,T> type;
  19420. typedef column_list_impl<10> column_list_t;
  19421. template <typename Allocator,
  19422. template <typename,typename> class Sequence>
  19423. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19424. {
  19425. return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5],seq[6],seq[7],seq[8],seq[9]);
  19426. }
  19427. template <typename Allocator>
  19428. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19429. {
  19430. typename std::list<T,Allocator>::iterator b = list.begin();
  19431. return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4),*inc(b,5),*inc(b,6),*inc(b,7),*inc(b,8),*inc(b,9));
  19432. }
  19433. };
  19434. }
  19435. template <std::size_t N,
  19436. typename T,
  19437. typename Allocator,
  19438. template <typename,typename> class Sequence>
  19439. inline typename details::compose_st_selector_impl<T,N>::type
  19440. column_selector(const details::column_list_impl<N>& col_list, Sequence<T,Allocator>& seq)
  19441. {
  19442. if (seq.size() >= N)
  19443. {
  19444. typedef typename details::compose_st_selector_impl<T,N> composer_t;
  19445. return composer_t::create(col_list,seq);
  19446. }
  19447. else
  19448. throw std::invalid_argument("column_selector(sequence/list) - size < N!");
  19449. }
  19450. namespace details
  19451. {
  19452. template <typename InputIterator, std::size_t N>
  19453. class column_selector_iterator_impl
  19454. {
  19455. public:
  19456. typedef column_selector_iterator_impl<InputIterator,N> csii_t;
  19457. typedef details::column_list_impl<N> column_list_t;
  19458. typedef std::pair<InputIterator,InputIterator> iterator_type;
  19459. typedef iterator_type* iterator_type_ptr;
  19460. column_selector_iterator_impl(const details::column_list_impl<N>& column_list,iterator_type (&token_list)[N])
  19461. : column_list_(column_list),
  19462. token_list_(token_list),
  19463. current_index_(0),
  19464. target_index_(column_list_.index_list[0]),
  19465. col_list_index_(0)
  19466. {}
  19467. inline csii_t& operator*()
  19468. {
  19469. return (*this);
  19470. }
  19471. inline csii_t& operator++()
  19472. {
  19473. return (*this);
  19474. }
  19475. inline csii_t operator++(int)
  19476. {
  19477. return (*this);
  19478. }
  19479. template <typename Iterator>
  19480. inline csii_t& operator=(const std::pair<Iterator,Iterator>& r)
  19481. {
  19482. if (current_index_ == target_index_)
  19483. {
  19484. token_list_[col_list_index_] = r;
  19485. ++col_list_index_;
  19486. if (col_list_index_ < column_list_t::size)
  19487. target_index_ = column_list_.index_list[col_list_index_];
  19488. else
  19489. target_index_ = std::numeric_limits<std::size_t>::max();
  19490. }
  19491. ++current_index_;
  19492. return (*this);
  19493. }
  19494. private:
  19495. csii_t& operator=(const csii_t& csb);
  19496. const column_list_t& column_list_;
  19497. iterator_type_ptr token_list_;
  19498. std::size_t current_index_;
  19499. std::size_t target_index_;
  19500. std::size_t col_list_index_;
  19501. };
  19502. }
  19503. #define strtk_parse_col_token(Index)\
  19504. if (!string_to_type_converter(token_list[Index].first,token_list[Index].second,t##Index)) return false;
  19505. #define strtk_parse_col_token_seq(Index)\
  19506. if (!string_to_type_converter(token_list[Index].first,token_list[Index].second,seq[Index])) return false;
  19507. #define strtk_parse_columns_impl(NN)\
  19508. static const std::size_t N = NN;\
  19509. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;\
  19510. typedef std::pair<InputIterator,InputIterator> iterator_type;\
  19511. typedef details::column_selector_iterator_impl<InputIterator,N> csii_t;\
  19512. const std::size_t token_count = (column_list.index_list[N - 1] + 1);\
  19513. iterator_type token_list[N];\
  19514. csii_t csii(column_list,token_list);\
  19515. const std::size_t parsed_token_count = split_n<InputIterator,csii_t&>\
  19516. (delimiters,begin,end,token_count,csii,split_options::compress_delimiters);\
  19517. if (token_count > parsed_token_count) return false;\
  19518. #define strk_parse_col_seq\
  19519. return parse_columns(data.data(),data.data() + data.size(),delimiters,column_list,seq);
  19520. template <typename InputIterator,
  19521. typename T0, typename T1, typename T2, typename T3, typename T4,
  19522. typename T5, typename T6, typename T7, typename T8, typename T9,
  19523. typename T10, typename T11>
  19524. inline bool parse_columns(const InputIterator begin,
  19525. const InputIterator end,
  19526. const std::string& delimiters,
  19527. const details::column_list_impl<12>& column_list,
  19528. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19529. T6& t6, T7& t7, T8& t8, T9& t9, T10& t10, T11& t11)
  19530. {
  19531. strtk_parse_columns_impl(12)
  19532. strtk_parse_col_token( 0) strtk_parse_col_token( 1)
  19533. strtk_parse_col_token( 2) strtk_parse_col_token( 3)
  19534. strtk_parse_col_token( 4) strtk_parse_col_token( 5)
  19535. strtk_parse_col_token( 6) strtk_parse_col_token( 7)
  19536. strtk_parse_col_token( 8) strtk_parse_col_token( 9)
  19537. strtk_parse_col_token(10) strtk_parse_col_token(11)
  19538. return true;
  19539. }
  19540. template <typename InputIterator,
  19541. typename T0, typename T1, typename T2, typename T3, typename T4,
  19542. typename T5, typename T6, typename T7, typename T8, typename T9,
  19543. typename T10>
  19544. inline bool parse_columns(const InputIterator begin,
  19545. const InputIterator end,
  19546. const std::string& delimiters,
  19547. const details::column_list_impl<11>& column_list,
  19548. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19549. T6& t6, T7& t7, T8& t8, T9& t9, T10& t10)
  19550. {
  19551. strtk_parse_columns_impl(11)
  19552. strtk_parse_col_token( 0) strtk_parse_col_token(1)
  19553. strtk_parse_col_token( 2) strtk_parse_col_token(3)
  19554. strtk_parse_col_token( 4) strtk_parse_col_token(5)
  19555. strtk_parse_col_token( 6) strtk_parse_col_token(7)
  19556. strtk_parse_col_token( 8) strtk_parse_col_token(9)
  19557. strtk_parse_col_token(10)
  19558. return true;
  19559. }
  19560. template <typename InputIterator,
  19561. typename T0, typename T1, typename T2, typename T3, typename T4,
  19562. typename T5, typename T6, typename T7, typename T8, typename T9>
  19563. inline bool parse_columns(const InputIterator begin,
  19564. const InputIterator end,
  19565. const std::string& delimiters,
  19566. const details::column_list_impl<10>& column_list,
  19567. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19568. T6& t6, T7& t7, T8& t8, T9& t9)
  19569. {
  19570. strtk_parse_columns_impl(10)
  19571. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19572. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19573. strtk_parse_col_token(4) strtk_parse_col_token(5)
  19574. strtk_parse_col_token(6) strtk_parse_col_token(7)
  19575. strtk_parse_col_token(8) strtk_parse_col_token(9)
  19576. return true;
  19577. }
  19578. template <typename InputIterator,
  19579. typename T0, typename T1, typename T2, typename T3, typename T4,
  19580. typename T5, typename T6, typename T7, typename T8>
  19581. inline bool parse_columns(const InputIterator begin,
  19582. const InputIterator end,
  19583. const std::string& delimiters,
  19584. const details::column_list_impl<9>& column_list,
  19585. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  19586. T7& t7, T8& t8)
  19587. {
  19588. strtk_parse_columns_impl(9)
  19589. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19590. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19591. strtk_parse_col_token(4) strtk_parse_col_token(5)
  19592. strtk_parse_col_token(6) strtk_parse_col_token(7)
  19593. strtk_parse_col_token(8)
  19594. return true;
  19595. }
  19596. template <typename InputIterator,
  19597. typename T0, typename T1, typename T2, typename T3, typename T4,
  19598. typename T5, typename T6, typename T7>
  19599. inline bool parse_columns(const InputIterator begin,
  19600. const InputIterator end,
  19601. const std::string& delimiters,
  19602. const details::column_list_impl<8>& column_list,
  19603. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7)
  19604. {
  19605. strtk_parse_columns_impl(8)
  19606. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19607. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19608. strtk_parse_col_token(4) strtk_parse_col_token(5)
  19609. strtk_parse_col_token(6) strtk_parse_col_token(7)
  19610. return true;
  19611. }
  19612. template <typename InputIterator,
  19613. typename T0, typename T1, typename T2, typename T3, typename T4,
  19614. typename T5, typename T6>
  19615. inline bool parse_columns(const InputIterator begin,
  19616. const InputIterator end,
  19617. const std::string& delimiters,
  19618. const details::column_list_impl<7>& column_list,
  19619. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6)
  19620. {
  19621. strtk_parse_columns_impl(7)
  19622. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19623. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19624. strtk_parse_col_token(4) strtk_parse_col_token(5)
  19625. strtk_parse_col_token(6)
  19626. return true;
  19627. }
  19628. template <typename InputIterator,
  19629. typename T0, typename T1, typename T2, typename T3, typename T4,
  19630. typename T5>
  19631. inline bool parse_columns(const InputIterator begin,
  19632. const InputIterator end,
  19633. const std::string& delimiters,
  19634. const details::column_list_impl<6>& column_list,
  19635. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5)
  19636. {
  19637. strtk_parse_columns_impl(6)
  19638. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19639. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19640. strtk_parse_col_token(4) strtk_parse_col_token(5)
  19641. return true;
  19642. }
  19643. template <typename InputIterator,
  19644. typename T0, typename T1, typename T2, typename T3, typename T4>
  19645. inline bool parse_columns(const InputIterator begin,
  19646. const InputIterator end,
  19647. const std::string& delimiters,
  19648. const details::column_list_impl<5>& column_list,
  19649. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4)
  19650. {
  19651. strtk_parse_columns_impl(5)
  19652. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19653. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19654. strtk_parse_col_token(4)
  19655. return true;
  19656. }
  19657. template <typename InputIterator,
  19658. typename T0, typename T1, typename T2, typename T3>
  19659. inline bool parse_columns(const InputIterator begin,
  19660. const InputIterator end,
  19661. const std::string& delimiters,
  19662. const details::column_list_impl<4>& column_list,
  19663. T0& t0, T1& t1, T2& t2, T3& t3)
  19664. {
  19665. strtk_parse_columns_impl(4)
  19666. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19667. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19668. return true;
  19669. }
  19670. template <typename InputIterator,
  19671. typename T0, typename T1, typename T2>
  19672. inline bool parse_columns(const InputIterator begin,
  19673. const InputIterator end,
  19674. const std::string& delimiters,
  19675. const details::column_list_impl<3>& column_list,
  19676. T0& t0, T1& t1, T2& t2)
  19677. {
  19678. strtk_parse_columns_impl(3)
  19679. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19680. strtk_parse_col_token(2)
  19681. return true;
  19682. }
  19683. template <typename InputIterator,
  19684. typename T0, typename T1>
  19685. inline bool parse_columns(const InputIterator begin,
  19686. const InputIterator end,
  19687. const std::string& delimiters,
  19688. const details::column_list_impl<2>& column_list,
  19689. T0& t0, T1& t1)
  19690. {
  19691. strtk_parse_columns_impl(2)
  19692. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19693. return true;
  19694. }
  19695. template <typename InputIterator,
  19696. typename T0>
  19697. inline bool parse_columns(const InputIterator begin,
  19698. const InputIterator end,
  19699. const std::string& delimiters,
  19700. const details::column_list_impl<1>& column_list,
  19701. T0& t0)
  19702. {
  19703. strtk_parse_columns_impl(1)
  19704. strtk_parse_col_token(0)
  19705. return true;
  19706. }
  19707. template <typename InputIterator,
  19708. typename T,
  19709. typename Allocator,
  19710. template <typename,typename> class Sequence>
  19711. inline bool parse_columns(const InputIterator begin,
  19712. const InputIterator end,
  19713. const std::string& delimiters,
  19714. const details::column_list_impl<12>& column_list,
  19715. Sequence<T,Allocator>& seq)
  19716. {
  19717. strtk_parse_columns_impl(12)
  19718. strtk_parse_col_token_seq( 0) strtk_parse_col_token_seq( 1)
  19719. strtk_parse_col_token_seq( 2) strtk_parse_col_token_seq( 3)
  19720. strtk_parse_col_token_seq( 4) strtk_parse_col_token_seq( 5)
  19721. strtk_parse_col_token_seq( 6) strtk_parse_col_token_seq( 7)
  19722. strtk_parse_col_token_seq( 8) strtk_parse_col_token_seq( 9)
  19723. strtk_parse_col_token_seq(10) strtk_parse_col_token_seq(11)
  19724. return true;
  19725. }
  19726. template <typename InputIterator,
  19727. typename T,
  19728. typename Allocator,
  19729. template <typename,typename> class Sequence>
  19730. inline bool parse_columns(const InputIterator begin,
  19731. const InputIterator end,
  19732. const std::string& delimiters,
  19733. const details::column_list_impl<11>& column_list,
  19734. Sequence<T,Allocator>& seq)
  19735. {
  19736. strtk_parse_columns_impl(11)
  19737. strtk_parse_col_token_seq( 0) strtk_parse_col_token_seq(1)
  19738. strtk_parse_col_token_seq( 2) strtk_parse_col_token_seq(3)
  19739. strtk_parse_col_token_seq( 4) strtk_parse_col_token_seq(5)
  19740. strtk_parse_col_token_seq( 6) strtk_parse_col_token_seq(7)
  19741. strtk_parse_col_token_seq( 8) strtk_parse_col_token_seq(9)
  19742. strtk_parse_col_token_seq(10)
  19743. return true;
  19744. }
  19745. template <typename InputIterator,
  19746. typename T,
  19747. typename Allocator,
  19748. template <typename,typename> class Sequence>
  19749. inline bool parse_columns(const InputIterator begin,
  19750. const InputIterator end,
  19751. const std::string& delimiters,
  19752. const details::column_list_impl<10>& column_list,
  19753. Sequence<T,Allocator>& seq)
  19754. {
  19755. strtk_parse_columns_impl(10)
  19756. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  19757. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  19758. strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5)
  19759. strtk_parse_col_token_seq(6) strtk_parse_col_token_seq(7)
  19760. strtk_parse_col_token_seq(8) strtk_parse_col_token_seq(9)
  19761. return true;
  19762. }
  19763. template <typename InputIterator,
  19764. typename T,
  19765. typename Allocator,
  19766. template <typename,typename> class Sequence>
  19767. inline bool parse_columns(const InputIterator begin,
  19768. const InputIterator end,
  19769. const std::string& delimiters,
  19770. const details::column_list_impl<9>& column_list,
  19771. Sequence<T,Allocator>& seq)
  19772. {
  19773. strtk_parse_columns_impl(9)
  19774. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  19775. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  19776. strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5)
  19777. strtk_parse_col_token_seq(6) strtk_parse_col_token_seq(7)
  19778. strtk_parse_col_token_seq(8)
  19779. return true;
  19780. }
  19781. template <typename InputIterator,
  19782. typename T,
  19783. typename Allocator,
  19784. template <typename,typename> class Sequence>
  19785. inline bool parse_columns(const InputIterator begin,
  19786. const InputIterator end,
  19787. const std::string& delimiters,
  19788. const details::column_list_impl<8>& column_list,
  19789. Sequence<T,Allocator>& seq)
  19790. {
  19791. strtk_parse_columns_impl(8)
  19792. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  19793. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  19794. strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5)
  19795. strtk_parse_col_token_seq(6) strtk_parse_col_token_seq(7)
  19796. return true;
  19797. }
  19798. template <typename InputIterator,
  19799. typename T,
  19800. typename Allocator,
  19801. template <typename,typename> class Sequence>
  19802. inline bool parse_columns(const InputIterator begin,
  19803. const InputIterator end,
  19804. const std::string& delimiters,
  19805. const details::column_list_impl<7>& column_list,
  19806. Sequence<T,Allocator>& seq)
  19807. {
  19808. strtk_parse_columns_impl(7)
  19809. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  19810. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  19811. strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5)
  19812. strtk_parse_col_token_seq(6)
  19813. return true;
  19814. }
  19815. template <typename InputIterator,
  19816. typename T,
  19817. typename Allocator,
  19818. template <typename,typename> class Sequence>
  19819. inline bool parse_columns(const InputIterator begin,
  19820. const InputIterator end,
  19821. const std::string& delimiters,
  19822. const details::column_list_impl<6>& column_list,
  19823. Sequence<T,Allocator>& seq)
  19824. {
  19825. strtk_parse_columns_impl(6)
  19826. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  19827. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  19828. strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5)
  19829. return true;
  19830. }
  19831. template <typename InputIterator,
  19832. typename T,
  19833. typename Allocator,
  19834. template <typename,typename> class Sequence>
  19835. inline bool parse_columns(const InputIterator begin,
  19836. const InputIterator end,
  19837. const std::string& delimiters,
  19838. const details::column_list_impl<5>& column_list,
  19839. Sequence<T,Allocator>& seq)
  19840. {
  19841. strtk_parse_columns_impl(5)
  19842. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  19843. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  19844. strtk_parse_col_token_seq(4)
  19845. return true;
  19846. }
  19847. template <typename InputIterator,
  19848. typename T,
  19849. typename Allocator,
  19850. template <typename,typename> class Sequence>
  19851. inline bool parse_columns(const InputIterator begin,
  19852. const InputIterator end,
  19853. const std::string& delimiters,
  19854. const details::column_list_impl<4>& column_list,
  19855. Sequence<T,Allocator>& seq)
  19856. {
  19857. strtk_parse_columns_impl(4)
  19858. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  19859. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  19860. return true;
  19861. }
  19862. template <typename InputIterator,
  19863. typename T,
  19864. typename Allocator,
  19865. template <typename,typename> class Sequence>
  19866. inline bool parse_columns(const InputIterator begin,
  19867. const InputIterator end,
  19868. const std::string& delimiters,
  19869. const details::column_list_impl<3>& column_list,
  19870. Sequence<T,Allocator>& seq)
  19871. {
  19872. strtk_parse_columns_impl(3)
  19873. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  19874. strtk_parse_col_token_seq(2)
  19875. return true;
  19876. }
  19877. template <typename InputIterator,
  19878. typename T,
  19879. typename Allocator,
  19880. template <typename,typename> class Sequence>
  19881. inline bool parse_columns(const InputIterator begin,
  19882. const InputIterator end,
  19883. const std::string& delimiters,
  19884. const details::column_list_impl<2>& column_list,
  19885. Sequence<T,Allocator>& seq)
  19886. {
  19887. strtk_parse_columns_impl(2)
  19888. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  19889. return true;
  19890. }
  19891. template <typename InputIterator,
  19892. typename T,
  19893. typename Allocator,
  19894. template <typename,typename> class Sequence>
  19895. inline bool parse_columns(const InputIterator begin,
  19896. const InputIterator end,
  19897. const std::string& delimiters,
  19898. const details::column_list_impl<1>& column_list,
  19899. Sequence<T,Allocator>& seq)
  19900. {
  19901. strtk_parse_columns_impl(1)
  19902. strtk_parse_col_token_seq(0)
  19903. return true;
  19904. }
  19905. #undef strtk_parse_col_token
  19906. #undef strtk_parse_col_token_seq
  19907. #undef strtk_parse_columns_impl
  19908. #define strtk_parse_col_begin()\
  19909. return parse_columns(data.data(),\
  19910. data.data() + data.size(),delimiters,\
  19911. column_list,
  19912. #define strtk_parse_col_end() );
  19913. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  19914. typename T5, typename T6, typename T7, typename T8, typename T9,
  19915. typename T10, typename T11>
  19916. inline bool parse_columns(const std::string& data,
  19917. const std::string& delimiters,
  19918. const details::column_list_impl<12>& column_list,
  19919. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  19920. T5& t5, T6& t6, T7& t7, T8& t8, T9& t9,
  19921. T10& t10, T11& t11)
  19922. {
  19923. strtk_parse_col_begin()
  19924. t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11
  19925. strtk_parse_col_end()
  19926. }
  19927. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  19928. typename T5, typename T6, typename T7, typename T8, typename T9,
  19929. typename T10>
  19930. inline bool parse_columns(const std::string& data,
  19931. const std::string& delimiters,
  19932. const details::column_list_impl<11>& column_list,
  19933. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  19934. T5& t5, T6& t6, T7& t7, T8& t8, T9& t9,
  19935. T10& t10)
  19936. {
  19937. strtk_parse_col_begin()
  19938. t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10
  19939. strtk_parse_col_end()
  19940. }
  19941. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  19942. typename T5, typename T6, typename T7, typename T8, typename T9>
  19943. inline bool parse_columns(const std::string& data,
  19944. const std::string& delimiters,
  19945. const details::column_list_impl<10>& column_list,
  19946. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  19947. T5& t5, T6& t6, T7& t7, T8& t8,
  19948. T9& t9)
  19949. {
  19950. strtk_parse_col_begin()
  19951. t0,t1,t2,t3,t4,t5,t6,t7,t8,t9
  19952. strtk_parse_col_end()
  19953. }
  19954. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  19955. typename T5, typename T6, typename T7, typename T8>
  19956. inline bool parse_columns(const std::string& data,
  19957. const std::string& delimiters,
  19958. const details::column_list_impl<9>& column_list,
  19959. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  19960. T5& t5, T6& t6, T7& t7, T8& t8)
  19961. {
  19962. strtk_parse_col_begin()
  19963. t0,t1,t2,t3,t4,t5,t6,t7,t8
  19964. strtk_parse_col_end()
  19965. }
  19966. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  19967. typename T5, typename T6, typename T7>
  19968. inline bool parse_columns(const std::string& data,
  19969. const std::string& delimiters,
  19970. const details::column_list_impl<8>& column_list,
  19971. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  19972. T5& t5, T6& t6, T7& t7)
  19973. {
  19974. strtk_parse_col_begin()
  19975. t0,t1,t2,t3,t4,t5,t6,t7
  19976. strtk_parse_col_end()
  19977. }
  19978. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  19979. typename T5, typename T6>
  19980. inline bool parse_columns(const std::string& data,
  19981. const std::string& delimiters,
  19982. const details::column_list_impl<7>& column_list,
  19983. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  19984. T5& t5, T6& t6)
  19985. {
  19986. strtk_parse_col_begin()
  19987. t0,t1,t2,t3,t4,t5,t6
  19988. strtk_parse_col_end()
  19989. }
  19990. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  19991. typename T5>
  19992. inline bool parse_columns(const std::string& data,
  19993. const std::string& delimiters,
  19994. const details::column_list_impl<6>& column_list,
  19995. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  19996. T5& t5)
  19997. {
  19998. strtk_parse_col_begin()
  19999. t0,t1,t2,t3,t4,t5
  20000. strtk_parse_col_end()
  20001. }
  20002. template <typename T0, typename T1, typename T2, typename T3, typename T4>
  20003. inline bool parse_columns(const std::string& data,
  20004. const std::string& delimiters,
  20005. const details::column_list_impl<5>& column_list,
  20006. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4)
  20007. {
  20008. strtk_parse_col_begin()
  20009. t0,t1,t2,t3,t4
  20010. strtk_parse_col_end()
  20011. }
  20012. template <typename T0, typename T1, typename T2, typename T3>
  20013. inline bool parse_columns(const std::string& data,
  20014. const std::string& delimiters,
  20015. const details::column_list_impl<4>& column_list,
  20016. T0& t0, T1& t1, T2& t2, T3& t3)
  20017. {
  20018. strtk_parse_col_begin()
  20019. t0,t1,t2,t3
  20020. strtk_parse_col_end();
  20021. }
  20022. template <typename T0, typename T1, typename T2>
  20023. inline bool parse_columns(const std::string& data,
  20024. const std::string& delimiters,
  20025. const details::column_list_impl<3>& column_list,
  20026. T0& t0, T1& t1, T2& t2)
  20027. {
  20028. strtk_parse_col_begin()
  20029. t0,t1,t2
  20030. strtk_parse_col_end()
  20031. }
  20032. template <typename T0, typename T1>
  20033. inline bool parse_columns(const std::string& data,
  20034. const std::string& delimiters,
  20035. const details::column_list_impl<2>& column_list,
  20036. T0& t0, T1& t1)
  20037. {
  20038. strtk_parse_col_begin()
  20039. t0,t1
  20040. strtk_parse_col_end()
  20041. }
  20042. template <typename T>
  20043. inline bool parse_columns(const std::string& data,
  20044. const std::string& delimiters,
  20045. const details::column_list_impl<1>& column_list,
  20046. T& t)
  20047. {
  20048. strtk_parse_col_begin()
  20049. t
  20050. strtk_parse_col_end()
  20051. }
  20052. #undef strtk_parse_col_begin
  20053. #undef strtk_parse_col_end
  20054. template <typename T,
  20055. typename Allocator,
  20056. template <typename,typename> class Sequence>
  20057. inline bool parse_columns(const std::string& data,
  20058. const std::string& delimiters,
  20059. const details::column_list_impl<12>& column_list,
  20060. Sequence<T,Allocator>& seq)
  20061. {
  20062. strk_parse_col_seq
  20063. }
  20064. template <typename T,
  20065. typename Allocator,
  20066. template <typename,typename> class Sequence>
  20067. inline bool parse_columns(const std::string& data,
  20068. const std::string& delimiters,
  20069. const details::column_list_impl<11>& column_list,
  20070. Sequence<T,Allocator>& seq)
  20071. {
  20072. strk_parse_col_seq
  20073. }
  20074. template <typename T,
  20075. typename Allocator,
  20076. template <typename,typename> class Sequence>
  20077. inline bool parse_columns(const std::string& data,
  20078. const std::string& delimiters,
  20079. const details::column_list_impl<10>& column_list,
  20080. Sequence<T,Allocator>& seq)
  20081. {
  20082. strk_parse_col_seq
  20083. }
  20084. template <typename T,
  20085. typename Allocator,
  20086. template <typename,typename> class Sequence>
  20087. inline bool parse_columns(const std::string& data,
  20088. const std::string& delimiters,
  20089. const details::column_list_impl<9>& column_list,
  20090. Sequence<T,Allocator>& seq)
  20091. {
  20092. strk_parse_col_seq
  20093. }
  20094. template <typename T,
  20095. typename Allocator,
  20096. template <typename,typename> class Sequence>
  20097. inline bool parse_columns(const std::string& data,
  20098. const std::string& delimiters,
  20099. const details::column_list_impl<8>& column_list,
  20100. Sequence<T,Allocator>& seq)
  20101. {
  20102. strk_parse_col_seq
  20103. }
  20104. template <typename T,
  20105. typename Allocator,
  20106. template <typename,typename> class Sequence>
  20107. inline bool parse_columns(const std::string& data,
  20108. const std::string& delimiters,
  20109. const details::column_list_impl<7>& column_list,
  20110. Sequence<T,Allocator>& seq)
  20111. {
  20112. strk_parse_col_seq
  20113. }
  20114. template <typename T,
  20115. typename Allocator,
  20116. template <typename,typename> class Sequence>
  20117. inline bool parse_columns(const std::string& data,
  20118. const std::string& delimiters,
  20119. const details::column_list_impl<6>& column_list,
  20120. Sequence<T,Allocator>& seq)
  20121. {
  20122. strk_parse_col_seq
  20123. }
  20124. template <typename T,
  20125. typename Allocator,
  20126. template <typename,typename> class Sequence>
  20127. inline bool parse_columns(const std::string& data,
  20128. const std::string& delimiters,
  20129. const details::column_list_impl<5>& column_list,
  20130. Sequence<T,Allocator>& seq)
  20131. {
  20132. strk_parse_col_seq
  20133. }
  20134. template <typename T,
  20135. typename Allocator,
  20136. template <typename,typename> class Sequence>
  20137. inline bool parse_columns(const std::string& data,
  20138. const std::string& delimiters,
  20139. const details::column_list_impl<4>& column_list,
  20140. Sequence<T,Allocator>& seq)
  20141. {
  20142. strk_parse_col_seq
  20143. }
  20144. template <typename T,
  20145. typename Allocator,
  20146. template <typename,typename> class Sequence>
  20147. inline bool parse_columns(const std::string& data,
  20148. const std::string& delimiters,
  20149. const details::column_list_impl<3>& column_list,
  20150. Sequence<T,Allocator>& seq)
  20151. {
  20152. strk_parse_col_seq
  20153. }
  20154. template <typename T,
  20155. typename Allocator,
  20156. template <typename,typename> class Sequence>
  20157. inline bool parse_columns(const std::string& data,
  20158. const std::string& delimiters,
  20159. const details::column_list_impl<2>& column_list,
  20160. Sequence<T,Allocator>& seq)
  20161. {
  20162. strk_parse_col_seq
  20163. }
  20164. template <typename T,
  20165. typename Allocator,
  20166. template <typename,typename> class Sequence>
  20167. inline bool parse_columns(const std::string& data,
  20168. const std::string& delimiters,
  20169. const details::column_list_impl<1>& column_list,
  20170. Sequence<T,Allocator>& seq)
  20171. {
  20172. strk_parse_col_seq
  20173. }
  20174. #undef strk_parse_col_seq
  20175. namespace details
  20176. {
  20177. typedef const unsigned char* ptr;
  20178. template <typename T>
  20179. bool cmpimpl(ptr c1, ptr c2) { return (*reinterpret_cast<T>(c1)) == (*reinterpret_cast<T>(c2)); }
  20180. template <std::size_t K>
  20181. struct size_impl { static inline bool cmp(ptr,ptr) { return true; } };
  20182. template <>
  20183. struct size_impl<8> { static inline bool cmp(ptr c1, ptr c2) { return cmpimpl<const unsigned long long*>(c1,c2); } };
  20184. template <>
  20185. struct size_impl<4> { static inline bool cmp(ptr c1, ptr c2) { return cmpimpl<const unsigned int*>(c1,c2); } };
  20186. template <>
  20187. struct size_impl<2> { static inline bool cmp(ptr c1, ptr c2) { return cmpimpl<const unsigned short*>(c1,c2); } };
  20188. template <>
  20189. struct size_impl<1> { static inline bool cmp(ptr c1, ptr c2) { return cmpimpl<const unsigned char*>(c1,c2); } };
  20190. template <std::size_t N>
  20191. struct next_size { enum { size = (N >= 8) ? 8 : ((N >= 4) ? 4 : ((N >= 2) ? 2 : 1)) }; };
  20192. template <std::size_t N>
  20193. struct memcmp_n_impl
  20194. {
  20195. static inline bool process(details::ptr c1, details::ptr c2)
  20196. {
  20197. static const std::size_t size = details::next_size<N>::size;
  20198. return details::size_impl<size>::cmp(c1,c2) && memcmp_n_impl<N - size>::process(c1 + size, c2 + size);
  20199. }
  20200. static inline bool process(const char* c1, const char* c2)
  20201. {
  20202. return memcmp_n_impl<N>::process(reinterpret_cast<details::ptr>(c1),reinterpret_cast<details::ptr>(c2));
  20203. }
  20204. template <std::size_t K1, std::size_t K2>
  20205. static inline bool process(const unsigned char (&c1)[K1], const unsigned char (&c2)[K2])
  20206. {
  20207. return memcmp_n_impl<N>::process(static_cast<ptr>(c1),static_cast<ptr>(c2));
  20208. }
  20209. };
  20210. template<> struct memcmp_n_impl<0> { static inline bool process(ptr,ptr) { return true; } };
  20211. }
  20212. template <std::size_t N>
  20213. inline bool memcmp_n(details::ptr c1, details::ptr c2)
  20214. {
  20215. return details::memcmp_n_impl<N>::process(c1,c2);
  20216. }
  20217. template <std::size_t N>
  20218. inline bool memcmp_n(const char* c1, const char* c2)
  20219. {
  20220. return details::memcmp_n_impl<N>::process(c1,c2);
  20221. }
  20222. template <std::size_t N,std::size_t K1, std::size_t K2>
  20223. inline bool memcmp_n(const unsigned char (&c1)[K1], const unsigned char (&c2)[K2])
  20224. {
  20225. return details::memcmp_n_impl<N>::process(c1,c2);
  20226. }
  20227. namespace details
  20228. {
  20229. inline bool type_to_string_converter_impl(const strtk::util::value& v, std::string& result, value_type_tag)
  20230. {
  20231. return v.to_string(result);
  20232. }
  20233. }
  20234. template <typename Iterator>
  20235. inline std::size_t distance(const std::pair<Iterator,Iterator>& p)
  20236. {
  20237. return std::distance(p.first,p.second);
  20238. }
  20239. template <typename Iterator1, typename Iterator2>
  20240. inline std::pair<Iterator1,Iterator2> make_pair(const std::string& s)
  20241. {
  20242. return std::make_pair<Iterator1,Iterator2>(
  20243. reinterpret_cast<Iterator1>(const_cast<char*>(s.data())),
  20244. reinterpret_cast<Iterator2>(const_cast<char*>(s.data() + s.size())));
  20245. }
  20246. template <typename Iterator1, typename Iterator2>
  20247. inline std::pair<Iterator1,Iterator2> make_pair(const std::pair<const char*, const char*> p)
  20248. {
  20249. return std::make_pair<Iterator1,Iterator2>(
  20250. reinterpret_cast<Iterator1>(const_cast<char*>(p.first)),
  20251. reinterpret_cast<Iterator2>(const_cast<char*>(p.second)));
  20252. }
  20253. template <typename Iterator>
  20254. inline std::pair<Iterator,Iterator> make_pair(const std::string& s)
  20255. {
  20256. return make_pair<Iterator,Iterator>(s);
  20257. }
  20258. template <typename Iterator>
  20259. inline std::pair<Iterator,Iterator> make_pair(const std::pair<const char*, const char*>& p)
  20260. {
  20261. return make_pair<Iterator,Iterator>(p);
  20262. }
  20263. template <typename Iterator1, typename Iterator2>
  20264. inline std::pair<Iterator1,Iterator2> make_pair(const strtk::range::string& range)
  20265. {
  20266. return std::make_pair<Iterator1,Iterator2>(
  20267. reinterpret_cast<Iterator1>(const_cast<char*>(range.begin())),
  20268. reinterpret_cast<Iterator2>(const_cast<char*>(range.end())));
  20269. }
  20270. template <std::size_t N>
  20271. inline std::string make_string(const unsigned char (&s)[N], const std::size_t& length = N)
  20272. {
  20273. static const std::string null_string;
  20274. if (N < length)
  20275. return null_string;
  20276. else
  20277. return std::string(&s[0],&s[0] + length);
  20278. }
  20279. template <std::size_t N>
  20280. inline std::string make_string(const char (&s)[N], const std::size_t& length = N)
  20281. {
  20282. static const std::string null_string;
  20283. if (N < length)
  20284. return null_string;
  20285. else
  20286. return std::string(&s[0],&s[0] + length);
  20287. }
  20288. inline std::string make_string(const std::pair<const char*,const char*>& range)
  20289. {
  20290. return std::string(range.first,range.second);
  20291. }
  20292. template <typename T, std::size_t N>
  20293. inline bool clear_array(T (&a)[N], const T& t, const std::size_t& length = N)
  20294. {
  20295. if (N < length)
  20296. return false;
  20297. else
  20298. std::fill_n(&a[0],length,t);
  20299. return true;
  20300. }
  20301. template <std::size_t N>
  20302. inline bool set_array(unsigned char (&a)[N],
  20303. const std::string& s,
  20304. const bool pad = false,
  20305. const unsigned char padding = '0')
  20306. {
  20307. if (N < s.size())
  20308. return false;
  20309. std::copy(s.data(),s.data() + s.size(), &a[0]);
  20310. if ((s.size() < N) && pad)
  20311. std::fill_n(&a[s.size()],N - s.size(),padding);
  20312. return true;
  20313. }
  20314. template <std::size_t N, std::size_t M>
  20315. inline bool set_array(unsigned char (&dest)[N],
  20316. unsigned char (&src)[M],
  20317. const bool pad = false,
  20318. const unsigned char padding = '0')
  20319. {
  20320. if (N < M)
  20321. return false;
  20322. std::copy(src,src + N, &dest[0]);
  20323. if ((M < N) && pad)
  20324. std::fill_n(&dest[M],N - M,padding);
  20325. return true;
  20326. }
  20327. inline void reverse(const std_string::iterator_type& range)
  20328. {
  20329. char* begin = const_cast<char*>(range.first);
  20330. char* end = const_cast<char*>(range.second);
  20331. std::reverse(begin,end);
  20332. }
  20333. template <typename T>
  20334. inline void reverse(const range::adapter<T>& r)
  20335. {
  20336. T* begin = const_cast<T*>(r.begin());
  20337. T* end = const_cast<T*>(r.end());
  20338. std::reverse(begin,end);
  20339. }
  20340. template <typename T>
  20341. inline void reverse(const range::adapter<const T>& r)
  20342. {
  20343. T* begin = const_cast<T*>(r.begin());
  20344. T* end = const_cast<T*>(r.end());
  20345. std::reverse(begin,end);
  20346. }
  20347. inline void reverse(std::string& s)
  20348. {
  20349. std::reverse(s.begin(),s.end());
  20350. }
  20351. inline void fill(std::string& s, const std::string::value_type v)
  20352. {
  20353. std::fill(const_cast<char*>(s.data()),const_cast<char*>(s.data() + s.size()), v);
  20354. }
  20355. inline void fill(const std::pair<const char*,const char*>& range, char v)
  20356. {
  20357. char* begin = const_cast<char*>(range.first);
  20358. char* end = const_cast<char*>(range.second);
  20359. std::fill(begin,end,v);
  20360. }
  20361. template <typename T>
  20362. inline void fill(const range::adapter<const T>& r, const typename range::adapter<const T>::value_type& v)
  20363. {
  20364. char* begin = const_cast<char*>(r.begin());
  20365. char* end = const_cast<char*>(r.end());
  20366. std::fill(begin,end,v);
  20367. }
  20368. inline void fill(const std_string::iterator_type& range, const std::string::value_type& v)
  20369. {
  20370. char* begin = const_cast<char*>(range.first);
  20371. char* end = const_cast<char*>(range.second);
  20372. std::fill(begin,end,v);
  20373. }
  20374. template <typename T,
  20375. typename Allocator,
  20376. template <typename,typename> class Sequence>
  20377. inline void fill(Sequence<T,Allocator>& seq, const T& t)
  20378. {
  20379. if (seq.empty())
  20380. return;
  20381. fill_n(seq.begin(),seq.size(),t);
  20382. }
  20383. namespace keyvalue
  20384. {
  20385. template <typename CharType>
  20386. struct options
  20387. {
  20388. typedef CharType char_type;
  20389. options()
  20390. : pair_block_delimiter(0),
  20391. pair_delimiter(0)
  20392. {}
  20393. char_type pair_block_delimiter;
  20394. char_type pair_delimiter;
  20395. };
  20396. template <typename KeyValueMap>
  20397. class parser
  20398. {
  20399. public:
  20400. typedef unsigned char char_type;
  20401. typedef std::pair<char_type*,char_type*> range_type;
  20402. template <typename Options>
  20403. parser(const Options& opts)
  20404. : options_(opts),
  20405. kv_map_(opts),
  20406. pair_block_sdp_(options_.pair_block_delimiter),
  20407. pair_delimiter_sdp_(options_.pair_delimiter)
  20408. {
  20409. pair_list_.reserve(strtk::one_kilobyte);
  20410. }
  20411. template <typename T>
  20412. inline bool register_keyvalue(const typename KeyValueMap::key_type& key, T& t)
  20413. {
  20414. return kv_map_.register_keyvalue(key,t);
  20415. }
  20416. inline bool operator()(const range_type& data, const bool ignore_failures = false)
  20417. {
  20418. if (!ignore_failures)
  20419. {
  20420. const std::size_t pair_count = split(pair_block_sdp_,
  20421. data.first,
  20422. data.second,
  20423. pair_list_.begin());
  20424. if (0 == pair_count)
  20425. return false;
  20426. range_type key_range;
  20427. range_type value_range;
  20428. for (std::size_t i = 0; i < pair_count; ++i)
  20429. {
  20430. const range_type& r = pair_list_[i];
  20431. if (0 == std::distance(r.first,r.second))
  20432. continue;
  20433. else if (!split_pair(r.first,r.second,
  20434. pair_delimiter_sdp_,
  20435. key_range,value_range))
  20436. return false;
  20437. else if (!kv_map_(key_range,value_range))
  20438. return false;
  20439. }
  20440. return true;
  20441. }
  20442. else
  20443. {
  20444. parse_failures_ = 0;
  20445. pair_token_processor processor(*this);
  20446. split(pair_block_sdp_,
  20447. data.first,
  20448. data.second,
  20449. strtk::functional_inserter(processor));
  20450. return true;
  20451. }
  20452. }
  20453. inline bool operator()(const std::string& s, const bool ignore_failures = false)
  20454. {
  20455. return operator()(strtk::make_pair<range_type::first_type>(s),ignore_failures);
  20456. }
  20457. inline std::size_t failure_count() const
  20458. {
  20459. return parse_failures_;
  20460. }
  20461. private:
  20462. class pair_token_processor
  20463. {
  20464. public:
  20465. pair_token_processor(parser<KeyValueMap>& p)
  20466. : parser_(p)
  20467. {}
  20468. inline void operator()(const range_type& r)
  20469. {
  20470. if (r.first == r.second)
  20471. return;
  20472. if (split_pair(r.first,r.second,
  20473. parser_.pair_delimiter_sdp_,
  20474. key_range,
  20475. value_range))
  20476. {
  20477. if (!parser_.kv_map_(key_range,value_range))
  20478. ++parser_.parse_failures_;
  20479. }
  20480. else
  20481. ++parser_.parse_failures_;
  20482. }
  20483. private:
  20484. pair_token_processor operator=(const pair_token_processor&);
  20485. parser<KeyValueMap>& parser_;
  20486. range_type key_range;
  20487. range_type value_range;
  20488. };
  20489. options<char_type> options_;
  20490. std::size_t parse_failures_;
  20491. KeyValueMap kv_map_;
  20492. single_delimiter_predicate<char_type> pair_block_sdp_;
  20493. single_delimiter_predicate<char_type> pair_delimiter_sdp_;
  20494. std::vector<range_type> pair_list_;
  20495. };
  20496. class uintkey_map
  20497. {
  20498. private:
  20499. typedef unsigned char char_type;
  20500. typedef strtk::keyvalue::options<char_type> general_options;
  20501. public:
  20502. typedef unsigned int key_type;
  20503. struct options : public general_options
  20504. {
  20505. options()
  20506. : general_options(),
  20507. key_count(0)
  20508. {}
  20509. std::size_t key_count;
  20510. };
  20511. template <typename Options>
  20512. uintkey_map(const Options& options)
  20513. {
  20514. value_lut_.resize(options.key_count,strtk::util::value());
  20515. }
  20516. virtual ~uintkey_map()
  20517. {}
  20518. template <typename Range>
  20519. inline bool operator()(const Range& key_range, const Range& value_range)
  20520. {
  20521. std::size_t key = 0;
  20522. if (!fast::numeric_convert(distance(key_range),key_range.first,key,true))
  20523. return false;
  20524. if (key >= value_lut_.size())
  20525. return false;
  20526. const strtk::util::value& v = value_lut_[key];
  20527. if (!v)
  20528. return false;
  20529. else
  20530. return v(value_range);
  20531. }
  20532. template <typename T>
  20533. inline bool register_keyvalue(const key_type& key, T& t)
  20534. {
  20535. if (key < value_lut_.size())
  20536. {
  20537. strtk::util::value& v = value_lut_[key];
  20538. if (!v)
  20539. v = strtk::util::value(t);
  20540. else
  20541. v.assign(t);
  20542. return true;
  20543. }
  20544. else
  20545. return false;
  20546. }
  20547. private:
  20548. std::vector<strtk::util::value> value_lut_;
  20549. };
  20550. namespace details
  20551. {
  20552. template <typename Range,typename KType>
  20553. struct keygen
  20554. {
  20555. static inline KType transform(const Range&)
  20556. {
  20557. return KType();
  20558. }
  20559. };
  20560. template <typename Range>
  20561. struct keygen<Range,std::string>
  20562. {
  20563. static inline std::string transform(const Range& key_range)
  20564. {
  20565. return std::string(key_range.first,key_range.second);
  20566. }
  20567. };
  20568. template <typename Range>
  20569. struct keygen<Range,unsigned int>
  20570. {
  20571. static inline unsigned int transform(const Range& key_range)
  20572. {
  20573. unsigned int result = 0;
  20574. if (strtk::fast::numeric_convert(std::distance(key_range.first,key_range.second),key_range.first,result,true))
  20575. return result;
  20576. else
  20577. return std::numeric_limits<unsigned int>::max();
  20578. }
  20579. };
  20580. struct no_op_validator
  20581. {
  20582. template <typename Range>
  20583. inline bool operator()(const Range&)
  20584. {
  20585. return true;
  20586. }
  20587. };
  20588. }
  20589. template <typename KeyType,
  20590. typename MapType = std::map<KeyType,strtk::util::value>,
  20591. typename KeyValidator = details::no_op_validator,
  20592. typename ValueValidator = details::no_op_validator>
  20593. class key_map
  20594. {
  20595. public:
  20596. typedef KeyType key_type;
  20597. typedef MapType map_type;
  20598. typedef KeyValidator key_validator_type;
  20599. typedef ValueValidator value_validator_type;
  20600. template <typename Options>
  20601. key_map(const Options&)
  20602. {}
  20603. virtual ~key_map()
  20604. {}
  20605. template <typename Range>
  20606. inline bool operator()(const Range& key_range, const Range& value_range)
  20607. {
  20608. if (!key_validator_(key_range))
  20609. return false;
  20610. if (!val_validator_(value_range))
  20611. return false;
  20612. typename map_type::iterator itr = value_map_.find(details::keygen<Range,key_type>::transform(key_range));
  20613. if (value_map_.end() == itr)
  20614. return false;
  20615. const util::value& v = (*itr).second;
  20616. if (!v)
  20617. return false;
  20618. else
  20619. return v(value_range);
  20620. }
  20621. template <typename T>
  20622. inline bool register_keyvalue(const key_type& key, T& t)
  20623. {
  20624. strtk::util::value& v = value_map_[key];
  20625. if (!v)
  20626. v = strtk::util::value(t);
  20627. else
  20628. v.assign(t);
  20629. return true;
  20630. }
  20631. private:
  20632. map_type value_map_;
  20633. key_validator_type key_validator_;
  20634. value_validator_type val_validator_;
  20635. };
  20636. typedef key_map<std::string> stringkey_map;
  20637. }
  20638. } // namespace strtk
  20639. namespace
  20640. {
  20641. static inline std::ostream& operator<<(std::ostream& os,
  20642. const strtk::std_string::tokenizer<strtk::single_delimiter_predicate<char> >::type::iterator& range)
  20643. {
  20644. os << std::string((*range).first,(*range).second);
  20645. return os;
  20646. }
  20647. static inline std::ostream& operator<<(std::ostream& os,
  20648. const strtk::std_string::tokenizer<strtk::single_delimiter_predicate<unsigned char> >::type::iterator& range)
  20649. {
  20650. os << std::string((*range).first,(*range).second);
  20651. return os;
  20652. }
  20653. static inline std::ostream& operator<<(std::ostream& os,
  20654. const strtk::std_string::tokenizer<strtk::multiple_char_delimiter_predicate>::type::iterator& range)
  20655. {
  20656. os << std::string((*range).first,(*range).second);
  20657. return os;
  20658. }
  20659. #define strtk_register_pair_to_ostream(Iterator)\
  20660. static inline std::ostream& operator<<(std::ostream& os, const std::pair<Iterator,Iterator>& range)\
  20661. { os << std::string(range.first,range.second); return os; }\
  20662. static inline std::ostream& operator<<(std::ostream& os, std::pair<Iterator,Iterator>& range)\
  20663. { os << std::string(range.first,range.second); return os; }\
  20664. strtk_register_pair_to_ostream(char*)
  20665. strtk_register_pair_to_ostream(unsigned char*)
  20666. strtk_register_pair_to_ostream(const char*)
  20667. strtk_register_pair_to_ostream(const unsigned char*)
  20668. strtk_register_pair_to_ostream(std::string::iterator)
  20669. strtk_register_pair_to_ostream(std::string::const_iterator)
  20670. strtk_register_pair_to_ostream(const std::string::iterator)
  20671. strtk_register_pair_to_ostream(const std::string::const_iterator)
  20672. #undef strtk_register_pair_to_ostream
  20673. } // namespace anonymous
  20674. #ifdef WIN32
  20675. #ifndef NOMINMAX
  20676. #define NOMINMAX
  20677. #endif
  20678. #ifndef WIN32_LEAN_AND_MEAN
  20679. #define WIN32_LEAN_AND_MEAN
  20680. #endif
  20681. #include <windows.h>
  20682. #else
  20683. #include <sys/time.h>
  20684. #include <sys/types.h>
  20685. #endif
  20686. namespace strtk
  20687. {
  20688. namespace util
  20689. {
  20690. class timer
  20691. {
  20692. public:
  20693. #ifdef WIN32
  20694. timer()
  20695. : in_use_(false)
  20696. {
  20697. QueryPerformanceFrequency(&clock_frequency_);
  20698. }
  20699. inline void start()
  20700. {
  20701. in_use_ = true;
  20702. QueryPerformanceCounter(&start_time_);
  20703. }
  20704. inline void stop()
  20705. {
  20706. QueryPerformanceCounter(&stop_time_);
  20707. in_use_ = false;
  20708. }
  20709. inline double time() const
  20710. {
  20711. return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart);
  20712. }
  20713. #else
  20714. timer()
  20715. : in_use_(false)
  20716. {
  20717. start_time_.tv_sec = 0;
  20718. start_time_.tv_usec = 0;
  20719. stop_time_.tv_sec = 0;
  20720. stop_time_.tv_usec = 0;
  20721. }
  20722. inline void start()
  20723. {
  20724. in_use_ = true;
  20725. gettimeofday(&start_time_,0);
  20726. }
  20727. inline void stop()
  20728. {
  20729. gettimeofday(&stop_time_, 0);
  20730. in_use_ = false;
  20731. }
  20732. inline unsigned long long int usec_time() const
  20733. {
  20734. if (!in_use_)
  20735. {
  20736. if (stop_time_.tv_sec >= start_time_.tv_sec)
  20737. {
  20738. return 1000000 * (stop_time_.tv_sec - start_time_.tv_sec ) +
  20739. (stop_time_.tv_usec - start_time_.tv_usec);
  20740. }
  20741. else
  20742. return std::numeric_limits<unsigned long long int>::max();
  20743. }
  20744. else
  20745. return std::numeric_limits<unsigned long long int>::max();
  20746. }
  20747. inline double time() const
  20748. {
  20749. return usec_time() * 0.000001;
  20750. }
  20751. #endif
  20752. inline bool in_use() const
  20753. {
  20754. return in_use_;
  20755. }
  20756. private:
  20757. bool in_use_;
  20758. #ifdef WIN32
  20759. LARGE_INTEGER start_time_;
  20760. LARGE_INTEGER stop_time_;
  20761. LARGE_INTEGER clock_frequency_;
  20762. #else
  20763. struct timeval start_time_;
  20764. struct timeval stop_time_;
  20765. #endif
  20766. };
  20767. class scoped_timer
  20768. {
  20769. public:
  20770. scoped_timer(double& time_value)
  20771. : time_value_(time_value)
  20772. {
  20773. t_.start();
  20774. }
  20775. ~scoped_timer()
  20776. {
  20777. t_.stop();
  20778. time_value_ = t_.time();
  20779. }
  20780. private:
  20781. scoped_timer(const scoped_timer&);
  20782. scoped_timer& operator=(const scoped_timer&);
  20783. double& time_value_;
  20784. timer t_;
  20785. };
  20786. } // namespace util
  20787. namespace information
  20788. {
  20789. static const char* library = "String Toolkit";
  20790. static const char* version = "2.71828182845904523536028747135266249775724709369";
  20791. static const char* date = "20130126";
  20792. static inline std::string data()
  20793. {
  20794. static const std::string info_str = std::string(library) +
  20795. std::string(" v") + std::string(version) +
  20796. std::string(" (") + date + std::string(")");
  20797. return info_str;
  20798. }
  20799. } // namespace information
  20800. } // namespace strtk
  20801. #endif