/strtk.hpp

http://nanocalc.codeplex.com · C++ Header · 24290 lines · 23208 code · 1030 blank · 52 comment · 867 complexity · 19de77f2d0d1a844554dff52a287624f MD5 · raw file

  1. /*
  2. *****************************************************************
  3. * String Toolkit Library *
  4. * *
  5. * Author: Arash Partow (2002-2014) *
  6. * URL: http://www.partow.net/programming/strtk/index.html *
  7. * *
  8. * Copyright notice: *
  9. * Free use of the String Toolkit Library is permitted under the *
  10. * guidelines and in accordance with the most current version of *
  11. * the Common Public License. *
  12. * http://www.opensource.org/licenses/cpl1.0.php *
  13. * *
  14. *****************************************************************
  15. */
  16. #ifndef INCLUDE_STRTK_HPP
  17. #define INCLUDE_STRTK_HPP
  18. #include <algorithm>
  19. #include <cctype>
  20. #include <cerrno>
  21. #include <cmath>
  22. #include <cstddef>
  23. #include <cstring>
  24. #include <deque>
  25. #include <exception>
  26. #include <fstream>
  27. #include <iostream>
  28. #include <iterator>
  29. #include <limits>
  30. #include <list>
  31. #include <map>
  32. #include <queue>
  33. #include <set>
  34. #include <sstream>
  35. #include <stack>
  36. #include <stdexcept>
  37. #include <string>
  38. #include <utility>
  39. #include <vector>
  40. #ifndef strtk_no_tr1_or_boost
  41. #define strtk_enable_lexical_cast
  42. #define strtk_enable_random
  43. #define strtk_enable_regex
  44. #endif
  45. #ifdef strtk_enable_lexical_cast
  46. #include <boost/lexical_cast.hpp>
  47. #endif
  48. #ifdef strtk_enable_random
  49. // Requires definition of a TR1 compatible random library header
  50. //#include <random>
  51. #include <boost/random.hpp>
  52. #endif
  53. #ifdef strtk_enable_regex
  54. // Requires definition of a TR1 compatible regex library header
  55. //#include <regex>
  56. #include <boost/regex.hpp>
  57. #endif
  58. namespace strtk
  59. {
  60. static const std::size_t one_kilobyte = 1024;
  61. static const std::size_t one_megabyte = 1024 * one_kilobyte;
  62. static const std::size_t one_gigabyte = 1024 * one_megabyte;
  63. static const std::size_t magic_seed = 0xA5A5A5A5;
  64. template <typename Tokenizer, typename Function>
  65. inline std::size_t for_each_token(const std::string& buffer,
  66. Tokenizer& tokenizer,
  67. Function function)
  68. {
  69. std::size_t token_count = 0;
  70. tokenizer.assign(buffer);
  71. typename Tokenizer::iterator itr = tokenizer.begin();
  72. typename Tokenizer::const_iterator end = tokenizer.end();
  73. while (end != itr)
  74. {
  75. function(*itr);
  76. ++itr;
  77. ++token_count;
  78. }
  79. return token_count;
  80. }
  81. template <typename Function>
  82. inline std::size_t for_each_line(std::istream& stream,
  83. Function function,
  84. const std::size_t& buffer_size = one_kilobyte)
  85. {
  86. std::string buffer;
  87. buffer.reserve(buffer_size);
  88. std::size_t line_count = 0;
  89. while (std::getline(stream,buffer))
  90. {
  91. function(buffer);
  92. ++line_count;
  93. }
  94. return line_count;
  95. }
  96. template <typename Function>
  97. inline std::size_t for_each_line_n(std::istream& stream,
  98. const std::size_t& n,
  99. Function function,
  100. const std::size_t& buffer_size = one_kilobyte)
  101. {
  102. std::string buffer;
  103. buffer.reserve(buffer_size);
  104. std::size_t line_count = 0;
  105. while (std::getline(stream,buffer))
  106. {
  107. function(buffer);
  108. if (n == ++line_count)
  109. break;
  110. }
  111. return line_count;
  112. }
  113. template <typename Function>
  114. inline std::size_t for_each_line(const std::string& file_name,
  115. Function function,
  116. const std::size_t& buffer_size = one_kilobyte)
  117. {
  118. std::ifstream stream(file_name.c_str());
  119. if (stream)
  120. return for_each_line(stream,function,buffer_size);
  121. else
  122. return 0;
  123. }
  124. template <typename Function>
  125. inline std::size_t for_each_line_n(const std::string& file_name,
  126. const std::size_t& n,
  127. Function function,
  128. const std::size_t& buffer_size = one_kilobyte)
  129. {
  130. std::ifstream stream(file_name.c_str());
  131. if (stream)
  132. return for_each_line_n(stream,n,function,buffer_size);
  133. else
  134. return 0;
  135. }
  136. template <typename Function>
  137. inline std::size_t for_each_line_conditional(std::istream& stream,
  138. Function function,
  139. const std::size_t& buffer_size = one_kilobyte)
  140. {
  141. std::string buffer;
  142. buffer.reserve(buffer_size);
  143. std::size_t line_count = 0;
  144. while (std::getline(stream,buffer))
  145. {
  146. if (!function(buffer))
  147. {
  148. return line_count;
  149. }
  150. ++line_count;
  151. }
  152. return line_count;
  153. }
  154. template <typename Function>
  155. inline std::size_t for_each_line_n_conditional(std::istream& stream,
  156. const std::size_t& n,
  157. Function function,
  158. const std::size_t& buffer_size = one_kilobyte)
  159. {
  160. std::string buffer;
  161. buffer.reserve(buffer_size);
  162. std::size_t line_count = 0;
  163. while (std::getline(stream,buffer))
  164. {
  165. if (!function(buffer))
  166. {
  167. return line_count;
  168. }
  169. if (n == ++line_count)
  170. break;
  171. }
  172. return line_count;
  173. }
  174. template <typename Function>
  175. inline std::size_t for_each_line_conditional(const std::string& file_name,
  176. Function function,
  177. const std::size_t& buffer_size = one_kilobyte)
  178. {
  179. std::ifstream stream(file_name.c_str());
  180. if (stream)
  181. return for_each_line_conditional(stream,function,buffer_size);
  182. else
  183. return 0;
  184. }
  185. template <typename Function>
  186. inline std::size_t for_each_line_n_conditional(const std::string& file_name,
  187. const std::size_t& n,
  188. Function function,
  189. const std::size_t& buffer_size = one_kilobyte)
  190. {
  191. std::ifstream stream(file_name.c_str());
  192. if (stream)
  193. return for_each_line_n_conditional(stream,n,function,buffer_size);
  194. else
  195. return 0;
  196. }
  197. template <typename T>
  198. inline bool read_line_as_value(std::istream& stream,
  199. T& t,
  200. const std::size_t& buffer_size = one_kilobyte)
  201. {
  202. std::string buffer;
  203. buffer.reserve(buffer_size);
  204. if (!std::getline(stream,buffer))
  205. return false;
  206. else
  207. return string_to_type_converter(buffer,t);
  208. }
  209. namespace details
  210. {
  211. struct not_supported_type_tag {};
  212. struct unsigned_type_tag {};
  213. struct signed_type_tag {};
  214. struct real_type_tag {};
  215. struct byte_type_tag {};
  216. struct bool_type_tag {};
  217. struct hex_number_type_tag {};
  218. struct hex_string_type_tag {};
  219. struct base64_type_tag {};
  220. struct ignore_token_type_tag {};
  221. struct stdstring_type_tag {};
  222. struct stdstring_range_type_tag {};
  223. struct value_type_tag {};
  224. struct sink_type_tag {};
  225. struct stl_seq_type_tag {};
  226. struct attribute_type_tag {};
  227. struct semantic_action_type_tag {};
  228. struct expect_type_tag {};
  229. struct like_type_tag {};
  230. struct inrange_type_tag {};
  231. struct trim_type_tag {};
  232. struct lcase_type_tag {};
  233. struct ucase_type_tag {};
  234. struct fillchararray_type_tag {};
  235. struct truncint_type_tag {};
  236. struct decsink_type_tag {};
  237. template <typename RealType> struct real_type {};
  238. template <> struct real_type<float> { typedef double type; };
  239. template <> struct real_type<double> { typedef double type; };
  240. template <> struct real_type<long double> { typedef long double type; };
  241. template <typename T>
  242. struct supported_conversion_to_type
  243. {
  244. typedef not_supported_type_tag type;
  245. };
  246. template <typename T>
  247. struct supported_conversion_from_type
  248. {
  249. typedef not_supported_type_tag type;
  250. };
  251. template <bool, typename T = void>
  252. struct enable_if {};
  253. template <typename T>
  254. struct enable_if<true, T> { typedef T type; };
  255. template <typename T>
  256. struct supported_iterator_type
  257. {
  258. enum { value = false };
  259. };
  260. template <typename T>
  261. struct is_valid_iterator
  262. {
  263. typedef typename details::enable_if<details::supported_iterator_type<T>::value,T>::type type;
  264. };
  265. template <typename T> struct numeric;
  266. template <typename T> inline std::size_t type_length(const T&);
  267. struct no_t {};
  268. struct yes_t {};
  269. template <typename T>
  270. struct is_pod
  271. {
  272. typedef no_t result_t;
  273. enum { result = false };
  274. };
  275. template <typename T>
  276. struct is_stl_container
  277. { typedef no_t result_t; };
  278. #define register_stl_container1(C) \
  279. template <typename T1, typename T2>struct is_stl_container<C<T1,T2> >{ typedef yes_t result_t; };
  280. #define register_stl_container2(C) \
  281. template <typename T1, typename T2, typename T3>struct is_stl_container<C<T1,T2,T3> >{ typedef yes_t result_t; };
  282. register_stl_container1(std::vector)
  283. register_stl_container1(std::deque)
  284. register_stl_container1(std::list)
  285. register_stl_container1(std::queue)
  286. register_stl_container1(std::stack)
  287. register_stl_container2(std::set)
  288. register_stl_container2(std::multiset)
  289. register_stl_container2(std::priority_queue)
  290. #undef register_stl_container1
  291. #undef register_stl_container2
  292. template <typename T>
  293. void convert_type_assert(){}
  294. } // namespace details
  295. template <typename Iterator, typename T>
  296. inline bool string_to_type_converter(const Iterator begin, const Iterator end, T& t)
  297. {
  298. typedef typename details::is_valid_iterator<Iterator>::type itr_type;
  299. typename details::supported_conversion_to_type<T>::type type;
  300. details::convert_type_assert<itr_type>();
  301. Iterator itr = begin;
  302. return string_to_type_converter_impl(itr,end,t,type);
  303. }
  304. template <typename Iterator, typename T>
  305. inline bool string_to_type_converter(const std::pair<Iterator,Iterator>& range, T& t)
  306. {
  307. return string_to_type_converter(range.first,range.second,t);
  308. }
  309. template <typename T, typename Iterator>
  310. inline T string_to_type_converter(const Iterator begin, const Iterator end)
  311. {
  312. typedef typename details::is_valid_iterator<Iterator>::type itr_type;
  313. typename details::supported_conversion_to_type<T>::type type;
  314. details::convert_type_assert<itr_type>();
  315. T t;
  316. Iterator itr = begin;
  317. if (string_to_type_converter_impl(itr,end,t,type))
  318. return t;
  319. else
  320. throw std::invalid_argument("string_to_type_converter() - Failed to convert: " +
  321. std::string(begin,end));
  322. }
  323. template <typename T, typename Iterator>
  324. inline T string_to_type_converter(const std::pair<Iterator,Iterator>& range)
  325. {
  326. return string_to_type_converter<T>(range.first,range.second);
  327. }
  328. template <typename T>
  329. inline bool string_to_type_converter(const std::string& s, T& t)
  330. {
  331. return string_to_type_converter<const char*,T>(s.data(),s.data() + s.size(),t);
  332. }
  333. template <typename T>
  334. inline T string_to_type_converter(const std::string& s)
  335. {
  336. return string_to_type_converter<T>(s.data(),s.data() + s.size());
  337. }
  338. template <typename T>
  339. inline bool type_to_string(const T& t, std::string& s)
  340. {
  341. typename details::supported_conversion_from_type<T>::type type;
  342. return type_to_string_converter_impl(t,s,type);
  343. }
  344. template <typename T>
  345. inline std::string type_to_string(const T& t)
  346. {
  347. std::string s;
  348. if (type_to_string<T>(t,s))
  349. return s;
  350. else
  351. throw std::invalid_argument("type_to_string() - Failed to convert type to string");
  352. }
  353. #define strtk_begin_register_string_to_type \
  354. namespace strtk { namespace details { \
  355. #define strtk_end_register_string_to_type \
  356. }} \
  357. #define strtk_string_to_type_begin(Type) \
  358. namespace strtk { namespace details { template <typename Iterator> \
  359. inline bool string_to_type_converter_impl(const Iterator& begin, const Iterator& end, \
  360. Type& t, details::not_supported_type_tag&) { \
  361. #define strtk_string_to_type_end() \
  362. }}} \
  363. template <typename T,
  364. typename Allocator,
  365. template <typename,typename> class Sequence>
  366. inline std::size_t load_from_text_file(std::istream& stream,
  367. Sequence<T,Allocator>& sequence,
  368. const std::size_t& buffer_size = one_kilobyte)
  369. {
  370. if (!stream) return 0;
  371. std::string buffer;
  372. buffer.reserve(buffer_size);
  373. std::size_t line_count = 0;
  374. while (std::getline(stream,buffer))
  375. {
  376. ++line_count;
  377. sequence.push_back(string_to_type_converter<T>(buffer));
  378. }
  379. return line_count;
  380. }
  381. template <typename T,
  382. typename Comparator,
  383. typename Allocator>
  384. inline std::size_t load_from_text_file(std::istream& stream,
  385. std::set<T,Comparator,Allocator>& set,
  386. const std::size_t& buffer_size = one_kilobyte)
  387. {
  388. if (!stream) return 0;
  389. std::string buffer;
  390. buffer.reserve(buffer_size);
  391. std::size_t line_count = 0;
  392. while (std::getline(stream,buffer))
  393. {
  394. ++line_count;
  395. set.insert(string_to_type_converter<T>(buffer));
  396. }
  397. return line_count;
  398. }
  399. template <typename T,
  400. typename Comparator,
  401. typename Allocator>
  402. inline std::size_t load_from_text_file(std::istream& stream,
  403. std::multiset<T,Comparator,Allocator>& multiset,
  404. const std::size_t& buffer_size = one_kilobyte)
  405. {
  406. if (!stream) return 0;
  407. std::string buffer;
  408. buffer.reserve(buffer_size);
  409. std::size_t line_count = 0;
  410. while (std::getline(stream,buffer))
  411. {
  412. ++line_count;
  413. multiset.insert(string_to_type_converter<T>(buffer));
  414. }
  415. return line_count;
  416. }
  417. template <typename T, typename Container>
  418. inline std::size_t load_from_text_file(std::istream& stream,
  419. std::queue<T,Container>& queue,
  420. const std::size_t& buffer_size = one_kilobyte)
  421. {
  422. if (!stream) return 0;
  423. std::string buffer;
  424. buffer.reserve(buffer_size);
  425. std::size_t line_count = 0;
  426. while (std::getline(stream,buffer))
  427. {
  428. ++line_count;
  429. queue.push(string_to_type_converter<T>(buffer));
  430. }
  431. return line_count;
  432. }
  433. template <typename T, typename Container>
  434. inline std::size_t load_from_text_file(std::istream& stream,
  435. std::stack<T,Container>& stack,
  436. const std::size_t& buffer_size = one_kilobyte)
  437. {
  438. if (!stream) return 0;
  439. std::string buffer;
  440. buffer.reserve(buffer_size);
  441. std::size_t line_count = 0;
  442. while (std::getline(stream,buffer))
  443. {
  444. ++line_count;
  445. stack.push(string_to_type_converter<T>(buffer));
  446. }
  447. return line_count;
  448. }
  449. template <typename T,
  450. typename Container,
  451. typename Comparator>
  452. inline std::size_t load_from_text_file(std::istream& stream,
  453. std::priority_queue<T,Container,Comparator>& priority_queue,
  454. const std::size_t& buffer_size = one_kilobyte)
  455. {
  456. if (!stream) return 0;
  457. std::string buffer;
  458. buffer.reserve(buffer_size);
  459. std::size_t line_count = 0;
  460. while (std::getline(stream,buffer))
  461. {
  462. ++line_count;
  463. priority_queue.push(string_to_type_converter<T>(buffer));
  464. }
  465. return line_count;
  466. }
  467. template <typename T,
  468. typename Allocator,
  469. template <typename,typename> class Sequence>
  470. inline std::size_t load_from_text_file(const std::string& file_name,
  471. Sequence<T,Allocator>& sequence,
  472. const std::size_t& buffer_size = one_kilobyte)
  473. {
  474. std::ifstream stream(file_name.c_str());
  475. if (!stream)
  476. return 0;
  477. else
  478. return load_from_text_file(stream,sequence,buffer_size);
  479. }
  480. template <typename T,
  481. typename Comparator,
  482. typename Allocator>
  483. inline std::size_t load_from_text_file(const std::string& file_name,
  484. std::set<T,Comparator,Allocator>& set,
  485. const std::size_t& buffer_size = one_kilobyte)
  486. {
  487. std::ifstream stream(file_name.c_str());
  488. if (!stream)
  489. return 0;
  490. else
  491. return load_from_text_file(stream,set,buffer_size);
  492. }
  493. template <typename T,
  494. typename Comparator,
  495. typename Allocator>
  496. inline std::size_t load_from_text_file(const std::string& file_name,
  497. std::multiset<T,Comparator,Allocator>& multiset,
  498. const std::size_t& buffer_size = one_kilobyte)
  499. {
  500. std::ifstream stream(file_name.c_str());
  501. if (!stream)
  502. return 0;
  503. else
  504. return load_from_text_file(stream,multiset,buffer_size);
  505. }
  506. template <typename T, typename Container>
  507. inline std::size_t load_from_text_file(const std::string& file_name,
  508. std::queue<T,Container>& queue,
  509. const std::size_t& buffer_size = one_kilobyte)
  510. {
  511. std::ifstream stream(file_name.c_str());
  512. if (!stream)
  513. return 0;
  514. else
  515. return load_from_text_file(stream,queue,buffer_size);
  516. }
  517. template <typename T, typename Container>
  518. inline std::size_t load_from_text_file(const std::string& file_name,
  519. std::stack<T,Container>& stack,
  520. const std::size_t& buffer_size = one_kilobyte)
  521. {
  522. std::ifstream stream(file_name.c_str());
  523. if (!stream)
  524. return 0;
  525. else
  526. return load_from_text_file(stream,stack,buffer_size);
  527. }
  528. template <typename T,
  529. typename Container,
  530. typename Comparator>
  531. inline std::size_t load_from_text_file(const std::string& file_name,
  532. std::priority_queue<T,Container,Comparator>& priority_queue,
  533. const std::size_t& buffer_size = one_kilobyte)
  534. {
  535. std::ifstream stream(file_name.c_str());
  536. if (!stream)
  537. return 0;
  538. else
  539. return load_from_text_file(stream,priority_queue,buffer_size);
  540. }
  541. template <typename T,
  542. typename Allocator,
  543. template <typename,typename> class Sequence>
  544. inline std::size_t write_to_text_file(std::ostream& stream,
  545. const Sequence<T,Allocator>& sequence,
  546. const std::string& delimiter = "")
  547. {
  548. if (!stream) return 0;
  549. std::size_t count = 0;
  550. typename Sequence<T,Allocator>::const_iterator itr = sequence.begin();
  551. typename Sequence<T,Allocator>::const_iterator end = sequence.end();
  552. if (!delimiter.empty())
  553. {
  554. while (end != itr)
  555. {
  556. stream << (*itr) << delimiter;
  557. ++itr;
  558. ++count;
  559. }
  560. }
  561. else
  562. {
  563. while (end != itr)
  564. {
  565. stream << (*itr);
  566. ++itr;
  567. ++count;
  568. }
  569. }
  570. return count;
  571. }
  572. template <typename T,
  573. typename Comparator,
  574. typename Allocator>
  575. inline std::size_t write_to_text_file(std::ostream& stream,
  576. const std::set<T,Comparator,Allocator>& set,
  577. const std::string& delimiter = "")
  578. {
  579. if (!stream) return 0;
  580. std::size_t count = 0;
  581. typename std::set<T,Comparator,Allocator>::const_iterator itr = set.begin();
  582. typename std::set<T,Comparator,Allocator>::const_iterator end = set.end();
  583. if (!delimiter.empty())
  584. {
  585. while (end != itr)
  586. {
  587. stream << (*itr) << delimiter;
  588. ++itr;
  589. ++count;
  590. }
  591. }
  592. else
  593. {
  594. while (end != itr)
  595. {
  596. stream << (*itr);
  597. ++itr;
  598. ++count;
  599. }
  600. }
  601. return count;
  602. }
  603. template <typename T,
  604. typename Comparator,
  605. typename Allocator>
  606. inline std::size_t write_to_text_file(std::ostream& stream,
  607. const std::multiset<T,Comparator,Allocator>& multiset,
  608. const std::string& delimiter = "")
  609. {
  610. if (!stream) return 0;
  611. std::size_t count = 0;
  612. typename std::multiset<T,Comparator,Allocator>::const_iterator itr = multiset.begin();
  613. typename std::multiset<T,Comparator,Allocator>::const_iterator end = multiset.end();
  614. if (!delimiter.empty())
  615. {
  616. while (end != itr)
  617. {
  618. stream << (*itr) << delimiter;
  619. ++itr;
  620. ++count;
  621. }
  622. }
  623. else
  624. {
  625. while (end != itr)
  626. {
  627. stream << (*itr);
  628. ++itr;
  629. ++count;
  630. }
  631. }
  632. return count;
  633. }
  634. template <typename T,
  635. typename Allocator,
  636. template <typename,typename> class Sequence>
  637. inline std::size_t write_to_text_file(const std::string& file_name,
  638. const Sequence<T,Allocator>& sequence,
  639. const std::string& delimiter = "")
  640. {
  641. std::ofstream stream(file_name.c_str());
  642. if (!stream)
  643. return 0;
  644. else
  645. return write_to_text_file(stream,sequence,delimiter);
  646. }
  647. template <typename T,
  648. typename Comparator,
  649. typename Allocator>
  650. inline std::size_t write_to_text_file(const std::string& file_name,
  651. const std::set<T,Comparator,Allocator>& set,
  652. const std::string& delimiter = "")
  653. {
  654. std::ofstream stream(file_name.c_str());
  655. if (!stream)
  656. return 0;
  657. else
  658. return write_to_text_file(stream,set,delimiter);
  659. }
  660. template <typename T,
  661. typename Comparator,
  662. typename Allocator>
  663. inline std::size_t write_to_text_file(const std::string& file_name,
  664. const std::multiset<T,Comparator,Allocator>& multiset,
  665. const std::string& delimiter = "")
  666. {
  667. std::ofstream stream(file_name.c_str());
  668. if (!stream)
  669. return 0;
  670. else
  671. return write_to_text_file(stream,multiset,delimiter);
  672. }
  673. template <typename InputIterator, typename OutputIterator>
  674. inline void copy_n(InputIterator itr, std::size_t n, OutputIterator out)
  675. {
  676. while (n)
  677. {
  678. (*out) = (*itr);
  679. ++itr;
  680. ++out;
  681. --n;
  682. }
  683. }
  684. template <typename Predicate,
  685. typename InputIterator,
  686. typename OutputIterator>
  687. inline void copy_if(Predicate predicate,
  688. const InputIterator begin, const InputIterator end,
  689. OutputIterator out)
  690. {
  691. InputIterator itr = begin;
  692. while (end != itr)
  693. {
  694. if (predicate(*itr))
  695. {
  696. *(out++) = (*itr);
  697. }
  698. ++itr;
  699. }
  700. }
  701. template <typename Predicate,
  702. typename InputIterator,
  703. typename OutputIterator>
  704. inline InputIterator copy_while(Predicate predicate,
  705. const InputIterator begin, const InputIterator end,
  706. OutputIterator out)
  707. {
  708. InputIterator itr = begin;
  709. while (end != itr)
  710. {
  711. if (!predicate(*itr))
  712. return itr;
  713. *(out++) = *(itr++);
  714. }
  715. return end;
  716. }
  717. template <typename Predicate,
  718. typename InputIterator,
  719. typename OutputIterator>
  720. inline InputIterator copy_until(Predicate predicate,
  721. const InputIterator begin, const InputIterator end,
  722. OutputIterator out)
  723. {
  724. InputIterator itr = begin;
  725. while (end != itr)
  726. {
  727. if (predicate(*itr))
  728. return itr;
  729. *(out++) = *(itr++);
  730. }
  731. return end;
  732. }
  733. template <typename InputIterator, typename OutputIterator>
  734. inline void extract_unique(const InputIterator begin, const InputIterator end,
  735. OutputIterator out)
  736. {
  737. typedef typename std::iterator_traits<InputIterator>::value_type T;
  738. std::vector<T> buffer(begin,end);
  739. std::sort(buffer.begin(),buffer.end());
  740. std::unique_copy(buffer.begin(),buffer.end(),out);
  741. }
  742. template <typename Predicate, typename InputIterator>
  743. inline bool range_only_contains(Predicate predicate,
  744. const InputIterator begin,
  745. const InputIterator end)
  746. {
  747. InputIterator itr = begin;
  748. while (end != itr)
  749. {
  750. if (!predicate(*itr))
  751. {
  752. return false;
  753. }
  754. ++itr;
  755. }
  756. return true;
  757. }
  758. namespace range
  759. {
  760. template <typename T>
  761. class adapter
  762. {
  763. public:
  764. typedef T value_type;
  765. typedef T* iterator;
  766. typedef const iterator const_iterator;
  767. adapter(T* const begin, T* const end)
  768. : begin_(begin),
  769. end_(end)
  770. {}
  771. adapter(const std::pair<T*,T*>& r)
  772. : begin_(r.first),
  773. end_(r.second)
  774. {}
  775. adapter(T* const begin, const std::size_t length)
  776. : begin_(begin),
  777. end_(begin_ + length)
  778. {}
  779. inline iterator begin() const
  780. {
  781. return begin_;
  782. }
  783. inline iterator end() const
  784. {
  785. return end_;
  786. }
  787. inline std::size_t size() const
  788. {
  789. return std::distance(begin_,end_);
  790. }
  791. inline operator std::string() const
  792. {
  793. return stringify(begin_,end_);
  794. }
  795. inline const T& operator[](const std::size_t& index) const
  796. {
  797. return *(begin_ + index);
  798. }
  799. inline T& operator[](const std::size_t& index)
  800. {
  801. return *(begin_ + index);
  802. }
  803. private:
  804. template <typename Type>
  805. static inline std::string stringify(Type*,Type*)
  806. {
  807. static std::string result = "";
  808. return result;
  809. }
  810. static inline std::string stringify(const char* begin, const char* end)
  811. {
  812. return std::string(begin,end);
  813. }
  814. iterator begin_;
  815. iterator end_;
  816. };
  817. typedef adapter<const char> string;
  818. typedef adapter<const unsigned char> ustring;
  819. template <typename T>
  820. inline adapter<T> type(const T* begin, const T* end)
  821. {
  822. return adapter<T>(begin,end);
  823. }
  824. template <typename T, std::size_t N>
  825. inline adapter<T> type(const T (&t)[N])
  826. {
  827. return adapter<T>(t,N);
  828. }
  829. static inline adapter<const char> type(const std::string& s)
  830. {
  831. return adapter<const char>(s.data(),s.size());
  832. }
  833. template <typename T,
  834. typename Allocator,
  835. template <typename,typename> class Sequence>
  836. inline adapter<typename Sequence<T,Allocator>::iterator> type(const Sequence<T,Allocator>& seq)
  837. {
  838. return adapter<typename Sequence<T,Allocator>::iterator>(seq.begin(),seq.end());
  839. }
  840. inline std::string as_string(const adapter<const char>& a)
  841. {
  842. return std::string(a.begin(),a.end());
  843. }
  844. inline std::string as_string(const adapter<const unsigned char>& a)
  845. {
  846. return std::string(a.begin(),a.end());
  847. }
  848. } // namespace range
  849. template <typename T>
  850. struct single_delimiter_predicate
  851. {
  852. public:
  853. typedef T value_type;
  854. single_delimiter_predicate(const T& d)
  855. : delimiter_(d)
  856. {}
  857. inline bool operator()(const T& d) const
  858. {
  859. return delimiter_ == d;
  860. }
  861. private:
  862. single_delimiter_predicate<T>& operator=(const single_delimiter_predicate<T>&);
  863. const T delimiter_;
  864. };
  865. template <typename T>
  866. struct multiple_delimiter_predicate
  867. {
  868. public:
  869. typedef T value_type;
  870. multiple_delimiter_predicate(const T* d_begin, const T* d_end)
  871. : length_(std::distance(d_begin,d_end)),
  872. delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
  873. delimiter_end_(delimiter_ + length_)
  874. {
  875. std::copy(d_begin,d_end, delimiter_);
  876. }
  877. multiple_delimiter_predicate(const T d[], const std::size_t& length)
  878. : length_(length),
  879. delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
  880. delimiter_end_(delimiter_ + length_)
  881. {
  882. std::copy(d,d + length, delimiter_);
  883. }
  884. template <typename Iterator>
  885. multiple_delimiter_predicate(const Iterator begin, const Iterator end)
  886. : length_(std::distance(begin,end)),
  887. delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
  888. delimiter_end_(delimiter_ + length_)
  889. {
  890. //static_assert(T == std::iterator_traits<Iterator>::value_type);
  891. std::copy(begin,end, delimiter_);
  892. }
  893. template <typename Type>
  894. multiple_delimiter_predicate(const range::adapter<Type>& r)
  895. : length_(std::distance(r.begin(),r.end())),
  896. delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
  897. delimiter_end_(delimiter_ + length_)
  898. {
  899. //static_assert(T == std::iterator_traits<Iterator>::value_type);
  900. std::copy(r.begin(),r.end(), delimiter_);
  901. }
  902. ~multiple_delimiter_predicate()
  903. {
  904. if (length_ > sbo_buffer_size)
  905. {
  906. delete[] delimiter_;
  907. }
  908. }
  909. inline bool operator()(const T& d) const
  910. {
  911. return (std::find(delimiter_,delimiter_end_,d) != delimiter_end_);
  912. }
  913. private:
  914. multiple_delimiter_predicate(const multiple_delimiter_predicate<T>& mdp);
  915. multiple_delimiter_predicate& operator=(const multiple_delimiter_predicate<T>& mdp);
  916. std::size_t length_;
  917. T* delimiter_;
  918. T* delimiter_end_;
  919. enum { sbo_buffer_size = 32 };
  920. T sbo_buffer[sbo_buffer_size];
  921. };
  922. struct multiple_char_delimiter_predicate
  923. {
  924. public:
  925. template <typename Iterator>
  926. multiple_char_delimiter_predicate(const Iterator begin, const Iterator end)
  927. {
  928. setup_delimiter_table(begin,end);
  929. }
  930. multiple_char_delimiter_predicate(const std::string& s)
  931. {
  932. setup_delimiter_table(s.data(),s.data() + s.size());
  933. }
  934. inline bool operator()(const unsigned char& c) const
  935. {
  936. return (delimiter_table_[c]);
  937. }
  938. inline bool operator()(const char& c) const
  939. {
  940. return operator()(static_cast<unsigned char>(c));
  941. }
  942. private:
  943. static const std::size_t table_size = 256;
  944. template <typename Iterator>
  945. inline void setup_delimiter_table(const Iterator begin, const Iterator end)
  946. {
  947. std::fill_n(delimiter_table_,table_size,false);
  948. for (Iterator itr = begin; itr != end; ++itr)
  949. {
  950. delimiter_table_[static_cast<unsigned char>(*itr)] = true;
  951. }
  952. }
  953. bool delimiter_table_[table_size];
  954. };
  955. namespace details
  956. {
  957. template <typename Allocator,
  958. template <typename,typename> class Sequence>
  959. struct index_remover_impl
  960. {
  961. typedef Sequence<std::size_t,Allocator> sequence_t;
  962. index_remover_impl(const sequence_t& sequence)
  963. : itr_(sequence.begin()),
  964. end_(sequence.end()),
  965. current_index_(0),
  966. check_(true)
  967. {}
  968. template <typename T>
  969. inline bool operator()(const T&)
  970. {
  971. if (check_)
  972. {
  973. if (current_index_++ == *itr_)
  974. {
  975. if (end_ == ++itr_)
  976. {
  977. check_ = false;
  978. }
  979. return true;
  980. }
  981. }
  982. return false;
  983. }
  984. typename sequence_t::const_iterator itr_;
  985. typename sequence_t::const_iterator end_;
  986. std::size_t current_index_;
  987. bool check_;
  988. };
  989. }
  990. template <typename Allocator,
  991. template <typename,typename> class Sequence>
  992. inline details::index_remover_impl<Allocator,Sequence> index_remover(const Sequence<std::size_t,Allocator>& sequence)
  993. {
  994. return details::index_remover_impl<Allocator,Sequence>(sequence);
  995. }
  996. template <typename Iterator, typename Predicate>
  997. inline std::size_t remove_inplace(Predicate predicate,
  998. Iterator begin,
  999. Iterator end)
  1000. {
  1001. Iterator itr1 = begin;
  1002. Iterator itr2 = begin;
  1003. std::size_t removal_count = 0;
  1004. while (end != itr1)
  1005. {
  1006. if (predicate(*itr1))
  1007. {
  1008. ++itr1;
  1009. ++removal_count;
  1010. }
  1011. else
  1012. {
  1013. if (itr1 != itr2)
  1014. {
  1015. (*itr2) = (*itr1);
  1016. }
  1017. ++itr1;
  1018. ++itr2;
  1019. }
  1020. }
  1021. return removal_count;
  1022. }
  1023. template <typename T, typename Predicate>
  1024. inline std::size_t remove_inplace(Predicate predicate, const range::adapter<T>& r)
  1025. {
  1026. return remove_inplace(predicate,r.begin(),r.end());
  1027. }
  1028. template <typename Predicate,
  1029. typename T,
  1030. typename Allocator,
  1031. template <typename,typename> class Sequence>
  1032. inline std::size_t remove_inplace(Predicate predicate, Sequence<T,Allocator>& sequence)
  1033. {
  1034. const std::size_t removal_count = remove_inplace(predicate,sequence.begin(),sequence.end());
  1035. sequence.resize(sequence.size() - removal_count);
  1036. return removal_count;
  1037. }
  1038. inline void remove_inplace(const std::string::value_type c, std::string& s)
  1039. {
  1040. const std::size_t removal_count = remove_inplace(single_delimiter_predicate<std::string::value_type>(c),
  1041. const_cast<char*>(s.data()),
  1042. const_cast<char*>(s.data() + s.size()));
  1043. if (removal_count > 0)
  1044. {
  1045. s.resize(s.size() - removal_count);
  1046. }
  1047. }
  1048. template <typename Predicate>
  1049. inline void remove_inplace(Predicate predicate, std::string& s)
  1050. {
  1051. const std::size_t removal_count = remove_inplace(predicate,
  1052. const_cast<char*>(s.data()),
  1053. const_cast<char*>(s.data() + s.size()));
  1054. if (removal_count > 0)
  1055. {
  1056. s.resize(s.size() - removal_count);
  1057. }
  1058. }
  1059. template <typename Iterator, typename Predicate>
  1060. inline std::size_t remove_consecutives_inplace(Predicate predicate,
  1061. Iterator begin,
  1062. Iterator end)
  1063. {
  1064. if (0 == std::distance(begin,end)) return 0;
  1065. Iterator itr1 = begin;
  1066. Iterator itr2 = begin;
  1067. typename std::iterator_traits<Iterator>::value_type prev = *begin;
  1068. std::size_t removal_count = 0;
  1069. ++itr1;
  1070. ++itr2;
  1071. while (end != itr1)
  1072. {
  1073. while ((end != itr1) && (!predicate(*itr1) || !predicate(prev)))
  1074. {
  1075. if (itr1 != itr2)
  1076. {
  1077. (*itr2) = (*itr1);
  1078. }
  1079. prev = (*itr1);
  1080. ++itr1;
  1081. ++itr2;
  1082. }
  1083. while ((end != itr1) && predicate(*itr1))
  1084. {
  1085. ++itr1;
  1086. ++removal_count;
  1087. }
  1088. }
  1089. return removal_count;
  1090. }
  1091. template <typename T, typename Predicate>
  1092. inline std::size_t remove_consecutives_inplace(Predicate predicate, const range::adapter<T>& r)
  1093. {
  1094. return remove_consecutives_inplace(predicate,r.begin(),r.end());
  1095. }
  1096. inline void remove_consecutives_inplace(const std::string::value_type c, std::string& s)
  1097. {
  1098. if (s.empty()) return;
  1099. const std::size_t removal_count = remove_consecutives_inplace(single_delimiter_predicate<std::string::value_type>(c),
  1100. const_cast<char*>(s.data()),
  1101. const_cast<char*>(s.data() + s.size()));
  1102. if (removal_count > 0)
  1103. {
  1104. s.resize(s.size() - removal_count);
  1105. }
  1106. }
  1107. inline void remove_consecutives_inplace(const std::string& rem_chars, std::string& s)
  1108. {
  1109. if (s.empty()) return;
  1110. const std::size_t removal_count = remove_consecutives_inplace(multiple_char_delimiter_predicate(rem_chars),
  1111. const_cast<char*>(s.data()),
  1112. const_cast<char*>(s.data() + s.size()));
  1113. if (removal_count > 0)
  1114. {
  1115. s.resize(s.size() - removal_count);
  1116. }
  1117. }
  1118. namespace details
  1119. {
  1120. #if (defined(__MINGW32_VERSION)) || \
  1121. (defined(__CYGWIN__) || defined(__CYGWIN32__)) || \
  1122. (defined(__APPLE__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)) || \
  1123. (defined(_WIN32) && (_MSC_VER < 1400))
  1124. inline std::size_t strnlength(const char* s, const std::size_t& n)
  1125. {
  1126. const char *end = reinterpret_cast<const char*>(memchr(s, '\0', n));
  1127. return end ? (size_t) (end - s) : n;
  1128. }
  1129. #else
  1130. inline std::size_t strnlength(const char* s, const std::size_t& n)
  1131. {
  1132. return strnlen(s,n);
  1133. }
  1134. #endif
  1135. }
  1136. inline void remove_consecutives_inplace(const char* rem_chars, std::string& s)
  1137. {
  1138. if (s.empty()) return;
  1139. const std::size_t removal_count = remove_consecutives_inplace(multiple_char_delimiter_predicate(
  1140. rem_chars,
  1141. rem_chars + details::strnlength(rem_chars,256)),
  1142. const_cast<char*>(s.data()),
  1143. const_cast<char*>(s.data() + s.size()));
  1144. if (removal_count > 0)
  1145. {
  1146. s.resize(s.size() - removal_count);
  1147. }
  1148. }
  1149. template <typename Predicate>
  1150. inline void remove_consecutives_inplace(Predicate predicate, std::string& s)
  1151. {
  1152. if (s.empty()) return;
  1153. const std::size_t removal_count = remove_consecutives_inplace(predicate,
  1154. const_cast<char*>(s.data()),
  1155. const_cast<char*>(s.data() + s.size()));
  1156. if (removal_count > 0)
  1157. {
  1158. s.resize(s.size() - removal_count);
  1159. }
  1160. }
  1161. template <typename Iterator>
  1162. inline std::size_t remove_consecutives_inplace(Iterator begin, Iterator end)
  1163. {
  1164. if (0 == std::distance(begin,end)) return 0;
  1165. Iterator itr1 = begin; ++itr1;
  1166. Iterator itr2 = begin; ++itr2;
  1167. typename std::iterator_traits<Iterator>::value_type prev = *begin;
  1168. std::size_t removal_count = 0;
  1169. while (end != itr1)
  1170. {
  1171. while ((end != itr1) && (prev != (*itr1)))
  1172. {
  1173. if (itr1 != itr2)
  1174. {
  1175. (*itr2) = (*itr1);
  1176. }
  1177. prev = (*itr1);
  1178. ++itr1;
  1179. ++itr2;
  1180. }
  1181. while ((end != itr1) && (prev == (*itr1)))
  1182. {
  1183. ++itr1;
  1184. ++removal_count;
  1185. }
  1186. }
  1187. return removal_count;
  1188. }
  1189. template <typename T>
  1190. inline std::size_t remove_consecutives_inplace(const range::adapter<T>& r)
  1191. {
  1192. return remove_consecutives_inplace(r.begin(),r.end());
  1193. }
  1194. template <typename T,
  1195. typename Allocator,
  1196. template <typename,typename> class Sequence>
  1197. inline void remove_consecutives_inplace(Sequence<T,Allocator>& sequence)
  1198. {
  1199. const std::size_t removal_count = remove_consecutives_inplace(sequence.begin(),sequence.end());
  1200. sequence.resize(sequence.size() - removal_count);
  1201. }
  1202. inline void remove_consecutives_inplace(std::string& s)
  1203. {
  1204. std::size_t removal_count = remove_consecutives_inplace(const_cast<char*>(s.data()),
  1205. const_cast<char*>(s.data() + s.size()));
  1206. if (removal_count > 0)
  1207. {
  1208. s.resize(s.size() - removal_count);
  1209. }
  1210. }
  1211. inline std::string remove_duplicates(const std::string& str)
  1212. {
  1213. std::string::value_type table[0xFF];
  1214. std::fill_n(table,0xFF,static_cast<char>(0));
  1215. std::string result;
  1216. result.reserve(str.size());
  1217. for (std::size_t i = 0; i < str.size(); ++i)
  1218. {
  1219. const char c = str[i];
  1220. if (0 == table[static_cast<std::size_t>(c)])
  1221. {
  1222. table[static_cast<std::size_t>(c)] = 0x01;
  1223. result += c;
  1224. }
  1225. }
  1226. return result;
  1227. }
  1228. inline std::string remove_duplicates_inplace(std::string& str)
  1229. {
  1230. return remove_duplicates(str);
  1231. }
  1232. template <typename Iterator, typename Predicate>
  1233. inline std::size_t remove_trailing(Predicate predicate,
  1234. Iterator begin,
  1235. Iterator end)
  1236. {
  1237. const std::size_t length = std::distance(begin,end);
  1238. if (0 == length)
  1239. return 0;
  1240. Iterator itr = begin + (length - 1);
  1241. std::size_t removal_count = 0;
  1242. while ((begin != itr) && predicate(*itr))
  1243. {
  1244. --itr;
  1245. ++removal_count;
  1246. }
  1247. return removal_count;
  1248. }
  1249. template <typename T, typename Predicate>
  1250. inline std::size_t remove_trailing(Predicate predicate, const range::adapter<T>& r)
  1251. {
  1252. return remove_trailing(predicate,r.begin(),r.end());
  1253. }
  1254. inline void remove_trailing(const std::string::value_type c, std::string& s)
  1255. {
  1256. if (s.empty()) return;
  1257. const std::size_t removal_count = remove_trailing(single_delimiter_predicate<std::string::value_type>(c),
  1258. const_cast<char*>(s.data()),
  1259. const_cast<char*>(s.data() + s.size()));
  1260. if (removal_count > 0)
  1261. {
  1262. s.resize(s.size() - removal_count);
  1263. }
  1264. }
  1265. inline void remove_trailing(const std::string& rem_chars, std::string& s)
  1266. {
  1267. if (s.empty()) return;
  1268. const std::size_t removal_count = remove_trailing(multiple_char_delimiter_predicate(rem_chars),
  1269. const_cast<char*>(s.data()),
  1270. const_cast<char*>(s.data() + s.size()));
  1271. if (removal_count > 0)
  1272. {
  1273. s.resize(s.size() - removal_count);
  1274. }
  1275. }
  1276. inline void remove_trailing(const char* rem_chars, std::string& s)
  1277. {
  1278. const std::size_t removal_count = remove_trailing(multiple_char_delimiter_predicate(
  1279. rem_chars,
  1280. rem_chars + details::strnlength(rem_chars,256)),
  1281. const_cast<char*>(s.data()),
  1282. const_cast<char*>(s.data() + s.size()));
  1283. if (removal_count > 0)
  1284. {
  1285. s.resize(s.size() - removal_count);
  1286. }
  1287. }
  1288. template <typename Predicate>
  1289. inline void remove_trailing(Predicate predicate, std::string& s)
  1290. {
  1291. if (s.empty()) return;
  1292. const std::size_t removal_count = remove_trailing(predicate,
  1293. const_cast<char*>(s.data()),
  1294. const_cast<char*>(s.data() + s.size()));
  1295. if (removal_count > 0)
  1296. {
  1297. s.resize(s.size() - removal_count);
  1298. }
  1299. }
  1300. template <typename Iterator, typename Predicate>
  1301. inline std::size_t remove_leading(Predicate predicate,
  1302. Iterator begin,
  1303. Iterator end)
  1304. {
  1305. const std::size_t length = std::distance(begin,end);
  1306. if (0 == length)
  1307. return 0;
  1308. Iterator itr = begin;
  1309. std::size_t removal_count = 0;
  1310. while ((end != itr) && predicate(*itr))
  1311. {
  1312. ++itr;
  1313. ++removal_count;
  1314. }
  1315. std::copy(itr,end,begin);
  1316. return removal_count;
  1317. }
  1318. template <typename T, typename Predicate>
  1319. inline std::size_t remove_leading(Predicate predicate, const range::adapter<T>& r)
  1320. {
  1321. return remove_leading(predicate,r.begin(),r.end());
  1322. }
  1323. inline void remove_leading(const std::string::value_type c, std::string& s)
  1324. {
  1325. if (s.empty()) return;
  1326. const std::size_t removal_count = remove_leading(single_delimiter_predicate<std::string::value_type>(c),
  1327. const_cast<char*>(s.data()),
  1328. const_cast<char*>(s.data() + s.size()));
  1329. if (removal_count > 0)
  1330. {
  1331. s.resize(s.size() - removal_count);
  1332. }
  1333. }
  1334. inline void remove_leading(const std::string& rem_chars, std::string& s)
  1335. {
  1336. if (s.empty()) return;
  1337. const std::size_t removal_count = remove_leading(multiple_char_delimiter_predicate(rem_chars),
  1338. const_cast<char*>(s.data()),
  1339. const_cast<char*>(s.data() + s.size()));
  1340. if (removal_count > 0)
  1341. {
  1342. s.resize(s.size() - removal_count);
  1343. }
  1344. }
  1345. inline void remove_leading(const char* rem_chars, std::string& s)
  1346. {
  1347. if (s.empty()) return;
  1348. const std::size_t removal_count = remove_leading(multiple_char_delimiter_predicate(
  1349. rem_chars,
  1350. rem_chars + details::strnlength(rem_chars,256)),
  1351. const_cast<char*>(s.data()),
  1352. const_cast<char*>(s.data() + s.size()));
  1353. if (removal_count > 0)
  1354. {
  1355. s.resize(s.size() - removal_count);
  1356. }
  1357. }
  1358. inline void remove_leading_trailing(const std::string& rem_chars, std::string& s)
  1359. {
  1360. remove_leading(rem_chars,s);
  1361. remove_trailing(rem_chars,s);
  1362. }
  1363. template <typename Predicate>
  1364. inline void remove_leading(Predicate predicate, std::string& s)
  1365. {
  1366. if (s.empty()) return;
  1367. const std::size_t removal_count = remove_leading(predicate,
  1368. const_cast<char*>(s.data()),
  1369. const_cast<char*>(s.data() + s.size()));
  1370. if (removal_count > 0)
  1371. {
  1372. s.resize(s.size() - removal_count);
  1373. }
  1374. }
  1375. template <typename Allocator,
  1376. template <typename,typename> class Sequence>
  1377. void remove_empty_strings(Sequence<std::string,Allocator>& seq)
  1378. {
  1379. struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
  1380. seq.erase(std::remove_if(seq.begin(),seq.end(),is_empty::check),seq.end());
  1381. }
  1382. template <typename Allocator>
  1383. void remove_empty_strings(std::list<std::string,Allocator>& l)
  1384. {
  1385. struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
  1386. l.remove_if(is_empty::check);
  1387. }
  1388. template <typename Comparator, typename Allocator>
  1389. void remove_empty_strings(std::set<std::string,Comparator,Allocator>& set)
  1390. {
  1391. struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
  1392. typename std::set<std::string,Comparator,Allocator>::iterator itr = set.begin();
  1393. while (set.end() != itr)
  1394. {
  1395. if ((*itr).empty())
  1396. set.erase(itr++);
  1397. else
  1398. ++itr;
  1399. }
  1400. }
  1401. template <typename Comparator, typename Allocator>
  1402. void remove_empty_strings(std::multiset<std::string,Comparator,Allocator>& set)
  1403. {
  1404. struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
  1405. typename std::multiset<std::string,Comparator,Allocator>::iterator itr = set.begin();
  1406. while (set.end() != itr)
  1407. {
  1408. if ((*itr).empty())
  1409. set.erase(itr++);
  1410. else
  1411. ++itr;
  1412. }
  1413. }
  1414. template <typename Iterator>
  1415. inline void replace(const typename std::iterator_traits<Iterator>::value_type& c1,
  1416. const typename std::iterator_traits<Iterator>::value_type& c2,
  1417. const Iterator begin,
  1418. const Iterator end)
  1419. {
  1420. for (Iterator itr = begin; end != itr; ++itr)
  1421. {
  1422. if (c1 == (*itr))
  1423. {
  1424. (*itr) = c2;
  1425. }
  1426. }
  1427. }
  1428. inline void replace(const std::string::value_type& c0,
  1429. const std::string::value_type& c1,
  1430. std::string& s)
  1431. {
  1432. replace(c0,c1,const_cast<char*>(s.data()),const_cast<char*>(s.data() + s.size()));
  1433. }
  1434. template <typename T>
  1435. inline void replace(const T& c1, const T& c2, const range::adapter<T>& r)
  1436. {
  1437. replace(c1,c2,r.begin(),r.end());
  1438. }
  1439. inline void replace_pattern(const std::string& s, // input
  1440. const std::string& p, // pattern
  1441. const std::string& r, // replacement
  1442. std::string& n)
  1443. {
  1444. if (p.empty() || (p == r))
  1445. {
  1446. n.assign(s);
  1447. return;
  1448. }
  1449. const std::size_t p_size = p.size();
  1450. const std::size_t r_size = r.size();
  1451. int inc = static_cast<int>(r_size) - static_cast<int>(p_size);
  1452. std::size_t pos = 0;
  1453. std::vector<std::size_t> delta_list;
  1454. delta_list.reserve(std::min<std::size_t>(32,(s.size() / p_size) + 1));
  1455. while (std::string::npos != (pos = s.find(p,pos)))
  1456. {
  1457. delta_list.push_back(pos);
  1458. pos += p_size;
  1459. }
  1460. if (delta_list.empty())
  1461. {
  1462. n.assign(s);
  1463. return;
  1464. }
  1465. n.resize(delta_list.size() * inc + s.size(), 0x00);
  1466. char* n_itr = const_cast<char*>(n.data());
  1467. const char* s_end = s.data() + s.size();
  1468. const char* s_itr = s.data();
  1469. const char* r_begin = r.data();
  1470. const char* r_end = r.data() + r_size;
  1471. const std::size_t delta_list_size = delta_list.size();
  1472. std::size_t i = 0;
  1473. std::size_t delta = delta_list[0];
  1474. for ( ; ; )
  1475. {
  1476. std::copy(s_itr, s_itr + delta, n_itr);
  1477. s_itr += p_size + delta;
  1478. n_itr += delta;
  1479. std::copy(r_begin, r_end, n_itr);
  1480. n_itr += r_size;
  1481. if (++i >= delta_list_size)
  1482. break;
  1483. delta = delta_list[i] - (delta_list[i - 1] + p_size);
  1484. }
  1485. if (s_end != s_itr)
  1486. {
  1487. std::copy(s_itr, s_end, n_itr);
  1488. }
  1489. }
  1490. template <typename InputIterator, typename OutputIterator>
  1491. inline std::size_t replace_pattern(const InputIterator s_begin, const InputIterator s_end, // input
  1492. const InputIterator p_begin, const InputIterator p_end, // pattern
  1493. const InputIterator r_begin, const InputIterator r_end, // replacement
  1494. OutputIterator out)
  1495. {
  1496. InputIterator s_itr = s_begin;
  1497. InputIterator r_itr = r_begin;
  1498. InputIterator p_itr = p_begin;
  1499. const std::size_t p_size = std::distance(p_begin,p_end);
  1500. const std::size_t r_size = std::distance(r_begin,r_end);
  1501. if (
  1502. (0 == p_size) ||
  1503. (
  1504. (p_size == r_size) &&
  1505. std::equal(p_begin,p_end,r_begin)
  1506. )
  1507. )
  1508. {
  1509. std::copy(s_begin,s_end,out);
  1510. return std::distance(s_begin,s_end);
  1511. }
  1512. std::size_t pos = 0;
  1513. std::size_t prev_pos = 0;
  1514. std::size_t count = 0;
  1515. std::size_t new_size = std::distance(s_begin,s_end);
  1516. int inc = r_size - p_size;
  1517. InputIterator temp_s_itr = s_itr;
  1518. while (s_end != s_itr)
  1519. {
  1520. /*
  1521. Need to replace the following search code with
  1522. Knuth-Pratt-Morris or Boyer-Moore string search
  1523. algorithms.
  1524. */
  1525. bool found = true;
  1526. p_itr = p_begin;
  1527. temp_s_itr = s_itr;
  1528. while ((p_end != p_itr) && (s_end != temp_s_itr))
  1529. {
  1530. if (*(temp_s_itr++) != *(p_itr++))
  1531. {
  1532. found = false;
  1533. break;
  1534. }
  1535. }
  1536. if (found && (p_itr == p_end))
  1537. {
  1538. ++count;
  1539. new_size += inc;
  1540. s_itr = temp_s_itr;
  1541. }
  1542. else
  1543. ++s_itr;
  1544. }
  1545. s_itr = s_begin;
  1546. p_itr = p_begin;
  1547. pos = 0;
  1548. prev_pos = 0;
  1549. temp_s_itr = s_itr;
  1550. while (0 < count)
  1551. {
  1552. p_itr = p_begin;
  1553. bool found = true;
  1554. InputIterator pattern_start = temp_s_itr;
  1555. while ((p_end != p_itr) && (s_end != temp_s_itr))
  1556. {
  1557. if (*(temp_s_itr++) != *(p_itr++))
  1558. {
  1559. found = false;
  1560. temp_s_itr = pattern_start;
  1561. ++temp_s_itr;
  1562. break;
  1563. }
  1564. }
  1565. if (!found || (p_itr != p_end)) continue;
  1566. pos = std::distance(s_begin,temp_s_itr) - p_size;
  1567. int diff = pos - prev_pos;
  1568. std::copy(s_itr,s_itr + diff, out);
  1569. s_itr = temp_s_itr;
  1570. std::copy(r_itr,r_end, out);
  1571. pos += p_size;
  1572. prev_pos = pos;
  1573. --count;
  1574. }
  1575. std::copy(s_itr,s_end,out);
  1576. return new_size;
  1577. }
  1578. inline void remove_pattern(const std::string& s,
  1579. const std::string& p,
  1580. std::string& n)
  1581. {
  1582. static const std::string r("");
  1583. replace_pattern(s,p,r,n);
  1584. }
  1585. inline void sort(std::string& s)
  1586. {
  1587. std::sort(s.begin(),s.end());
  1588. }
  1589. template <typename Iterator>
  1590. inline bool match(const Iterator pattern_begin,
  1591. const Iterator pattern_end,
  1592. const Iterator data_begin,
  1593. const Iterator data_end,
  1594. const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
  1595. const typename std::iterator_traits<Iterator>::value_type& zero_or_one)
  1596. {
  1597. /*
  1598. Credits: Adapted from code by Jack Handy (2001)
  1599. */
  1600. if (0 == std::distance(data_begin,data_end)) return false;
  1601. Iterator d_itr = data_begin;
  1602. Iterator p_itr = pattern_begin;
  1603. Iterator c_itr = data_begin;
  1604. Iterator m_itr = data_begin;
  1605. while ((data_end != d_itr) && (zero_or_more != (*p_itr)))
  1606. {
  1607. if (((*p_itr) != (*d_itr)) && (zero_or_one != (*p_itr)))
  1608. {
  1609. return false;
  1610. }
  1611. ++p_itr;
  1612. ++d_itr;
  1613. }
  1614. while (data_end != d_itr)
  1615. {
  1616. if (zero_or_more == (*p_itr))
  1617. {
  1618. if (pattern_end == (++p_itr))
  1619. {
  1620. return true;
  1621. }
  1622. m_itr = p_itr;
  1623. c_itr = d_itr;
  1624. ++c_itr;
  1625. }
  1626. else if (((*p_itr) == (*d_itr)) || (zero_or_one == (*p_itr)))
  1627. {
  1628. ++p_itr;
  1629. ++d_itr;
  1630. }
  1631. else
  1632. {
  1633. p_itr = m_itr;
  1634. d_itr = c_itr++;
  1635. }
  1636. }
  1637. while ((p_itr != pattern_end) && (zero_or_more == (*p_itr))) ++p_itr;
  1638. return (p_itr == pattern_end);
  1639. }
  1640. inline bool match(const std::string& wild_card,
  1641. const std::string& str)
  1642. {
  1643. /*
  1644. * : Zero or more match
  1645. ? : Zero or one match
  1646. */
  1647. return match(wild_card.data(),
  1648. wild_card.data() + wild_card.size(),
  1649. str.data(),
  1650. str.data() + str.size(),
  1651. '*',
  1652. '?');
  1653. }
  1654. inline bool imatch_char(const char c1, const char c2)
  1655. {
  1656. return std::toupper(c1) == std::toupper(c2);
  1657. }
  1658. template <typename InputIterator>
  1659. inline bool imatch(const InputIterator begin1, const InputIterator end1,
  1660. const InputIterator begin2, const InputIterator end2)
  1661. {
  1662. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1663. details::convert_type_assert<itr_type>();
  1664. if (std::distance(begin1,end1) != std::distance(begin2,end2))
  1665. {
  1666. return false;
  1667. }
  1668. InputIterator itr1 = begin1;
  1669. InputIterator itr2 = begin2;
  1670. while (end1 != itr1)
  1671. {
  1672. //if (std::toupper(*itr1, std::locale::classic()) != std::toupper(*it2, std::locale::classic()))
  1673. if (std::toupper(*itr1) != std::toupper(*itr2))
  1674. {
  1675. return false;
  1676. }
  1677. ++itr1;
  1678. ++itr2;
  1679. }
  1680. return true;
  1681. }
  1682. template <typename T>
  1683. inline bool imatch(const range::adapter<T>& r1, const range::adapter<T>& r2)
  1684. {
  1685. return imatch(r1.begin(),r1.end(),r2.begin(),r2.end());
  1686. }
  1687. inline bool imatch(const std::string& s1, const std::string& s2)
  1688. {
  1689. return imatch(s1.data(),
  1690. s1.data() + s1.size(),
  1691. s2.data(),
  1692. s2.data() + s2.size());
  1693. }
  1694. template <typename Iterator>
  1695. inline Iterator imatch(const std::string& s, const Iterator begin, const Iterator end)
  1696. {
  1697. for (const std::string* itr = begin; end != itr; ++itr)
  1698. {
  1699. if (imatch(s,*itr))
  1700. {
  1701. return itr;
  1702. }
  1703. }
  1704. return end;
  1705. }
  1706. template <typename Allocator,
  1707. template <typename,typename> class Sequence>
  1708. inline bool imatch(const std::string& s, const Sequence<std::string,Allocator>& sequence)
  1709. {
  1710. return (sequence.end() != imatch(s,sequence.begin(),sequence.end()));
  1711. }
  1712. template <typename Comparator, typename Allocator>
  1713. inline bool imatch(const std::string& s, const std::set<std::string,Comparator,Allocator>& set)
  1714. {
  1715. return imatch(s,set.begin(),set.end());
  1716. }
  1717. template <typename Comparator, typename Allocator>
  1718. inline bool imatch(const std::string& s, const std::multiset<std::string,Comparator,Allocator>& multiset)
  1719. {
  1720. return imatch(s,multiset.begin(),multiset.end());
  1721. }
  1722. template <typename Iterator, typename OutputIterator>
  1723. inline std::size_t find_all(const Iterator pattern_begin,
  1724. const Iterator pattern_end,
  1725. const Iterator begin,
  1726. const Iterator end,
  1727. OutputIterator out)
  1728. {
  1729. Iterator itr = begin;
  1730. const std::size_t pattern_length = std::distance(pattern_begin,pattern_end);
  1731. std::size_t match_count = 0;
  1732. while (end != (itr = std::search(itr, end, pattern_begin, pattern_end)))
  1733. {
  1734. (*out) = std::make_pair(itr,itr + pattern_length);
  1735. itr += pattern_length;
  1736. ++out;
  1737. ++match_count;
  1738. }
  1739. return match_count;
  1740. }
  1741. template <typename Iterator,
  1742. typename Range,
  1743. typename Allocator,
  1744. template <typename,typename> class Sequence>
  1745. inline std::size_t find_all(const Iterator pattern_begin,
  1746. const Iterator pattern_end,
  1747. const Iterator begin,
  1748. const Iterator end,
  1749. Sequence<Range,Allocator>& seq)
  1750. {
  1751. return find_all(pattern_begin,pattern_end,begin,end,std::back_inserter(seq));
  1752. }
  1753. inline std::size_t ifind(const std::string& pattern, const std::string& data)
  1754. {
  1755. if (pattern.size() > data.size())
  1756. return std::string::npos;
  1757. const char* result_itr = std::search(data.data(),data.data() + data.size(),
  1758. pattern.data(), pattern.data() + pattern.size(),
  1759. imatch_char);
  1760. if ((data.data() + data.size()) == result_itr)
  1761. return std::string::npos;
  1762. else
  1763. return std::distance(data.data(),result_itr);
  1764. }
  1765. template <typename Iterator, typename OutputIterator>
  1766. inline std::size_t ifind_all(const Iterator pattern_begin,
  1767. const Iterator pattern_end,
  1768. const Iterator begin,
  1769. const Iterator end,
  1770. OutputIterator out)
  1771. {
  1772. Iterator itr = begin;
  1773. const std::size_t pattern_length = std::distance(pattern_begin,pattern_end);
  1774. std::size_t match_count = 0;
  1775. while (end != (itr = std::search(itr, end, pattern_begin, pattern_end, imatch_char)))
  1776. {
  1777. (*out) = std::make_pair(itr,itr + pattern_length);
  1778. itr += pattern_length;
  1779. ++out;
  1780. ++match_count;
  1781. }
  1782. return match_count;
  1783. }
  1784. template <typename OutputIterator>
  1785. inline std::size_t find_all(const std::string& pattern,
  1786. const std::string& data,
  1787. OutputIterator out)
  1788. {
  1789. return find_all(pattern.data(), pattern.data() + pattern.size(),
  1790. data.data(), data.data() + data.size(),
  1791. out);
  1792. }
  1793. template <typename Range,
  1794. typename Allocator,
  1795. template <typename,typename> class Sequence>
  1796. inline std::size_t find_all(const std::string& pattern,
  1797. const std::string& data,
  1798. Sequence<Range,Allocator>& seq)
  1799. {
  1800. return find_all(pattern,data,std::back_inserter(seq));
  1801. }
  1802. template <typename OutputIterator>
  1803. inline std::size_t ifind_all(const std::string& pattern,
  1804. const std::string& data,
  1805. OutputIterator out)
  1806. {
  1807. return ifind_all(pattern.data(), pattern.data() + pattern.size(),
  1808. data.data(), data.data() + data.size(),
  1809. out);
  1810. }
  1811. template <typename Range,
  1812. typename Allocator,
  1813. template <typename,typename> class Sequence>
  1814. inline std::size_t ifind_all(const std::string& pattern,
  1815. const std::string& data,
  1816. Sequence<Range,Allocator>& seq)
  1817. {
  1818. return ifind_all(pattern,data,std::back_inserter(seq));
  1819. }
  1820. template <typename InputIterator>
  1821. inline bool begins_with(const InputIterator pattern_begin,
  1822. const InputIterator pattern_end,
  1823. const InputIterator begin,
  1824. const InputIterator end)
  1825. {
  1826. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1827. details::convert_type_assert<itr_type>();
  1828. if (std::distance(pattern_begin,pattern_end) <= std::distance(begin,end))
  1829. {
  1830. return std::equal(pattern_begin,pattern_end,begin);
  1831. }
  1832. else
  1833. return false;
  1834. }
  1835. inline bool begins_with(const std::string& pattern, const std::string& data)
  1836. {
  1837. if (pattern.size() <= data.size())
  1838. {
  1839. return begins_with(pattern.data(),
  1840. pattern.data() + pattern.size(),
  1841. data.data(),
  1842. data.data() + data.size());
  1843. }
  1844. else
  1845. return false;
  1846. }
  1847. template <typename InputIterator>
  1848. inline bool ibegins_with(const InputIterator pattern_begin,
  1849. const InputIterator pattern_end,
  1850. const InputIterator begin,
  1851. const InputIterator end)
  1852. {
  1853. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1854. details::convert_type_assert<itr_type>();
  1855. if (std::distance(pattern_begin,pattern_end) <= std::distance(begin,end))
  1856. {
  1857. return std::equal(pattern_begin,pattern_end,begin,imatch_char);
  1858. }
  1859. else
  1860. return false;
  1861. }
  1862. inline bool ibegins_with(const std::string& pattern, const std::string& data)
  1863. {
  1864. if (pattern.size() <= data.size())
  1865. {
  1866. return ibegins_with(pattern.data(),
  1867. pattern.data() + pattern.size(),
  1868. data.data(),
  1869. data.data() + data.size());
  1870. }
  1871. else
  1872. return false;
  1873. }
  1874. template <typename InputIterator>
  1875. inline bool ends_with(const InputIterator pattern_begin,
  1876. const InputIterator pattern_end,
  1877. const InputIterator begin,
  1878. const InputIterator end)
  1879. {
  1880. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1881. details::convert_type_assert<itr_type>();
  1882. const std::size_t pattern_length = std::distance(pattern_begin,pattern_end);
  1883. const std::size_t data_length = std::distance(begin,end);
  1884. if (pattern_length <= data_length)
  1885. {
  1886. return std::equal(pattern_begin,
  1887. pattern_end,
  1888. begin + (data_length - pattern_length));
  1889. }
  1890. else
  1891. return false;
  1892. }
  1893. inline bool ends_with(const std::string& pattern, const std::string& data)
  1894. {
  1895. if (pattern.size() <= data.size())
  1896. {
  1897. return ends_with(pattern.data(),
  1898. pattern.data() + pattern.size(),
  1899. data.data(),
  1900. data.data() + data.size());
  1901. }
  1902. else
  1903. return false;
  1904. }
  1905. template <typename InputIterator>
  1906. inline bool iends_with(const InputIterator pattern_begin,
  1907. const InputIterator pattern_end,
  1908. const InputIterator begin,
  1909. const InputIterator end)
  1910. {
  1911. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  1912. details::convert_type_assert<itr_type>();
  1913. const std::size_t pattern_length = std::distance(pattern_begin,pattern_end);
  1914. const std::size_t data_length = std::distance(begin,end);
  1915. if (pattern_length <= data_length)
  1916. {
  1917. return std::equal(pattern_begin,
  1918. pattern_end,
  1919. begin + (data_length - pattern_length),
  1920. imatch_char);
  1921. }
  1922. else
  1923. return false;
  1924. }
  1925. inline bool iends_with(const std::string& pattern, const std::string& data)
  1926. {
  1927. if (pattern.size() <= data.size())
  1928. {
  1929. return iends_with(pattern.data(),
  1930. pattern.data() + pattern.size(),
  1931. data.data(),
  1932. data.data() + data.size());
  1933. }
  1934. else
  1935. return false;
  1936. }
  1937. inline std::size_t index_of(const std::string& pattern, const std::string& data)
  1938. {
  1939. if (pattern.empty())
  1940. return std::string::npos;
  1941. else if (data.empty())
  1942. return std::string::npos;
  1943. else if (pattern.size() > data.size())
  1944. return std::string::npos;
  1945. const char* itr = std::search(data.data(),
  1946. data.data() + data.size(),
  1947. pattern.data(),
  1948. pattern.data() + pattern.size());
  1949. return ((data.data() + data.size()) == itr) ? std::string::npos : std::distance(data.data(),itr);
  1950. }
  1951. namespace tokenize_options
  1952. {
  1953. typedef std::size_t type;
  1954. enum
  1955. {
  1956. default_mode = 0,
  1957. compress_delimiters = 1,
  1958. include_1st_delimiter = 2,
  1959. include_all_delimiters = 4
  1960. };
  1961. static inline bool perform_compress_delimiters(const type& split_opt)
  1962. {
  1963. return compress_delimiters == (split_opt & compress_delimiters);
  1964. }
  1965. static inline bool perform_include_1st_delimiter(const type& split_opt)
  1966. {
  1967. return include_1st_delimiter == (split_opt & include_1st_delimiter);
  1968. }
  1969. static inline bool perform_include_all_delimiters(const type& split_opt)
  1970. {
  1971. return include_all_delimiters == (split_opt & include_all_delimiters);
  1972. }
  1973. } // namespace tokenize_options
  1974. template <typename Iterator, typename DelimiterPredicate>
  1975. class tokenizer
  1976. {
  1977. private:
  1978. template <typename Iterartor,
  1979. typename Predicate,
  1980. typename T = std::pair<Iterator,Iterator> >
  1981. class tokenizer_iterator : public std::iterator<std::forward_iterator_tag,T>
  1982. {
  1983. protected:
  1984. typedef Iterator iterator;
  1985. typedef const iterator const_iterator;
  1986. typedef typename std::pair<iterator,iterator> range_type;
  1987. public:
  1988. explicit inline tokenizer_iterator(const iterator begin,
  1989. const iterator end,
  1990. const Predicate& predicate,
  1991. const tokenize_options::type tokenize_option = tokenize_options::default_mode)
  1992. : predicate_(predicate),
  1993. end_(end),
  1994. range_(begin,begin),
  1995. current_token_(end,end),
  1996. compress_delimiters_(tokenize_options::perform_compress_delimiters(tokenize_option)),
  1997. include_1st_delimiter_(tokenize_options::perform_include_1st_delimiter(tokenize_option)),
  1998. include_all_delimiters_(tokenize_options::perform_include_all_delimiters(tokenize_option)),
  1999. include_delimiters_(include_1st_delimiter_ || include_all_delimiters_),
  2000. last_token_done_(false)
  2001. {
  2002. if (end != begin)
  2003. {
  2004. this->operator++();
  2005. }
  2006. }
  2007. inline tokenizer_iterator& operator++()
  2008. {
  2009. if (last_token_done_)
  2010. {
  2011. range_.first = range_.second;
  2012. return (*this);
  2013. }
  2014. else if (end_ != range_.second)
  2015. {
  2016. range_.first = range_.second;
  2017. }
  2018. while (end_ != range_.second)
  2019. {
  2020. if (predicate_(*(range_.second)))
  2021. {
  2022. if (include_delimiters_)
  2023. {
  2024. if (include_1st_delimiter_)
  2025. ++range_.second;
  2026. else if (include_all_delimiters_)
  2027. while ((end_ != range_.second) && predicate_(*(range_.second))) ++range_.second;
  2028. current_token_ = range_;
  2029. if ((!include_all_delimiters_) && compress_delimiters_)
  2030. while ((end_ != range_.second) && predicate_(*(range_.second))) ++range_.second;
  2031. }
  2032. else
  2033. {
  2034. current_token_ = range_;
  2035. if (compress_delimiters_)
  2036. while ((end_ != (++range_.second)) && predicate_(*(range_.second))) ;
  2037. else
  2038. ++range_.second;
  2039. }
  2040. return (*this);
  2041. }
  2042. else
  2043. ++range_.second;
  2044. }
  2045. if (range_.first != range_.second)
  2046. {
  2047. current_token_.second = range_.second;
  2048. if (!last_token_done_)
  2049. {
  2050. if (predicate_(*(range_.second - 1)))
  2051. current_token_.first = range_.second;
  2052. else
  2053. current_token_.first = range_.first;
  2054. last_token_done_ = true;
  2055. }
  2056. else
  2057. range_.first = range_.second;
  2058. }
  2059. return (*this);
  2060. }
  2061. inline tokenizer_iterator operator++(int)
  2062. {
  2063. tokenizer_iterator tmp = (*this);
  2064. this->operator++();
  2065. return tmp;
  2066. }
  2067. inline tokenizer_iterator& operator+=(const int inc)
  2068. {
  2069. if (inc > 0)
  2070. {
  2071. for (int i = 0; i < inc; ++i, ++(*this)) ;
  2072. }
  2073. return (*this);
  2074. }
  2075. inline T operator*() const
  2076. {
  2077. return current_token_;
  2078. }
  2079. inline std::string as_string() const
  2080. {
  2081. return std::string(current_token_.first,current_token_.second);
  2082. }
  2083. inline bool operator==(const tokenizer_iterator& itr) const
  2084. {
  2085. return (range_ == itr.range_) && (end_ == itr.end_);
  2086. }
  2087. inline bool operator!=(const tokenizer_iterator& itr) const
  2088. {
  2089. return (range_ != itr.range_) || (end_ != itr.end_);
  2090. }
  2091. inline tokenizer_iterator& operator=(const tokenizer_iterator& itr)
  2092. {
  2093. if (this != &itr)
  2094. {
  2095. range_ = itr.range_;
  2096. current_token_ = itr.current_token_;
  2097. end_ = itr.end_;
  2098. compress_delimiters_ = itr.compress_delimiters_;
  2099. include_1st_delimiter_ = itr.include_1st_delimiter_;
  2100. include_all_delimiters_ = itr.include_all_delimiters_;
  2101. include_delimiters_ = itr.include_delimiters_;
  2102. last_token_done_ = itr.last_token_done_;
  2103. }
  2104. return (*this);
  2105. }
  2106. inline std::string remaining() const
  2107. {
  2108. return std::string(current_token_.first,end_);
  2109. }
  2110. protected:
  2111. const Predicate& predicate_;
  2112. iterator end_;
  2113. range_type range_;
  2114. range_type current_token_;
  2115. bool compress_delimiters_;
  2116. bool include_1st_delimiter_;
  2117. bool include_all_delimiters_;
  2118. bool include_delimiters_;
  2119. bool last_token_done_;
  2120. };
  2121. public:
  2122. typedef typename std::iterator_traits<Iterator>::value_type value_type;
  2123. typedef DelimiterPredicate predicate;
  2124. typedef tokenizer_iterator<Iterator,DelimiterPredicate> iterator;
  2125. typedef const iterator const_iterator;
  2126. typedef iterator& iterator_ref;
  2127. typedef const_iterator& const_iterator_ref;
  2128. inline tokenizer(const Iterator begin,
  2129. const Iterator end,
  2130. const DelimiterPredicate& predicate,
  2131. const tokenize_options::type tokenize_options = tokenize_options::default_mode)
  2132. : tokenize_options_(tokenize_options),
  2133. predicate_(predicate),
  2134. begin_(begin),
  2135. end_(end),
  2136. begin_itr_(begin_,end_,predicate_,tokenize_options_),
  2137. end_itr_(end_,end_,predicate_,tokenize_options_)
  2138. {}
  2139. inline tokenizer(const std::string& s,
  2140. const DelimiterPredicate& predicate,
  2141. const tokenize_options::type tokenize_options = tokenize_options::default_mode)
  2142. : tokenize_options_(tokenize_options),
  2143. predicate_(predicate),
  2144. begin_(s.data()),
  2145. end_(s.data() + s.size()),
  2146. begin_itr_(begin_,end_,predicate_,tokenize_options_),
  2147. end_itr_(end_,end_,predicate_,tokenize_options_)
  2148. {}
  2149. inline tokenizer& operator=(const tokenizer& t)
  2150. {
  2151. if (this != &t)
  2152. {
  2153. begin_ = t.begin_;
  2154. end_ = t.end_;
  2155. end_itr_ = t.end_itr_;
  2156. begin_itr_ = t.begin_itr_;
  2157. tokenize_options_ = t.tokenize_options_;
  2158. }
  2159. return (*this);
  2160. }
  2161. inline void assign(const std::string& s) const
  2162. {
  2163. assign(s.data(),s.data() + s.size());
  2164. }
  2165. inline void assign(const std::string& s)
  2166. {
  2167. assign(s.data(),s.data() + s.size());
  2168. }
  2169. inline void assign(const Iterator begin, const Iterator end)
  2170. {
  2171. begin_ = begin;
  2172. end_ = end;
  2173. begin_itr_ = iterator(begin_,end_,predicate_,tokenize_options_);
  2174. end_itr_ = iterator(end_,end_,predicate_,tokenize_options_);
  2175. }
  2176. inline const_iterator_ref begin() const
  2177. {
  2178. return begin_itr_;
  2179. }
  2180. inline const_iterator_ref end() const
  2181. {
  2182. return end_itr_;
  2183. }
  2184. private:
  2185. tokenize_options::type tokenize_options_;
  2186. const DelimiterPredicate& predicate_;
  2187. Iterator begin_;
  2188. Iterator end_;
  2189. iterator begin_itr_;
  2190. iterator end_itr_;
  2191. };
  2192. namespace std_string
  2193. {
  2194. template <typename DelimiterPredicate = single_delimiter_predicate<std::string::value_type> >
  2195. struct tokenizer
  2196. {
  2197. typedef DelimiterPredicate predicate_type;
  2198. typedef const std::string::value_type* string_iterator_type;
  2199. typedef strtk::tokenizer<string_iterator_type,DelimiterPredicate> type;
  2200. typedef strtk::tokenizer<string_iterator_type,multiple_char_delimiter_predicate> md_type;
  2201. typedef std::pair<string_iterator_type,string_iterator_type> iterator_type;
  2202. };
  2203. typedef tokenizer<>::iterator_type iterator_type;
  2204. typedef tokenizer<>::iterator_type range_t;
  2205. typedef std::vector<iterator_type> token_vector_type;
  2206. typedef std::deque<iterator_type> token_deque_type;
  2207. typedef std::list<iterator_type> token_list_type;
  2208. } // namespace std_string
  2209. template <typename Sequence>
  2210. class range_to_type_back_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2211. void,
  2212. void,
  2213. void,
  2214. void>
  2215. {
  2216. public:
  2217. typedef typename Sequence::value_type value_type;
  2218. explicit inline range_to_type_back_inserter_iterator(Sequence& sequence)
  2219. : sequence_(sequence)
  2220. {}
  2221. range_to_type_back_inserter_iterator(const range_to_type_back_inserter_iterator& itr)
  2222. : sequence_(itr.sequence_)
  2223. {}
  2224. inline range_to_type_back_inserter_iterator& operator=(const range_to_type_back_inserter_iterator& itr)
  2225. {
  2226. if (this != &itr)
  2227. {
  2228. this->sequence_ = itr.sequence_;
  2229. }
  2230. return (*this);
  2231. }
  2232. template <typename Iterator>
  2233. inline range_to_type_back_inserter_iterator& operator=(const std::pair<Iterator,Iterator>& r)
  2234. {
  2235. value_type t;
  2236. if (string_to_type_converter(r.first,r.second,t))
  2237. sequence_.push_back(t);
  2238. return (*this);
  2239. }
  2240. inline range_to_type_back_inserter_iterator& operator=(const std::string& s)
  2241. {
  2242. value_type t;
  2243. if (string_to_type_converter(s.data(),s.data() + s.size(),t))
  2244. sequence_.push_back(t);
  2245. return (*this);
  2246. }
  2247. template <typename Iterator>
  2248. inline void operator()(const std::pair<Iterator,Iterator>& r) const
  2249. {
  2250. value_type t;
  2251. if (string_to_type_converter(r.first,r.second,t))
  2252. sequence_.push_back(t);
  2253. }
  2254. template <typename Iterator>
  2255. inline void operator()(const Iterator begin, const Iterator end)
  2256. {
  2257. sequence_.push_back(string_to_type_converter<value_type>(begin,end));
  2258. }
  2259. inline range_to_type_back_inserter_iterator& operator*()
  2260. {
  2261. return (*this);
  2262. }
  2263. inline range_to_type_back_inserter_iterator& operator++()
  2264. {
  2265. return (*this);
  2266. }
  2267. inline range_to_type_back_inserter_iterator operator++(int)
  2268. {
  2269. return (*this);
  2270. }
  2271. private:
  2272. Sequence& sequence_;
  2273. };
  2274. template <typename Sequence>
  2275. inline range_to_type_back_inserter_iterator<Sequence> range_to_type_back_inserter(Sequence& sequence)
  2276. {
  2277. return (range_to_type_back_inserter_iterator<Sequence>(sequence));
  2278. }
  2279. template <typename Set>
  2280. class range_to_type_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2281. void,
  2282. void,
  2283. void,
  2284. void>
  2285. {
  2286. public:
  2287. typedef typename Set::value_type value_type;
  2288. explicit inline range_to_type_inserter_iterator(Set& set)
  2289. : set_(set)
  2290. {}
  2291. range_to_type_inserter_iterator(const range_to_type_inserter_iterator& itr)
  2292. : set_(itr.set_)
  2293. {}
  2294. inline range_to_type_inserter_iterator& operator=(const range_to_type_inserter_iterator& itr)
  2295. {
  2296. if (this != &itr)
  2297. {
  2298. this->set_ = itr.set_;
  2299. }
  2300. return (*this);
  2301. }
  2302. template <typename Iterator>
  2303. inline range_to_type_inserter_iterator& operator=(const std::pair<Iterator,Iterator>& r)
  2304. {
  2305. value_type t;
  2306. if (string_to_type_converter(r.first,r.second,t))
  2307. set_.insert(t);
  2308. return (*this);
  2309. }
  2310. template <typename Iterator>
  2311. inline void operator()(const std::pair<Iterator,Iterator>& r)
  2312. {
  2313. value_type t;
  2314. if (string_to_type_converter(r.first,r.second,t))
  2315. set_.insert(t);
  2316. }
  2317. inline range_to_type_inserter_iterator& operator*()
  2318. {
  2319. return (*this);
  2320. }
  2321. inline range_to_type_inserter_iterator& operator++()
  2322. {
  2323. return (*this);
  2324. }
  2325. inline range_to_type_inserter_iterator operator++(int)
  2326. {
  2327. return (*this);
  2328. }
  2329. private:
  2330. Set& set_;
  2331. };
  2332. template <typename Set>
  2333. inline range_to_type_inserter_iterator<Set> range_to_type_inserter(Set& set)
  2334. {
  2335. return (range_to_type_inserter_iterator<Set>(set));
  2336. }
  2337. template <typename Container>
  2338. class range_to_type_push_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2339. void,
  2340. void,
  2341. void,
  2342. void>
  2343. {
  2344. public:
  2345. typedef typename Container::value_type value_type;
  2346. explicit inline range_to_type_push_inserter_iterator(Container& container)
  2347. : container_(container)
  2348. {}
  2349. range_to_type_push_inserter_iterator(const range_to_type_push_inserter_iterator& itr)
  2350. : container_(itr.container_)
  2351. {}
  2352. inline range_to_type_push_inserter_iterator& operator=(const range_to_type_push_inserter_iterator& itr)
  2353. {
  2354. if (this != &itr)
  2355. {
  2356. this->container_ = itr.container_;
  2357. }
  2358. return (*this);
  2359. }
  2360. template <typename Iterator>
  2361. inline range_to_type_push_inserter_iterator& operator=(const std::pair<Iterator,Iterator>& r)
  2362. {
  2363. value_type t;
  2364. if (string_to_type_converter(r.first,r.second,t))
  2365. container_.push(t);
  2366. return (*this);
  2367. }
  2368. template <typename Iterator>
  2369. inline void operator()(const std::pair<Iterator,Iterator>& r)
  2370. {
  2371. value_type t;
  2372. if (string_to_type_converter(r.first,r.second,t))
  2373. container_.push(t);
  2374. }
  2375. inline range_to_type_push_inserter_iterator& operator*()
  2376. {
  2377. return (*this);
  2378. }
  2379. inline range_to_type_push_inserter_iterator& operator++()
  2380. {
  2381. return (*this);
  2382. }
  2383. inline range_to_type_push_inserter_iterator operator++(int)
  2384. {
  2385. return (*this);
  2386. }
  2387. private:
  2388. Container& container_;
  2389. };
  2390. template <typename Container>
  2391. inline range_to_type_push_inserter_iterator<Container> range_to_type_push_inserter(Container& container)
  2392. {
  2393. return (range_to_type_push_inserter_iterator<Container>(container));
  2394. }
  2395. template <typename Sequence>
  2396. class back_inserter_with_valuetype_iterator : public std::iterator<std::output_iterator_tag,
  2397. typename Sequence::value_type,
  2398. void,
  2399. void,
  2400. void>
  2401. {
  2402. public:
  2403. explicit inline back_inserter_with_valuetype_iterator(Sequence& sequence)
  2404. : sequence_(sequence)
  2405. {}
  2406. back_inserter_with_valuetype_iterator(const back_inserter_with_valuetype_iterator& itr)
  2407. : sequence_(itr.sequence_)
  2408. {}
  2409. inline back_inserter_with_valuetype_iterator& operator=(const back_inserter_with_valuetype_iterator& itr)
  2410. {
  2411. if (this != &itr)
  2412. {
  2413. this->sequence_ = itr.sequence_;
  2414. }
  2415. return (*this);
  2416. }
  2417. inline back_inserter_with_valuetype_iterator& operator=(const typename Sequence::value_type& v)
  2418. {
  2419. sequence_.push_back(v);
  2420. return (*this);
  2421. }
  2422. inline void operator()(const typename Sequence::value_type& v)
  2423. {
  2424. sequence_.push_back(v);
  2425. }
  2426. inline back_inserter_with_valuetype_iterator& operator*()
  2427. {
  2428. return (*this);
  2429. }
  2430. inline back_inserter_with_valuetype_iterator& operator++()
  2431. {
  2432. return (*this);
  2433. }
  2434. inline back_inserter_with_valuetype_iterator operator++(int)
  2435. {
  2436. return (*this);
  2437. }
  2438. private:
  2439. Sequence& sequence_;
  2440. };
  2441. template <typename Sequence>
  2442. inline back_inserter_with_valuetype_iterator<Sequence> back_inserter_with_valuetype(Sequence& sequence_)
  2443. {
  2444. return (back_inserter_with_valuetype_iterator<Sequence>(sequence_));
  2445. }
  2446. template <typename Set>
  2447. class inserter_with_valuetype_iterator : public std::iterator<std::output_iterator_tag,
  2448. typename Set::value_type,
  2449. void,
  2450. void,
  2451. void>
  2452. {
  2453. public:
  2454. explicit inline inserter_with_valuetype_iterator(Set& set)
  2455. : set_(set)
  2456. {}
  2457. inserter_with_valuetype_iterator(const inserter_with_valuetype_iterator& itr)
  2458. : set_(itr.set_)
  2459. {}
  2460. inline inserter_with_valuetype_iterator& operator=(const inserter_with_valuetype_iterator& itr)
  2461. {
  2462. if (this != &itr)
  2463. {
  2464. this->set_ = itr.set_;
  2465. }
  2466. return (*this);
  2467. }
  2468. inline inserter_with_valuetype_iterator& operator=(const typename Set::value_type& v)
  2469. {
  2470. set_.insert(v);
  2471. return (*this);
  2472. }
  2473. inline void operator()(const typename Set::value_type& v)
  2474. {
  2475. set_.insert(v);
  2476. }
  2477. inline inserter_with_valuetype_iterator& operator*()
  2478. {
  2479. return (*this);
  2480. }
  2481. inline inserter_with_valuetype_iterator& operator++()
  2482. {
  2483. return (*this);
  2484. }
  2485. inline inserter_with_valuetype_iterator operator++(int)
  2486. {
  2487. return (*this);
  2488. }
  2489. private:
  2490. Set& set_;
  2491. };
  2492. template <typename Set>
  2493. inline inserter_with_valuetype_iterator<Set> inserter_with_valuetype(Set& set_)
  2494. {
  2495. return (inserter_with_valuetype_iterator<Set>(set_));
  2496. }
  2497. template <typename Container>
  2498. class push_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2499. void,
  2500. void,
  2501. void,
  2502. void>
  2503. {
  2504. public:
  2505. explicit inline push_inserter_iterator(Container& container)
  2506. : container_(container)
  2507. {}
  2508. inline push_inserter_iterator& operator=(const push_inserter_iterator& itr)
  2509. {
  2510. if (this != &itr)
  2511. {
  2512. this->container_ = itr.container_;
  2513. }
  2514. return (*this);
  2515. }
  2516. inline push_inserter_iterator<Container>& operator=(typename Container::const_reference v)
  2517. {
  2518. container_.push(v);
  2519. return (*this);
  2520. }
  2521. inline push_inserter_iterator<Container>& operator*()
  2522. {
  2523. return (*this);
  2524. }
  2525. inline push_inserter_iterator<Container>& operator++()
  2526. {
  2527. return (*this);
  2528. }
  2529. inline push_inserter_iterator<Container> operator++(int)
  2530. {
  2531. return (*this);
  2532. }
  2533. private:
  2534. Container& container_;
  2535. };
  2536. template <typename Container>
  2537. inline push_inserter_iterator<Container> push_inserter(Container& c)
  2538. {
  2539. return push_inserter_iterator<Container>(c);
  2540. }
  2541. template <typename T>
  2542. class range_to_ptr_type_iterator : public std::iterator<std::output_iterator_tag,
  2543. void,
  2544. void,
  2545. void,
  2546. void>
  2547. {
  2548. public:
  2549. typedef T value_type;
  2550. explicit inline range_to_ptr_type_iterator(T* pointer, std::size_t& insert_count)
  2551. : pointer_(pointer),
  2552. insert_count_(insert_count)
  2553. {}
  2554. range_to_ptr_type_iterator(const range_to_ptr_type_iterator& itr)
  2555. : pointer_(itr.pointer_)
  2556. {}
  2557. inline range_to_ptr_type_iterator& operator=(const range_to_ptr_type_iterator& itr)
  2558. {
  2559. if (this != &itr)
  2560. {
  2561. this->pointer_ = itr.pointer_;
  2562. }
  2563. return (*this);
  2564. }
  2565. template <typename Iterator>
  2566. inline range_to_ptr_type_iterator& operator=(const std::pair<Iterator,Iterator>& r)
  2567. {
  2568. value_type t = value_type();
  2569. if (string_to_type_converter(r.first,r.second,t))
  2570. {
  2571. (*pointer_) = t;
  2572. ++pointer_;
  2573. ++insert_count_;
  2574. }
  2575. return (*this);
  2576. }
  2577. inline range_to_ptr_type_iterator& operator=(const std::string& s)
  2578. {
  2579. value_type t = value_type();
  2580. if (string_to_type_converter(s.data(),s.data() + s.size(),t))
  2581. {
  2582. (*pointer_) = t;
  2583. ++pointer_;
  2584. ++insert_count_;
  2585. }
  2586. return (*this);
  2587. }
  2588. template <typename Iterator>
  2589. inline void operator()(const std::pair<Iterator,Iterator>& r) const
  2590. {
  2591. value_type t;
  2592. if (string_to_type_converter(r.first,r.second,t))
  2593. {
  2594. (*pointer_) = t;
  2595. ++pointer_;
  2596. ++insert_count_;
  2597. }
  2598. }
  2599. template <typename Iterator>
  2600. inline void operator()(const Iterator begin, const Iterator end)
  2601. {
  2602. (*pointer_) = string_to_type_converter<T>(begin,end);
  2603. ++pointer_;
  2604. ++insert_count_;
  2605. }
  2606. inline range_to_ptr_type_iterator& operator*()
  2607. {
  2608. return (*this);
  2609. }
  2610. inline range_to_ptr_type_iterator& operator++()
  2611. {
  2612. return (*this);
  2613. }
  2614. inline range_to_ptr_type_iterator operator++(int)
  2615. {
  2616. return (*this);
  2617. }
  2618. private:
  2619. T* pointer_;
  2620. std::size_t& insert_count_;
  2621. };
  2622. template <typename T>
  2623. inline range_to_ptr_type_iterator<T> range_to_ptr_type(T* pointer, std::size_t& insert_count)
  2624. {
  2625. return (range_to_ptr_type_iterator<T>(pointer,insert_count));
  2626. }
  2627. template <typename T>
  2628. inline range_to_ptr_type_iterator<T> range_to_ptr_type(T* pointer)
  2629. {
  2630. static std::size_t insert_count = 0;
  2631. return (range_to_ptr_type_iterator<T>(pointer,insert_count));
  2632. }
  2633. template <typename T>
  2634. class counting_back_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2635. T,
  2636. void,
  2637. void,
  2638. void>
  2639. {
  2640. public:
  2641. explicit inline counting_back_inserter_iterator(std::size_t& counter)
  2642. : counter_(counter)
  2643. {}
  2644. counting_back_inserter_iterator(const counting_back_inserter_iterator& itr)
  2645. : counter_(itr.counter_)
  2646. {}
  2647. inline counting_back_inserter_iterator& operator=(const counting_back_inserter_iterator& itr)
  2648. {
  2649. if (this != &itr)
  2650. {
  2651. this->counter_ = itr.counter_;
  2652. }
  2653. return (*this);
  2654. }
  2655. inline counting_back_inserter_iterator& operator=(const T&)
  2656. {
  2657. ++counter_;
  2658. return (*this);
  2659. }
  2660. inline void operator()(const T&)
  2661. {
  2662. ++counter_;
  2663. }
  2664. inline counting_back_inserter_iterator& operator*()
  2665. {
  2666. return (*this);
  2667. }
  2668. inline counting_back_inserter_iterator& operator++()
  2669. {
  2670. return (*this);
  2671. }
  2672. inline counting_back_inserter_iterator operator++(int)
  2673. {
  2674. return (*this);
  2675. }
  2676. private:
  2677. std::size_t& counter_;
  2678. };
  2679. template <typename T>
  2680. inline counting_back_inserter_iterator<T> counting_back_inserter(std::size_t& counter_)
  2681. {
  2682. return (counting_back_inserter_iterator<T>(counter_));
  2683. }
  2684. template <typename Function>
  2685. class functional_inserter_iterator : public std::iterator<std::output_iterator_tag,
  2686. void,
  2687. void,
  2688. void,
  2689. void>
  2690. {
  2691. public:
  2692. explicit inline functional_inserter_iterator(Function function)
  2693. : function_(function)
  2694. {}
  2695. functional_inserter_iterator(const functional_inserter_iterator& itr)
  2696. : function_(itr.function_)
  2697. {}
  2698. inline functional_inserter_iterator& operator=(const functional_inserter_iterator& itr)
  2699. {
  2700. if (this != &itr)
  2701. {
  2702. this->function_ = itr.function_;
  2703. }
  2704. return (*this);
  2705. }
  2706. template <typename T>
  2707. inline functional_inserter_iterator& operator=(const T& t)
  2708. {
  2709. function_(t);
  2710. return (*this);
  2711. }
  2712. template <typename T>
  2713. inline void operator()(const T& t)
  2714. {
  2715. function_(t);
  2716. }
  2717. inline functional_inserter_iterator& operator*()
  2718. {
  2719. return (*this);
  2720. }
  2721. inline functional_inserter_iterator& operator++()
  2722. {
  2723. return (*this);
  2724. }
  2725. inline functional_inserter_iterator operator++(int)
  2726. {
  2727. return (*this);
  2728. }
  2729. private:
  2730. Function function_;
  2731. };
  2732. template <typename Function>
  2733. inline functional_inserter_iterator<Function> functional_inserter(Function function)
  2734. {
  2735. return (functional_inserter_iterator<Function>(function));
  2736. }
  2737. namespace split_options
  2738. {
  2739. typedef std::size_t type;
  2740. enum
  2741. {
  2742. default_mode = 0,
  2743. compress_delimiters = 1,
  2744. include_1st_delimiter = 2,
  2745. include_all_delimiters = 4
  2746. };
  2747. static inline bool perform_compress_delimiters(const type& split_opt)
  2748. {
  2749. return compress_delimiters == (split_opt & compress_delimiters);
  2750. }
  2751. static inline bool perform_include_1st_delimiter(const type& split_opt)
  2752. {
  2753. return include_1st_delimiter == (split_opt & include_1st_delimiter);
  2754. }
  2755. static inline bool perform_include_all_delimiters(const type& split_opt)
  2756. {
  2757. return include_all_delimiters == (split_opt & include_all_delimiters);
  2758. }
  2759. } // namespace split_options
  2760. namespace details
  2761. {
  2762. template <typename DelimiterPredicate,
  2763. typename Iterator,
  2764. typename OutputIterator>
  2765. inline std::size_t split_compress_delimiters(const DelimiterPredicate& delimiter,
  2766. const Iterator begin,
  2767. const Iterator end,
  2768. OutputIterator out)
  2769. {
  2770. std::size_t token_count = 0;
  2771. std::pair<Iterator,Iterator> range(begin,begin);
  2772. while (end != range.second)
  2773. {
  2774. if (delimiter(*range.second))
  2775. {
  2776. (*out) = range;
  2777. ++out;
  2778. while ((end != ++range.second) && delimiter(*range.second));
  2779. range.first = range.second;
  2780. if (end != range.second)
  2781. ++range.second;
  2782. ++token_count;
  2783. }
  2784. else
  2785. ++range.second;
  2786. }
  2787. if ((range.first != range.second) || delimiter(*(range.second - 1)))
  2788. {
  2789. (*out) = range;
  2790. ++out;
  2791. ++token_count;
  2792. }
  2793. return token_count;
  2794. }
  2795. }
  2796. template <typename DelimiterPredicate,
  2797. typename Iterator,
  2798. typename OutputIterator>
  2799. inline std::size_t split(const DelimiterPredicate& delimiter,
  2800. const Iterator begin,
  2801. const Iterator end,
  2802. OutputIterator out,
  2803. const split_options::type split_option = split_options::default_mode)
  2804. {
  2805. if (begin == end) return 0;
  2806. const bool compress_delimiters = split_options::perform_compress_delimiters(split_option);
  2807. const bool include_1st_delimiter = split_options::perform_include_1st_delimiter(split_option);
  2808. const bool include_all_delimiters = (!include_1st_delimiter) && split_options::perform_include_all_delimiters(split_option);
  2809. const bool include_delimiters = include_1st_delimiter || include_all_delimiters;
  2810. if (compress_delimiters && (!include_delimiters))
  2811. {
  2812. return details::split_compress_delimiters(delimiter,begin,end,out);
  2813. }
  2814. std::size_t token_count = 0;
  2815. std::pair<Iterator,Iterator> range(begin,begin);
  2816. while (end != range.second)
  2817. {
  2818. if (delimiter(*range.second))
  2819. {
  2820. if (include_delimiters)
  2821. {
  2822. if (include_1st_delimiter)
  2823. ++range.second;
  2824. else if (include_all_delimiters)
  2825. while ((end != range.second) && delimiter(*range.second)) ++range.second;
  2826. (*out) = range;
  2827. ++out;
  2828. if ((!include_all_delimiters) && compress_delimiters)
  2829. while ((end != range.second) && delimiter(*range.second)) ++range.second;
  2830. }
  2831. else
  2832. {
  2833. (*out) = range;
  2834. ++out;
  2835. ++range.second;
  2836. }
  2837. ++token_count;
  2838. range.first = range.second;
  2839. }
  2840. else
  2841. ++range.second;
  2842. }
  2843. if ((range.first != range.second) || delimiter(*(range.second - 1)))
  2844. {
  2845. (*out) = range;
  2846. ++out;
  2847. ++token_count;
  2848. }
  2849. return token_count;
  2850. }
  2851. template <typename DelimiterPredicate,
  2852. typename Iterator,
  2853. typename OutputIterator>
  2854. inline std::size_t split(const DelimiterPredicate& delimiter,
  2855. const std::pair<Iterator,Iterator>& range,
  2856. OutputIterator out,
  2857. const split_options::type split_option = split_options::default_mode)
  2858. {
  2859. return split(delimiter,
  2860. range.first,range.second,
  2861. out,
  2862. split_option);
  2863. }
  2864. template <typename DelimiterPredicate,
  2865. typename Iterator,
  2866. typename OutputIterator>
  2867. inline std::size_t split(const char* delimiters,
  2868. const std::pair<Iterator,Iterator>& range,
  2869. OutputIterator out,
  2870. const split_options::type split_option = split_options::default_mode)
  2871. {
  2872. if (1 == details::strnlength(delimiters,256))
  2873. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2874. range.first,range.second,
  2875. out,
  2876. split_option);
  2877. else
  2878. return split(multiple_char_delimiter_predicate(delimiters),
  2879. range.first,range.second,
  2880. out,
  2881. split_option);
  2882. }
  2883. template <typename DelimiterPredicate,
  2884. typename Iterator,
  2885. typename OutputIterator>
  2886. inline std::size_t split(const std::string& delimiters,
  2887. const std::pair<Iterator,Iterator>& range,
  2888. OutputIterator out,
  2889. const split_options::type split_option = split_options::default_mode)
  2890. {
  2891. if (1 == delimiters.size())
  2892. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2893. range.first,range.second,
  2894. out,
  2895. split_option);
  2896. else
  2897. return split(multiple_char_delimiter_predicate(delimiters),
  2898. range.first,range.second,
  2899. out,
  2900. split_option);
  2901. }
  2902. template <typename OutputIterator>
  2903. inline std::size_t split(const char* delimiters,
  2904. const std::string& str,
  2905. OutputIterator out,
  2906. const split_options::type& split_option = split_options::default_mode)
  2907. {
  2908. if (1 == details::strnlength(delimiters,256))
  2909. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2910. str.data(), str.data() + str.size(),
  2911. out,
  2912. split_option);
  2913. else
  2914. return split(multiple_char_delimiter_predicate(delimiters),
  2915. str.data(), str.data() + str.size(),
  2916. out,
  2917. split_option);
  2918. }
  2919. template <typename OutputIterator>
  2920. inline std::size_t split(const std::string& delimiters,
  2921. const std::string& str,
  2922. OutputIterator out,
  2923. const split_options::type& split_option = split_options::default_mode)
  2924. {
  2925. if (1 == delimiters.size())
  2926. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2927. str.data(), str.data() + str.size(),
  2928. out,
  2929. split_option);
  2930. else
  2931. return split(multiple_char_delimiter_predicate(delimiters),
  2932. str.data(), str.data() + str.size(),
  2933. out,
  2934. split_option);
  2935. }
  2936. template <typename OutputIterator>
  2937. inline std::size_t split(const std::string::value_type delimiter,
  2938. const std::string& str,
  2939. OutputIterator out,
  2940. const split_options::type& split_option = split_options::default_mode)
  2941. {
  2942. return split(single_delimiter_predicate<std::string::value_type>(delimiter),
  2943. str.data(), str.data() + str.size(),
  2944. out,
  2945. split_option);
  2946. }
  2947. template <typename Allocator,
  2948. template <typename,typename> class Sequence>
  2949. inline std::size_t split(const char* delimiters,
  2950. const std::string& str,
  2951. Sequence<std::pair<const char*, const char*>,Allocator>& sequence,
  2952. const split_options::type& split_option = split_options::default_mode)
  2953. {
  2954. if (1 == details::strnlength(delimiters,256))
  2955. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2956. str.data(), str.data() + str.size(),
  2957. std::back_inserter(sequence),
  2958. split_option);
  2959. else
  2960. return split(multiple_char_delimiter_predicate(delimiters),
  2961. str.data(), str.data() + str.size(),
  2962. std::back_inserter(sequence),
  2963. split_option);
  2964. }
  2965. template <typename Allocator,
  2966. template <typename,typename> class Sequence>
  2967. inline std::size_t split(const std::string& delimiters,
  2968. const std::string& str,
  2969. Sequence<std::pair<const char*, const char*>,Allocator>& sequence,
  2970. const split_options::type& split_option = split_options::default_mode)
  2971. {
  2972. if (1 == delimiters.size())
  2973. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  2974. str.data(), str.data() + str.size(),
  2975. std::back_inserter(sequence),
  2976. split_option);
  2977. else
  2978. return split(multiple_char_delimiter_predicate(delimiters),
  2979. str.data(), str.data() + str.size(),
  2980. std::back_inserter(sequence),
  2981. split_option);
  2982. }
  2983. template <typename DelimiterPredicate,
  2984. typename OutputIterator>
  2985. inline std::size_t split(const DelimiterPredicate& delimiter,
  2986. const std::string& str,
  2987. OutputIterator out,
  2988. const split_options::type& split_option = split_options::default_mode)
  2989. {
  2990. return split(delimiter,
  2991. str.data(), str.data() + str.size(),
  2992. out,
  2993. split_option);
  2994. }
  2995. template <typename DelimiterPredicate,
  2996. typename Iterator,
  2997. typename OutputIterator>
  2998. inline std::size_t split_n(const DelimiterPredicate& delimiter,
  2999. const Iterator begin,
  3000. const Iterator end,
  3001. const std::size_t& token_count,
  3002. OutputIterator out,
  3003. const split_options::type& split_option = split_options::default_mode)
  3004. {
  3005. if (0 == token_count) return 0;
  3006. if (begin == end) return 0;
  3007. std::size_t match_count = 0;
  3008. std::pair<Iterator,Iterator> range(begin,begin);
  3009. const bool compress_delimiters = split_options::perform_compress_delimiters(split_option);
  3010. const bool include_1st_delimiter = split_options::perform_include_1st_delimiter(split_option);
  3011. const bool include_all_delimiters = (!include_1st_delimiter) && split_options::perform_include_all_delimiters(split_option);
  3012. const bool include_delimiters = include_1st_delimiter || include_all_delimiters;
  3013. while (end != range.second)
  3014. {
  3015. if (delimiter(*range.second))
  3016. {
  3017. if (include_delimiters)
  3018. {
  3019. ++range.second;
  3020. (*out) = range;
  3021. ++out;
  3022. if (++match_count >= token_count)
  3023. return match_count;
  3024. if (compress_delimiters)
  3025. while ((end != range.second) && delimiter(*range.second)) ++range.second;
  3026. }
  3027. else
  3028. {
  3029. (*out) = range;
  3030. ++out;
  3031. if (++match_count >= token_count)
  3032. return match_count;
  3033. if (compress_delimiters)
  3034. while ((end != (++range.second)) && delimiter(*range.second)) ;
  3035. else
  3036. ++range.second;
  3037. }
  3038. range.first = range.second;
  3039. }
  3040. else
  3041. ++range.second;
  3042. }
  3043. if ((range.first != range.second) || delimiter(*(range.second - 1)))
  3044. {
  3045. (*out) = range;
  3046. ++out;
  3047. ++match_count;
  3048. }
  3049. return match_count;
  3050. }
  3051. template <typename OutputIterator>
  3052. inline std::size_t split_n(const char* delimiters,
  3053. const std::string& str,
  3054. const std::size_t& token_count,
  3055. OutputIterator out,
  3056. const split_options::type& split_option = split_options::default_mode)
  3057. {
  3058. return split_n(multiple_char_delimiter_predicate(delimiters),
  3059. str.data(), str.data() + str.size(),
  3060. token_count,
  3061. out,
  3062. split_option);
  3063. }
  3064. template <typename OutputIterator>
  3065. inline std::size_t split_n(const std::string& delimiters,
  3066. const std::string& str,
  3067. const std::size_t& token_count,
  3068. OutputIterator out,
  3069. const split_options::type& split_option = split_options::default_mode)
  3070. {
  3071. if (1 == delimiters.size())
  3072. return split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  3073. str.data(), str.data() + str.size(),
  3074. token_count,
  3075. out,
  3076. split_option);
  3077. else
  3078. return split_n(multiple_char_delimiter_predicate(delimiters),
  3079. str.data(), str.data() + str.size(),
  3080. token_count,
  3081. out,
  3082. split_option);
  3083. }
  3084. template <typename InputIterator, typename OutputIterator>
  3085. inline std::size_t split_n(const std::string& delimiters,
  3086. const InputIterator begin,
  3087. const InputIterator end,
  3088. const std::size_t& token_count,
  3089. OutputIterator out,
  3090. const split_options::type& split_option = split_options::default_mode)
  3091. {
  3092. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  3093. details::convert_type_assert<itr_type>();
  3094. if (1 == delimiters.size())
  3095. return split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  3096. begin,end,
  3097. token_count,
  3098. out,
  3099. split_option);
  3100. else
  3101. return split_n(multiple_char_delimiter_predicate(delimiters),
  3102. begin,end,
  3103. token_count,
  3104. out,
  3105. split_option);
  3106. }
  3107. template <typename OutputIterator>
  3108. inline std::size_t split_n(const std::string::value_type delimiter,
  3109. const std::string& str,
  3110. const std::size_t& token_count,
  3111. OutputIterator out,
  3112. const split_options::type& split_option = split_options::default_mode)
  3113. {
  3114. return split_n(single_delimiter_predicate<std::string::value_type>(delimiter),
  3115. str.data(),str.data() + str.size(),
  3116. token_count,
  3117. out,
  3118. split_option);
  3119. }
  3120. template <typename DelimiterPredicate,
  3121. typename OutputIterator>
  3122. inline std::size_t split_n(const DelimiterPredicate& delimiter,
  3123. const std::string& str,
  3124. const std::size_t& token_count,
  3125. OutputIterator out,
  3126. const split_options::type& split_option = split_options::default_mode)
  3127. {
  3128. return split_n(delimiter,
  3129. str.data(),str.data() + str.size(),
  3130. token_count,
  3131. out,
  3132. split_option);
  3133. }
  3134. #ifdef strtk_enable_regex
  3135. static const std::string uri_expression ("((https?|ftp)\\://((\\[?(\\d{1,3}\\.){3}\\d{1,3}\\]?)|(([-a-zA-Z0-9]+\\.)+[a-zA-Z]{2,4}))(\\:\\d+)?(/[-a-zA-Z0-9._?,+&amp;%$#=~\\\\]+)*/?)");
  3136. static const std::string email_expression ("([\\w\\-\\.]+)@((\\[([0-9]{1,3}\\.){3}[0-9]{1,3}\\])|(([\\w\\-]+\\.)+)([a-zA-Z]{2,4}))");
  3137. static const std::string ip_expression ("(([0-2]*[0-9]+[0-9]+)\\.([0-2]*[0-9]+[0-9]+)\\.([0-2]*[0-9]+[0-9]+)\\.([0-2]*[0-9]+[0-9]+))");
  3138. static const std::string ieee754_expression ("([-+]?((\\.[0-9]+|[0-9]+\\.[0-9]+)([eE][-+][0-9]+)?|[0-9]+))");
  3139. namespace regex_match_mode
  3140. {
  3141. enum type
  3142. {
  3143. match_all = 0,
  3144. match_1 = 1,
  3145. match_2 = 2,
  3146. match_3 = 3,
  3147. match_4 = 4,
  3148. match_5 = 5,
  3149. match_6 = 6,
  3150. match_7 = 7,
  3151. match_8 = 8,
  3152. match_9 = 9
  3153. };
  3154. }
  3155. template <typename InputIterator, typename OutputIterator>
  3156. inline std::size_t split_regex(const boost::regex& delimiter_expression,
  3157. const InputIterator begin,
  3158. const InputIterator end,
  3159. OutputIterator out,
  3160. const regex_match_mode::type mode = regex_match_mode::match_all)
  3161. {
  3162. boost::regex_iterator<InputIterator> itr(begin,end,delimiter_expression);
  3163. boost::regex_iterator<InputIterator> itr_end;
  3164. std::pair<InputIterator,InputIterator> range(begin,begin);
  3165. std::size_t match_count = 0;
  3166. while (itr_end != itr)
  3167. {
  3168. range.first = (*itr)[mode].first;
  3169. range.second = (*itr)[mode].second;
  3170. (*out) = range;
  3171. ++out;
  3172. ++itr;
  3173. ++match_count;
  3174. }
  3175. return match_count;
  3176. }
  3177. template <typename InputIterator, typename OutputIterator>
  3178. inline std::size_t split_regex(const std::string& delimiter_expression,
  3179. const InputIterator begin,
  3180. const InputIterator end,
  3181. OutputIterator out,
  3182. const regex_match_mode::type mode = regex_match_mode::match_all)
  3183. {
  3184. const boost::regex regex_expression(delimiter_expression);
  3185. return split_regex(regex_expression,
  3186. begin,end,
  3187. out,
  3188. mode);
  3189. }
  3190. template <typename OutputIterator>
  3191. inline std::size_t split_regex(const std::string& delimiter_expression,
  3192. const std::string& text,
  3193. OutputIterator out,
  3194. const regex_match_mode::type mode = regex_match_mode::match_all)
  3195. {
  3196. return split_regex(delimiter_expression,
  3197. text.begin(),text.end(),
  3198. out,
  3199. mode);
  3200. }
  3201. template <typename OutputIterator>
  3202. inline std::size_t split_regex(const boost::regex& delimiter_expression,
  3203. const std::string& text,
  3204. OutputIterator out,
  3205. const regex_match_mode::type mode = regex_match_mode::match_all)
  3206. {
  3207. return split_regex(delimiter_expression,
  3208. text.begin(),text.end(),
  3209. out,
  3210. mode);
  3211. }
  3212. template <typename InputIterator, typename OutputIterator>
  3213. inline std::size_t split_regex_n(const boost::regex& delimiter_expression,
  3214. const InputIterator begin,
  3215. const InputIterator end,
  3216. const std::size_t& token_count,
  3217. OutputIterator out,
  3218. const regex_match_mode::type mode = regex_match_mode::match_all)
  3219. {
  3220. boost::sregex_iterator itr(begin,end,delimiter_expression);
  3221. const boost::sregex_iterator itr_end;
  3222. std::pair<InputIterator,InputIterator> range(begin,begin);
  3223. std::size_t match_count = 0;
  3224. while (itr_end != itr)
  3225. {
  3226. range.first = (*itr)[mode].first;
  3227. range.second = (*itr)[mode].second;
  3228. (*out) = range;
  3229. ++out;
  3230. ++itr;
  3231. if (++match_count >= token_count)
  3232. return match_count;
  3233. }
  3234. return match_count;
  3235. }
  3236. template <typename InputIterator, typename OutputIterator>
  3237. inline std::size_t split_regex_n(const std::string& delimiter_expression,
  3238. const InputIterator begin,
  3239. const InputIterator end,
  3240. const std::size_t& token_count,
  3241. OutputIterator out,
  3242. const regex_match_mode::type mode = regex_match_mode::match_all)
  3243. {
  3244. const boost::regex regex_expression(delimiter_expression);
  3245. return split_regex_n(regex_expression,
  3246. begin,end,
  3247. token_count,
  3248. out,
  3249. mode);
  3250. }
  3251. template <typename OutputIterator>
  3252. inline std::size_t split_regex_n(const std::string& delimiter_expression,
  3253. const std::string& text,
  3254. const std::size_t& token_count,
  3255. OutputIterator out,
  3256. const regex_match_mode::type mode = regex_match_mode::match_all)
  3257. {
  3258. return split_regex_n(delimiter_expression,
  3259. text.begin(),text.end(),
  3260. token_count,
  3261. out,
  3262. mode);
  3263. }
  3264. template <typename OutputIterator>
  3265. inline std::size_t split_regex_n(const boost::regex& delimiter_expression,
  3266. const std::string& text,
  3267. const std::size_t& token_count,
  3268. OutputIterator out,
  3269. const regex_match_mode::type mode = regex_match_mode::match_all)
  3270. {
  3271. return split_regex_n(delimiter_expression,
  3272. text.begin(),text.end(),
  3273. token_count,
  3274. out,
  3275. mode);
  3276. }
  3277. #endif // strtk_enable_regex
  3278. template <const std::size_t offset_list_size>
  3279. class offset_predicate
  3280. {
  3281. public:
  3282. offset_predicate(const int offset_list[], const bool rotate = false)
  3283. : rotate_(rotate),
  3284. current_index_(0)
  3285. {
  3286. std::copy(offset_list, offset_list + offset_list_size, offset_list_);
  3287. offset_list_[offset_list_size] = 0;
  3288. }
  3289. inline bool operator!() const
  3290. {
  3291. return (0 == offset_list_size);
  3292. }
  3293. inline void reset() const
  3294. {
  3295. current_index_ = 0;
  3296. }
  3297. inline std::size_t size() const
  3298. {
  3299. return offset_list_size;
  3300. }
  3301. inline int next() const
  3302. {
  3303. int result = offset_list_[current_index_++];
  3304. if (rotate_ && (current_index_ >= offset_list_size))
  3305. {
  3306. current_index_ = 0;
  3307. }
  3308. return result;
  3309. }
  3310. private:
  3311. bool rotate_;
  3312. mutable std::size_t current_index_;
  3313. int offset_list_[offset_list_size + 1];
  3314. };
  3315. inline offset_predicate<12> offsets(const int& v1, const int& v2, const int& v3,
  3316. const int& v4, const int& v5, const int& v6,
  3317. const int& v7, const int& v8, const int& v9,
  3318. const int& v10, const int& v11, const int& v12,
  3319. const bool& rotate = false)
  3320. {
  3321. const int offset_list[12] = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 };
  3322. return offset_predicate<12>(offset_list,rotate);
  3323. }
  3324. inline offset_predicate<11> offsets(const int& v1, const int& v2, const int& v3,
  3325. const int& v4, const int& v5, const int& v6,
  3326. const int& v7, const int& v8, const int& v9,
  3327. const int& v10, const int& v11,
  3328. const bool& rotate = false)
  3329. {
  3330. const int offset_list[11] = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 };
  3331. return offset_predicate<11>(offset_list,rotate);
  3332. }
  3333. inline offset_predicate<10> offsets(const int& v1, const int& v2, const int& v3,
  3334. const int& v4, const int& v5, const int& v6,
  3335. const int& v7, const int& v8, const int& v9,
  3336. const int& v10, const bool& rotate = false)
  3337. {
  3338. const int offset_list[10] = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 };
  3339. return offset_predicate<10>(offset_list,rotate);
  3340. }
  3341. inline offset_predicate<9> offsets(const int& v1, const int& v2, const int& v3,
  3342. const int& v4, const int& v5, const int& v6,
  3343. const int& v7, const int& v8, const int& v9,
  3344. const bool& rotate = false)
  3345. {
  3346. const int offset_list[9] = { v1, v2, v3, v4, v5, v6, v7, v8, v9 };
  3347. return offset_predicate<9>(offset_list,rotate);
  3348. }
  3349. inline offset_predicate<8> offsets(const int& v1, const int& v2, const int& v3,
  3350. const int& v4, const int& v5, const int& v6,
  3351. const int& v7, const int& v8, const bool& rotate = false)
  3352. {
  3353. const int offset_list[8] = { v1, v2, v3, v4, v5, v6, v7, v8 };
  3354. return offset_predicate<8>(offset_list,rotate);
  3355. }
  3356. inline offset_predicate<7> offsets(const int& v1, const int& v2, const int& v3,
  3357. const int& v4, const int& v5, const int& v6,
  3358. const int& v7, const bool& rotate = false)
  3359. {
  3360. const int offset_list[7] = { v1, v2, v3, v4, v5, v6, v7 };
  3361. return offset_predicate<7>(offset_list,rotate);
  3362. }
  3363. inline offset_predicate<6> offsets(const int& v1, const int& v2, const int& v3,
  3364. const int& v4, const int& v5, const int& v6,
  3365. const bool& rotate = false)
  3366. {
  3367. const int offset_list[6] = { v1, v2, v3, v4, v5, v6 };
  3368. return offset_predicate<6>(offset_list,rotate);
  3369. }
  3370. inline offset_predicate<5> offsets(const int& v1, const int& v2, const int& v3,
  3371. const int& v4, const int& v5, const bool& rotate = false)
  3372. {
  3373. const int offset_list[5] = { v1, v2, v3, v4, v5 };
  3374. return offset_predicate<5>(offset_list,rotate);
  3375. }
  3376. inline offset_predicate<4> offsets(const int& v1, const int& v2, const int& v3,
  3377. const int& v4, const bool& rotate = false)
  3378. {
  3379. const int offset_list[4] = { v1, v2, v3, v4 };
  3380. return offset_predicate<4>(offset_list,rotate);
  3381. }
  3382. inline offset_predicate<3> offsets(const int& v1, const int& v2, const int& v3,
  3383. const bool& rotate = false)
  3384. {
  3385. const int offset_list[3] = { v1, v2, v3 };
  3386. return offset_predicate<3>(offset_list,rotate);
  3387. }
  3388. inline offset_predicate<2> offsets(const int& v1, const int& v2, const bool& rotate = false)
  3389. {
  3390. const int offset_list[2] = { v1, v2 };
  3391. return offset_predicate<2>(offset_list,rotate);
  3392. }
  3393. inline offset_predicate<1> offsets(const int& v1,
  3394. const bool& rotate = false)
  3395. {
  3396. const int offset_list[1] = { v1 };
  3397. return offset_predicate<1>(offset_list,rotate);
  3398. }
  3399. template <typename OffsetPredicate,
  3400. typename InputIterator,
  3401. typename OutputIterator>
  3402. inline std::size_t offset_splitter(const InputIterator begin,
  3403. const InputIterator end,
  3404. const OffsetPredicate& offset,
  3405. OutputIterator out)
  3406. {
  3407. std::size_t length = 0;
  3408. if (0 == (length = std::distance(begin,end))) return 0;
  3409. std::pair<InputIterator,InputIterator> range(begin,begin);
  3410. std::size_t match_count = 0;
  3411. int offset_length = 0;
  3412. std::size_t increment_amount = 0;
  3413. while ((end != range.second) && (0 < (offset_length = offset.next())))
  3414. {
  3415. increment_amount = std::min<std::size_t>(length,offset_length);
  3416. range.first = range.second;
  3417. range.second += increment_amount;
  3418. length -= increment_amount;
  3419. (*out) = range;
  3420. ++out;
  3421. ++match_count;
  3422. }
  3423. return match_count;
  3424. }
  3425. template <typename OffsetPredicate,
  3426. typename OutputIterator>
  3427. inline std::size_t offset_splitter(const std::string& str,
  3428. const OffsetPredicate& offset,
  3429. OutputIterator out)
  3430. {
  3431. return offset_splitter(str.data(),str.data() + str.size(),offset,out);
  3432. }
  3433. template <typename InputIterator,
  3434. typename Predicate,
  3435. typename OutputPair>
  3436. inline bool split_pair(const InputIterator begin,
  3437. const InputIterator end,
  3438. const Predicate& delimiter,
  3439. OutputPair& v1,
  3440. OutputPair& v2)
  3441. {
  3442. if (0 == std::distance(begin,end)) return false;
  3443. InputIterator itr = begin;
  3444. while (end != itr)
  3445. {
  3446. if (delimiter(*itr))
  3447. {
  3448. v1 = std::make_pair(begin,itr);
  3449. ++itr;
  3450. if (0 != std::distance(itr,end))
  3451. {
  3452. v2 = std::make_pair(itr,end);
  3453. return true;
  3454. }
  3455. else
  3456. return false;
  3457. }
  3458. else
  3459. ++itr;
  3460. }
  3461. return false;
  3462. }
  3463. inline bool split_pair(const std::string::value_type delimiter,
  3464. const std::string& str,
  3465. std::pair<const char*,const char*>& v1,
  3466. std::pair<const char*,const char*>& v2)
  3467. {
  3468. return split_pair(str.data(),
  3469. str.data() + str.size(),
  3470. single_delimiter_predicate<std::string::value_type>(delimiter),
  3471. v1,
  3472. v2);
  3473. }
  3474. template <typename DelimiterPredicate>
  3475. inline bool split_pair(const DelimiterPredicate& delimiter,
  3476. const std::string& str,
  3477. std::pair<const char*,const char*>& v1,
  3478. std::pair<const char*,const char*>& v2)
  3479. {
  3480. return split_pair(str.data(),
  3481. str.data() + str.size(),
  3482. delimiter,
  3483. v1,
  3484. v2);
  3485. }
  3486. template <typename Function>
  3487. inline std::size_t for_each_token(const std::string& buffer,
  3488. const std::string& delimiters,
  3489. Function function)
  3490. {
  3491. return split(delimiters,
  3492. buffer,
  3493. strtk::functional_inserter<Function>(function));
  3494. }
  3495. template <typename Function>
  3496. inline std::size_t for_each_token(const std::string& buffer,
  3497. const char* delimiters,
  3498. Function function)
  3499. {
  3500. return split(delimiters,
  3501. buffer,
  3502. strtk::functional_inserter<Function>(function));
  3503. }
  3504. template <typename InputIterator>
  3505. inline std::size_t count_consecutive_duplicates(const InputIterator begin, const InputIterator end)
  3506. {
  3507. if (std::distance(begin,end) < 2) return 0;
  3508. InputIterator prev = begin;
  3509. InputIterator itr = begin;
  3510. std::size_t count = 0;
  3511. while (end != ++itr)
  3512. {
  3513. if ((*prev) == (*itr))
  3514. ++count;
  3515. else
  3516. prev = itr;
  3517. }
  3518. return count;
  3519. }
  3520. template <typename T,
  3521. typename Allocator,
  3522. template <typename,typename> class Sequence>
  3523. inline T min_of_cont(const Sequence<T,Allocator>& sequence)
  3524. {
  3525. return (*std::min_element(sequence.begin(),sequence.end()));
  3526. }
  3527. template <typename T,
  3528. typename Comparator,
  3529. typename Allocator>
  3530. inline T min_of_cont(const std::set<T,Comparator,Allocator>& set)
  3531. {
  3532. return (*set.begin());
  3533. }
  3534. template <typename T,
  3535. typename Comparator,
  3536. typename Allocator>
  3537. inline T min_of_cont(const std::multiset<T,Comparator,Allocator>& multiset)
  3538. {
  3539. return (*multiset.begin());
  3540. }
  3541. template <typename T,
  3542. typename Allocator,
  3543. template <typename,typename> class Sequence>
  3544. inline T max_of_cont(const Sequence<T,Allocator>& sequence)
  3545. {
  3546. return (*std::max_element(sequence.begin(),sequence.end()));
  3547. }
  3548. template <typename T,
  3549. typename Comparator,
  3550. typename Allocator>
  3551. inline T max_of_cont(const std::set<T,Comparator,Allocator>& set)
  3552. {
  3553. return (*set.rbegin());
  3554. }
  3555. template <typename T,
  3556. typename Comparator,
  3557. typename Allocator>
  3558. inline T max_of_cont(const std::multiset<T,Comparator,Allocator>& multiset)
  3559. {
  3560. return (*multiset.rbegin());
  3561. }
  3562. template <typename InputIterator>
  3563. inline void min_max_of_range(const InputIterator begin, const InputIterator end,
  3564. typename std::iterator_traits<InputIterator>::value_type& min_value,
  3565. typename std::iterator_traits<InputIterator>::value_type& max_value)
  3566. {
  3567. min_value = *begin;
  3568. max_value = *begin;
  3569. InputIterator itr = begin;
  3570. while (end != ++itr)
  3571. {
  3572. if (*itr < min_value)
  3573. min_value = (*itr);
  3574. else if (*itr > max_value)
  3575. max_value = (*itr);
  3576. }
  3577. }
  3578. template <typename T,
  3579. typename Allocator,
  3580. template <typename,typename> class Sequence>
  3581. inline void min_max_of_cont(const Sequence<T,Allocator>& sequence,
  3582. T& min_value,
  3583. T& max_value)
  3584. {
  3585. min_max_of_range(sequence.begin(),sequence.end(),
  3586. min_value,
  3587. max_value);
  3588. }
  3589. template <typename T,
  3590. typename Comparator,
  3591. typename Allocator>
  3592. inline void min_max_of_cont(const std::set<T,Comparator,Allocator>& set,
  3593. T& min_value,
  3594. T& max_value)
  3595. {
  3596. min_value = (*set.begin());
  3597. max_value = (*set.rbegin());
  3598. }
  3599. template <typename T,
  3600. typename Comparator,
  3601. typename Allocator>
  3602. inline void min_max_of_cont(const std::multiset<T,Comparator,Allocator>& multiset,
  3603. T& min_value,
  3604. T& max_value)
  3605. {
  3606. min_value = (*multiset.begin());
  3607. max_value = (*multiset.rbegin());
  3608. }
  3609. template <typename Iterator>
  3610. inline void lexicographically_canonicalize(Iterator begin, Iterator end)
  3611. {
  3612. typedef typename std::iterator_traits<Iterator>::value_type type;
  3613. typedef typename std::pair<Iterator,Iterator> iter_type;
  3614. typedef typename std::list<iter_type> itr_list_type;
  3615. itr_list_type itr_list;
  3616. type smallest = (*std::min_element(begin,end));
  3617. for (Iterator itr = begin; itr != end; ++itr)
  3618. {
  3619. if (*itr == smallest) itr_list.push_back(std::make_pair(itr,itr));
  3620. }
  3621. while (itr_list.size() > 1)
  3622. {
  3623. typename itr_list_type::iterator itr = itr_list.begin();
  3624. while (itr_list.end() != itr)
  3625. {
  3626. ++(*itr).first;
  3627. if (end == (*itr).first)
  3628. itr = itr_list.erase(itr);
  3629. else
  3630. ++itr;
  3631. }
  3632. smallest = *(*itr_list.begin()).first;
  3633. for (itr = (++itr_list.begin()); itr != itr_list.end(); ++itr)
  3634. {
  3635. if (*(*itr).first < smallest)
  3636. {
  3637. smallest = *(*itr).first;
  3638. }
  3639. }
  3640. itr = itr_list.begin();
  3641. while (itr_list.end() != itr)
  3642. {
  3643. if (*(*itr).first != smallest)
  3644. itr = itr_list.erase(itr);
  3645. else
  3646. ++itr;
  3647. }
  3648. itr = itr_list.begin();
  3649. while (itr_list.end() != itr)
  3650. {
  3651. if (end == (*itr).first)
  3652. itr = itr_list.erase(itr);
  3653. else
  3654. ++itr;
  3655. }
  3656. }
  3657. std::rotate(begin,(*itr_list.begin()).second,end);
  3658. }
  3659. inline void lexicographically_canonicalize(std::string& str)
  3660. {
  3661. lexicographically_canonicalize(const_cast<char*>(str.data()),
  3662. const_cast<char*>(str.data() + str.size()));
  3663. }
  3664. template <typename T,
  3665. typename Allocator,
  3666. template <typename,typename> class Sequence>
  3667. inline void lexicographically_canonicalize(Sequence<T,Allocator>& sequence)
  3668. {
  3669. lexicographically_canonicalize(sequence.begin(),sequence.end());
  3670. }
  3671. inline const char* first_non_repeated_char(const char* begin, const char* end)
  3672. {
  3673. static const std::size_t lut_size = 256;
  3674. unsigned long long int lut[lut_size];
  3675. std::fill_n(lut,lut_size,std::numeric_limits<unsigned long long int>::max());
  3676. static const unsigned long long int not_yet_encountered = std::numeric_limits<unsigned long long int>::max();
  3677. static const unsigned long long int repeated = not_yet_encountered - 1;
  3678. const char* itr = begin;
  3679. unsigned long long int position = 0;
  3680. while (end != itr)
  3681. {
  3682. unsigned long long int& element = lut[static_cast<unsigned int>(*itr)];
  3683. if (not_yet_encountered == element)
  3684. {
  3685. element = position;
  3686. }
  3687. else if (element < repeated)
  3688. {
  3689. element = repeated;
  3690. }
  3691. ++itr;
  3692. ++position;
  3693. }
  3694. position = repeated;
  3695. for (std::size_t i = 0; i < lut_size; ++i)
  3696. {
  3697. if (lut[i] < position)
  3698. position = lut[i];
  3699. }
  3700. return (repeated != position) ? (begin + position) : end;
  3701. }
  3702. inline const unsigned char* first_non_repeated_char(const unsigned char* begin, const unsigned char* end)
  3703. {
  3704. char * b = reinterpret_cast<char*>(const_cast<unsigned char*>(begin));
  3705. char * e = reinterpret_cast<char*>(const_cast<unsigned char*>(end));
  3706. return const_cast<const unsigned char*>(reinterpret_cast<unsigned char*>(const_cast<char*>(first_non_repeated_char(b,e))));
  3707. }
  3708. inline std::size_t first_non_repeated_char(const std::string& str)
  3709. {
  3710. if (str.empty())
  3711. return static_cast<std::size_t>(std::string::npos);
  3712. const char* itr = first_non_repeated_char(str.data(),str.data() + str.size());
  3713. if ((str.data() + str.size()) != itr)
  3714. return static_cast<std::size_t>(itr - str.data());
  3715. else
  3716. return static_cast<std::size_t>(std::string::npos);
  3717. }
  3718. inline void convert_bin_to_hex(const unsigned char* begin, const unsigned char* end, unsigned char* out)
  3719. {
  3720. static const unsigned short hex_lut[] =
  3721. {
  3722. 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730,
  3723. 0x3830, 0x3930, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530, 0x4630,
  3724. 0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731,
  3725. 0x3831, 0x3931, 0x4131, 0x4231, 0x4331, 0x4431, 0x4531, 0x4631,
  3726. 0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732,
  3727. 0x3832, 0x3932, 0x4132, 0x4232, 0x4332, 0x4432, 0x4532, 0x4632,
  3728. 0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733,
  3729. 0x3833, 0x3933, 0x4133, 0x4233, 0x4333, 0x4433, 0x4533, 0x4633,
  3730. 0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734,
  3731. 0x3834, 0x3934, 0x4134, 0x4234, 0x4334, 0x4434, 0x4534, 0x4634,
  3732. 0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735,
  3733. 0x3835, 0x3935, 0x4135, 0x4235, 0x4335, 0x4435, 0x4535, 0x4635,
  3734. 0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736,
  3735. 0x3836, 0x3936, 0x4136, 0x4236, 0x4336, 0x4436, 0x4536, 0x4636,
  3736. 0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737,
  3737. 0x3837, 0x3937, 0x4137, 0x4237, 0x4337, 0x4437, 0x4537, 0x4637,
  3738. 0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738,
  3739. 0x3838, 0x3938, 0x4138, 0x4238, 0x4338, 0x4438, 0x4538, 0x4638,
  3740. 0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739,
  3741. 0x3839, 0x3939, 0x4139, 0x4239, 0x4339, 0x4439, 0x4539, 0x4639,
  3742. 0x3041, 0x3141, 0x3241, 0x3341, 0x3441, 0x3541, 0x3641, 0x3741,
  3743. 0x3841, 0x3941, 0x4141, 0x4241, 0x4341, 0x4441, 0x4541, 0x4641,
  3744. 0x3042, 0x3142, 0x3242, 0x3342, 0x3442, 0x3542, 0x3642, 0x3742,
  3745. 0x3842, 0x3942, 0x4142, 0x4242, 0x4342, 0x4442, 0x4542, 0x4642,
  3746. 0x3043, 0x3143, 0x3243, 0x3343, 0x3443, 0x3543, 0x3643, 0x3743,
  3747. 0x3843, 0x3943, 0x4143, 0x4243, 0x4343, 0x4443, 0x4543, 0x4643,
  3748. 0x3044, 0x3144, 0x3244, 0x3344, 0x3444, 0x3544, 0x3644, 0x3744,
  3749. 0x3844, 0x3944, 0x4144, 0x4244, 0x4344, 0x4444, 0x4544, 0x4644,
  3750. 0x3045, 0x3145, 0x3245, 0x3345, 0x3445, 0x3545, 0x3645, 0x3745,
  3751. 0x3845, 0x3945, 0x4145, 0x4245, 0x4345, 0x4445, 0x4545, 0x4645,
  3752. 0x3046, 0x3146, 0x3246, 0x3346, 0x3446, 0x3546, 0x3646, 0x3746,
  3753. 0x3846, 0x3946, 0x4146, 0x4246, 0x4346, 0x4446, 0x4546, 0x4646
  3754. };
  3755. for (const unsigned char* itr = begin; end != itr; ++itr)
  3756. {
  3757. *reinterpret_cast<unsigned short*>(out) = hex_lut[(*itr)];
  3758. out += sizeof(unsigned short);
  3759. }
  3760. }
  3761. inline void convert_bin_to_hex(const char* begin, const char* end, char* out)
  3762. {
  3763. convert_bin_to_hex(reinterpret_cast<const unsigned char*>(begin),
  3764. reinterpret_cast<const unsigned char*>(end),
  3765. reinterpret_cast<unsigned char*>(out));
  3766. }
  3767. inline void convert_bin_to_hex(const std::pair<unsigned char*,unsigned char*>& r, unsigned char* out)
  3768. {
  3769. convert_bin_to_hex(r.first,r.second,out);
  3770. }
  3771. inline void convert_bin_to_hex(const std::pair<const unsigned char*,const unsigned char*>& r, unsigned char* out)
  3772. {
  3773. convert_bin_to_hex(r.first,r.second,out);
  3774. }
  3775. inline void convert_bin_to_hex(const std::pair<const char*,const char*>& r, char* out)
  3776. {
  3777. convert_bin_to_hex(r.first,r.second,out);
  3778. }
  3779. inline void convert_bin_to_hex(const std::string& binary_data, std::string& output)
  3780. {
  3781. output.resize(binary_data.size() * 2);
  3782. convert_bin_to_hex(binary_data.data(),
  3783. binary_data.data() + binary_data.size(),
  3784. const_cast<char*>(output.data()));
  3785. }
  3786. inline std::string convert_bin_to_hex(const std::string& binary_data)
  3787. {
  3788. std::string output;
  3789. convert_bin_to_hex(binary_data,output);
  3790. return output;
  3791. }
  3792. inline bool convert_hex_to_bin(const unsigned char* begin, const unsigned char* end, unsigned char* out)
  3793. {
  3794. const std::size_t length = std::distance(begin,end);
  3795. if (0 == length)
  3796. return false;
  3797. else if (1 == (length % 2))
  3798. return false;
  3799. static const unsigned char hex_to_bin[] =
  3800. {
  3801. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 - 0x07
  3802. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 - 0x0F
  3803. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 - 0x17
  3804. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 - 0x1F
  3805. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 - 0x27
  3806. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 - 0x2F
  3807. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 0x30 - 0x37
  3808. 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 - 0x3F
  3809. 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, // 0x40 - 0x47
  3810. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 - 0x4F
  3811. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 - 0x57
  3812. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 - 0x5F
  3813. 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, // 0x60 - 0x67
  3814. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 - 0x6F
  3815. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 - 0x77
  3816. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 - 0x7F
  3817. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 - 0x87
  3818. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 - 0x8F
  3819. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 - 0x97
  3820. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 - 0x9F
  3821. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 - 0xA7
  3822. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 - 0xAF
  3823. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 - 0xB7
  3824. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 - 0xBF
  3825. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 - 0xC7
  3826. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 - 0xCF
  3827. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 - 0xD7
  3828. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 - 0xDF
  3829. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 - 0xE7
  3830. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 - 0xEF
  3831. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 - 0xF7
  3832. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 0xF8 - 0xFF
  3833. };
  3834. const unsigned char* itr = begin;
  3835. while (end != itr)
  3836. {
  3837. *reinterpret_cast<unsigned char*>(out) = static_cast<unsigned char>(hex_to_bin[itr[0]] << 4 | hex_to_bin[itr[1]]);
  3838. ++out;
  3839. itr += 2;
  3840. }
  3841. return true;
  3842. }
  3843. inline bool convert_hex_to_bin(const char* begin, const char* end, char* out)
  3844. {
  3845. return convert_hex_to_bin(reinterpret_cast<const unsigned char*>(begin),
  3846. reinterpret_cast<const unsigned char*>(end),
  3847. reinterpret_cast<unsigned char*>(out));
  3848. }
  3849. inline bool convert_hex_to_bin(const std::pair<unsigned char*,unsigned char*>& r, unsigned char* out)
  3850. {
  3851. return convert_hex_to_bin(r.first,r.second,out);
  3852. }
  3853. inline bool convert_hex_to_bin(const std::pair<const unsigned char*,const unsigned char*>& r, unsigned char* out)
  3854. {
  3855. return convert_hex_to_bin(r.first,r.second,out);
  3856. }
  3857. inline bool convert_hex_to_bin(const std::pair<char*,char*>& r, char* out)
  3858. {
  3859. return convert_hex_to_bin(r.first,r.second,out);
  3860. }
  3861. inline bool convert_hex_to_bin(const std::pair<const char*,const char*>& r, char* out)
  3862. {
  3863. return convert_hex_to_bin(r.first,r.second,out);
  3864. }
  3865. inline bool convert_hex_to_bin(const std::string& hex_data, std::string& output)
  3866. {
  3867. if (hex_data.empty() || (1 == (hex_data.size() % 2)))
  3868. return false;
  3869. output.resize(hex_data.size() >> 1);
  3870. return convert_hex_to_bin(hex_data.data(),
  3871. hex_data.data() + hex_data.size(),
  3872. const_cast<char*>(output.data()));
  3873. }
  3874. inline std::size_t convert_bin_to_base64(const unsigned char* begin, const unsigned char* end, unsigned char* out)
  3875. {
  3876. static const unsigned char bin_to_base64 [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  3877. const std::size_t length = std::distance(begin,end);
  3878. std::size_t rounds = length / 3;
  3879. const unsigned char* itr = begin;
  3880. for (std::size_t i = 0; i < rounds; ++i)
  3881. {
  3882. unsigned int block = *(itr++) << 16;
  3883. block |= *(itr++) << 8;
  3884. block |= *(itr++) ;
  3885. *(out++) = bin_to_base64[( block >> 18 ) & 0x3F];
  3886. *(out++) = bin_to_base64[( block >> 12 ) & 0x3F];
  3887. *(out++) = bin_to_base64[( block >> 6 ) & 0x3F];
  3888. *(out++) = bin_to_base64[( block ) & 0x3F];
  3889. }
  3890. if ((rounds = (length % 3)) > 0)
  3891. {
  3892. switch (rounds)
  3893. {
  3894. case 1 : {
  3895. unsigned int block = (unsigned char) (*itr) << 16;
  3896. *(out++) = bin_to_base64[( block >> 18 ) & 0x3F];
  3897. *(out++) = bin_to_base64[( block >> 12 ) & 0x3F];
  3898. *(out++) = '=';
  3899. *(out++) = '=';
  3900. }
  3901. break;
  3902. case 2 : {
  3903. unsigned int block = *(itr++) << 16;
  3904. block |= *(itr++) << 8;
  3905. *(out++) = bin_to_base64[( block >> 18 ) & 0x3F];
  3906. *(out++) = bin_to_base64[( block >> 12 ) & 0x3F];
  3907. *(out++) = bin_to_base64[( block >> 6 ) & 0x3F];
  3908. *(out++) = '=';
  3909. }
  3910. break;
  3911. }
  3912. }
  3913. return static_cast<std::size_t>((length / 3) * 4) + ((length % 3) > 0 ? 4 : 0);
  3914. }
  3915. inline std::size_t convert_bin_to_base64(const char* begin, const char* end, char* out)
  3916. {
  3917. return convert_bin_to_base64(reinterpret_cast<const unsigned char*>(begin),
  3918. reinterpret_cast<const unsigned char*>(end),
  3919. reinterpret_cast<unsigned char*>(out));
  3920. }
  3921. inline void convert_bin_to_base64(const std::string& binary_data, std::string& output)
  3922. {
  3923. output.resize(std::max<std::size_t>(4,binary_data.size() << 1));
  3924. std::size_t resize = convert_bin_to_base64(binary_data.data(),
  3925. binary_data.data() + binary_data.size(),
  3926. const_cast<char*>(output.data()));
  3927. output.resize(resize);
  3928. }
  3929. inline std::size_t convert_base64_to_bin(const unsigned char* begin, const unsigned char* end, unsigned char* out)
  3930. {
  3931. static const unsigned char base64_to_bin[] =
  3932. {
  3933. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x00 - 0x07
  3934. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x08 - 0x0F
  3935. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x10 - 0x17
  3936. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x18 - 0x1F
  3937. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x20 - 0x27
  3938. 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, // 0x28 - 0x2F
  3939. 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 - 0x37
  3940. 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x38 - 0x3F
  3941. 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 - 0x47
  3942. 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 - 0x4F
  3943. 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 - 0x57
  3944. 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x58 - 0x5F
  3945. 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 - 0x67
  3946. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 - 0x6F
  3947. 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 - 0x77
  3948. 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x78 - 0x7F
  3949. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x80 - 0x87
  3950. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x88 - 0x8F
  3951. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x90 - 0x97
  3952. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x98 - 0x9F
  3953. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA0 - 0xA7
  3954. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA8 - 0xAF
  3955. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB0 - 0xB7
  3956. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB8 - 0xBF
  3957. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC0 - 0xC7
  3958. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC8 - 0xCF
  3959. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD0 - 0xD7
  3960. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD8 - 0xDF
  3961. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE0 - 0xE7
  3962. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE8 - 0xEF
  3963. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xF0 - 0xF7
  3964. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 0xF8 - 0xFF
  3965. };
  3966. const unsigned char* end_itr = end;
  3967. if ('=' == *(end - 2))
  3968. end_itr = end - 2;
  3969. else if ('=' == *(end - 1))
  3970. end_itr = end - 1;
  3971. const std::size_t length = std::distance(begin,end_itr);
  3972. const std::size_t rounds = length / 4;
  3973. const unsigned char* itr = begin;
  3974. for (std::size_t i = 0; i < rounds; ++i)
  3975. {
  3976. unsigned int block = base64_to_bin[*(itr++)] << 18;
  3977. block |= base64_to_bin[*(itr++)] << 12;
  3978. block |= base64_to_bin[*(itr++)] << 6;
  3979. block |= base64_to_bin[*(itr++)];
  3980. *(out++) = static_cast<unsigned char>(( block >> 16 ) & 0xFF);
  3981. *(out++) = static_cast<unsigned char>(( block >> 8 ) & 0xFF);
  3982. *(out++) = static_cast<unsigned char>(( block ) & 0xFF);
  3983. }
  3984. const std::size_t remainder = (length % 4);
  3985. if (remainder > 0)
  3986. {
  3987. switch (remainder)
  3988. {
  3989. case 2 : {
  3990. unsigned int block = base64_to_bin[*(itr++)] << 18;
  3991. block |= base64_to_bin[*(itr++)] << 12;
  3992. (*out) = static_cast<unsigned char>(( block >> 16 ) & 0xFF);
  3993. }
  3994. break;
  3995. case 3 : {
  3996. unsigned int block = base64_to_bin[*(itr++)] << 18;
  3997. block |= base64_to_bin[*(itr++)] << 12;
  3998. block |= base64_to_bin[*(itr++)] << 6;
  3999. *(out++) = static_cast<unsigned char>(( block >> 16 ) & 0xFF);
  4000. *(out ) = static_cast<unsigned char>(( block >> 8 ) & 0xFF);
  4001. }
  4002. break;
  4003. }
  4004. }
  4005. return static_cast<std::size_t>((3 * length) / 4);
  4006. }
  4007. inline std::size_t convert_base64_to_bin(const char* begin, const char* end, char* out)
  4008. {
  4009. return convert_base64_to_bin(reinterpret_cast<const unsigned char*>(begin),
  4010. reinterpret_cast<const unsigned char*>(end),
  4011. reinterpret_cast<unsigned char*>(out));
  4012. }
  4013. inline void convert_base64_to_bin(const std::string& binary_data, std::string& output)
  4014. {
  4015. output.resize(binary_data.size());
  4016. std::size_t resize = convert_base64_to_bin(binary_data.data(),
  4017. binary_data.data() + binary_data.size(),
  4018. const_cast<char*>(output.data()));
  4019. output.resize(resize);
  4020. }
  4021. inline void convert_to_printable_chars(unsigned char* begin, unsigned char* end)
  4022. {
  4023. static const unsigned char printable_char_table[] =
  4024. {
  4025. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x00 - 0x07
  4026. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x08 - 0x0F
  4027. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x10 - 0x17
  4028. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x18 - 0x1F
  4029. 0x2E, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, // 0x20 - 0x27
  4030. 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, // 0x28 - 0x2F
  4031. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // 0x30 - 0x37
  4032. 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // 0x38 - 0x3F
  4033. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, // 0x40 - 0x47
  4034. 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, // 0x48 - 0x4F
  4035. 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, // 0x50 - 0x57
  4036. 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, // 0x58 - 0x5F
  4037. 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, // 0x60 - 0x67
  4038. 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, // 0x68 - 0x6F
  4039. 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // 0x70 - 0x77
  4040. 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x2E, // 0x78 - 0x7F
  4041. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x80 - 0x87
  4042. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x88 - 0x8F
  4043. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x90 - 0x97
  4044. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x98 - 0x9F
  4045. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xA0 - 0xA7
  4046. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xA8 - 0xAF
  4047. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xB0 - 0xB7
  4048. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xB8 - 0xBF
  4049. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xC0 - 0xC7
  4050. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xC8 - 0xCF
  4051. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xD0 - 0xD7
  4052. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xD8 - 0xDF
  4053. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xE0 - 0xE7
  4054. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xE8 - 0xEF
  4055. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xF0 - 0xF7
  4056. 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E // 0xF8 - 0xFF
  4057. };
  4058. unsigned char* itr = begin;
  4059. while (end != itr)
  4060. {
  4061. (*itr) = printable_char_table[static_cast<unsigned int>((*itr))];
  4062. ++itr;
  4063. }
  4064. }
  4065. inline void convert_to_printable_chars(char* begin, char* end)
  4066. {
  4067. convert_to_printable_chars(reinterpret_cast<unsigned char*>(begin),
  4068. reinterpret_cast<unsigned char*>(end));
  4069. }
  4070. inline void convert_to_printable_chars(std::string& str)
  4071. {
  4072. convert_to_printable_chars(reinterpret_cast<unsigned char*>(const_cast<char*>(str.data())),
  4073. reinterpret_cast<unsigned char*>(const_cast<char*>(str.data() + str.size())));
  4074. }
  4075. inline void convert_to_uppercase(unsigned char* begin, unsigned char* end)
  4076. {
  4077. std::transform(begin,end,begin,::toupper);
  4078. /*
  4079. unsigned char* itr = begin;
  4080. while (end != itr)
  4081. {
  4082. //(*itr) = std::toupper((*itr), std::locale::classic());
  4083. (*itr) = static_cast<unsigned char>(::toupper(static_cast<int>(*itr)));
  4084. ++itr;
  4085. }
  4086. */
  4087. }
  4088. inline void convert_to_uppercase(char* begin, char* end)
  4089. {
  4090. convert_to_uppercase(reinterpret_cast<unsigned char*>(begin),
  4091. reinterpret_cast<unsigned char*>(end));
  4092. }
  4093. inline void convert_to_uppercase(std::string& str)
  4094. {
  4095. convert_to_uppercase(reinterpret_cast<unsigned char*>(const_cast<char*>(str.data())),
  4096. reinterpret_cast<unsigned char*>(const_cast<char*>(str.data() + str.size())));
  4097. }
  4098. inline void convert_to_lowercase(unsigned char* begin, unsigned char* end)
  4099. {
  4100. std::transform(begin,end,begin,::tolower);
  4101. /*
  4102. unsigned char* itr = begin;
  4103. while (end != itr)
  4104. {
  4105. //(*itr) = std::tolower((*itr), std::locale::classic());
  4106. (*itr) = static_cast<unsigned char>(::tolower(static_cast<int>(*itr)));
  4107. ++itr;
  4108. }
  4109. */
  4110. }
  4111. inline void convert_to_lowercase(char* begin, char* end)
  4112. {
  4113. convert_to_lowercase(reinterpret_cast<unsigned char*>(begin),
  4114. reinterpret_cast<unsigned char*>(end));
  4115. }
  4116. inline void convert_to_lowercase(const char* begin, const char* end)
  4117. {
  4118. convert_to_lowercase(const_cast<char*>(begin),const_cast<char*>(end));
  4119. }
  4120. inline void convert_to_lowercase(std::string& str)
  4121. {
  4122. convert_to_lowercase(reinterpret_cast<unsigned char*>(const_cast<char*>(str.data())),
  4123. reinterpret_cast<unsigned char*>(const_cast<char*>(str.data() + str.size())));
  4124. }
  4125. inline std::string as_lowercase(const std::string& str)
  4126. {
  4127. std::string result = str;
  4128. convert_to_lowercase(result);
  4129. return result;
  4130. }
  4131. inline std::string as_uppercase(const std::string& str)
  4132. {
  4133. std::string result = str;
  4134. convert_to_uppercase(result);
  4135. return result;
  4136. }
  4137. inline bool twoway_bitwise_interleave(const unsigned char* begin1, const unsigned char* end1,
  4138. const unsigned char* begin2, const unsigned char* end2,
  4139. unsigned char* out)
  4140. {
  4141. if (std::distance(begin1,end1) != std::distance(begin2,end2))
  4142. {
  4143. return false;
  4144. }
  4145. static const std::size_t interleave_table_size = 256;
  4146. static const unsigned short interleave_table[interleave_table_size] =
  4147. {
  4148. 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, // 0x00 - 0x07
  4149. 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, // 0x08 - 0x0F
  4150. 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, // 0x10 - 0x17
  4151. 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, // 0x18 - 0x1F
  4152. 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, // 0x20 - 0x27
  4153. 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, // 0x28 - 0x2F
  4154. 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, // 0x30 - 0x37
  4155. 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, // 0x38 - 0x3F
  4156. 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, // 0x40 - 0x47
  4157. 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, // 0x48 - 0x4F
  4158. 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, // 0x50 - 0x57
  4159. 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, // 0x58 - 0x5F
  4160. 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, // 0x60 - 0x67
  4161. 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, // 0x68 - 0x6F
  4162. 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, // 0x70 - 0x77
  4163. 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, // 0x78 - 0x7F
  4164. 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, // 0x80 - 0x87
  4165. 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, // 0x88 - 0x8F
  4166. 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, // 0x90 - 0x97
  4167. 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, // 0x98 - 0x9F
  4168. 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, // 0xA0 - 0xA7
  4169. 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, // 0xA8 - 0xAF
  4170. 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, // 0xB0 - 0xB7
  4171. 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, // 0xB8 - 0xBF
  4172. 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, // 0xC0 - 0xC7
  4173. 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, // 0xC8 - 0xCF
  4174. 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, // 0xD0 - 0xD7
  4175. 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, // 0xD8 - 0xDF
  4176. 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, // 0xE0 - 0xE7
  4177. 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, // 0xE8 - 0xEF
  4178. 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, // 0xF0 - 0xF7
  4179. 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 // 0xF8 - 0xFF
  4180. };
  4181. const unsigned char* itr1 = begin1;
  4182. const unsigned char* itr2 = begin2;
  4183. while (end1 != itr1)
  4184. {
  4185. *(reinterpret_cast<unsigned short*>(out)) = (interleave_table[*(itr2++)] << 1);
  4186. *(reinterpret_cast<unsigned short*>(out)) |= interleave_table[*(itr1++)];
  4187. out += 2;
  4188. }
  4189. return true;
  4190. }
  4191. inline bool twoway_bitwise_interleave(const char* begin1, const char* end1,
  4192. const char* begin2, const char* end2,
  4193. char* out)
  4194. {
  4195. return twoway_bitwise_interleave(reinterpret_cast<const unsigned char*>(begin1),
  4196. reinterpret_cast<const unsigned char*>(end1),
  4197. reinterpret_cast<const unsigned char*>(begin2),
  4198. reinterpret_cast<const unsigned char*>(end2),
  4199. reinterpret_cast<unsigned char*>(out));
  4200. }
  4201. inline bool twoway_bitwise_interleave(const std::string& str1,
  4202. const std::string& str2,
  4203. std::string& out)
  4204. {
  4205. if (str1.size() != str2.size())
  4206. {
  4207. return false;
  4208. }
  4209. out.resize(str1.size());
  4210. return twoway_bitwise_interleave(str1.data(),str1.data() + str1.size(),
  4211. str2.data(),str2.data() + str2.size(),
  4212. const_cast<char*>(out.data()));
  4213. }
  4214. template <std::size_t n>
  4215. struct interleave_ary;
  4216. template<> struct interleave_ary<sizeof(unsigned short)> { typedef unsigned short type; };
  4217. template<> struct interleave_ary<sizeof(unsigned int )> { typedef unsigned int type; };
  4218. template<> struct interleave_ary<sizeof(unsigned long long int)> { typedef unsigned long long int type; };
  4219. template <std::size_t n>
  4220. inline void create_nway_interleave_table(typename interleave_ary<n>::type table[256])
  4221. {
  4222. typedef typename interleave_ary<n>::type type;
  4223. const type diff = static_cast<type>(n - 1);
  4224. for (type i = static_cast<type>(0); i < static_cast<type>(256); ++i)
  4225. {
  4226. table[i] = 0x00;
  4227. for (type j = static_cast<type>(0); j < static_cast<type>(8); ++j)
  4228. {
  4229. table[i] |= (i & (1 << j)) << (j * diff);
  4230. }
  4231. }
  4232. }
  4233. namespace bitwise_operation { enum type { eAND, eOR, eXOR }; }
  4234. inline void bitwise_transform(const bitwise_operation::type& operation,
  4235. const unsigned char* begin1, const unsigned char* end1,
  4236. const unsigned char* begin2,
  4237. unsigned char* out)
  4238. {
  4239. const unsigned char* itr1 = begin1;
  4240. const unsigned char* itr2 = begin2;
  4241. switch (operation)
  4242. {
  4243. case bitwise_operation::eAND : while (itr1 != end1) { *(out++) = *(itr1++) & *(itr2++); } return;
  4244. case bitwise_operation::eOR : while (itr1 != end1) { *(out++) = *(itr1++) | *(itr2++); } return;
  4245. case bitwise_operation::eXOR : while (itr1 != end1) { *(out++) = *(itr1++) ^ *(itr2++); } return;
  4246. }
  4247. }
  4248. inline void bitwise_transform(const bitwise_operation::type& operation,
  4249. const char* begin1, const char* end1,
  4250. const char* begin2,
  4251. char* out)
  4252. {
  4253. bitwise_transform(operation,
  4254. reinterpret_cast<const unsigned char*>(begin1),
  4255. reinterpret_cast<const unsigned char*>(end1),
  4256. reinterpret_cast<const unsigned char*>(begin2),
  4257. reinterpret_cast<unsigned char*>(out));
  4258. }
  4259. inline void bitwise_transform(const bitwise_operation::type& operation,
  4260. const std::string& str1,
  4261. const std::string& str2,
  4262. std::string& out)
  4263. {
  4264. if (str1.size() != str2.size()) return;
  4265. out.resize(str1.size());
  4266. bitwise_transform(operation,
  4267. str1.data(),str1.data() + str1.size(),
  4268. str2.data(),
  4269. const_cast<char*>(out.data()));
  4270. }
  4271. inline std::size_t high_bit_count(const unsigned char c)
  4272. {
  4273. static const std::size_t high_bits_in_char[256] =
  4274. {
  4275. 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
  4276. 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  4277. 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  4278. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4279. 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  4280. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4281. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4282. 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  4283. 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  4284. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4285. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4286. 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  4287. 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  4288. 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  4289. 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  4290. 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
  4291. };
  4292. return high_bits_in_char[c];
  4293. }
  4294. inline std::size_t high_bit_count(const unsigned short& s)
  4295. {
  4296. const unsigned char* ptr = reinterpret_cast<const unsigned char*>(&s);
  4297. return high_bit_count(*(ptr + 0)) + high_bit_count(*(ptr + 1));
  4298. }
  4299. inline std::size_t high_bit_count(const unsigned int& i)
  4300. {
  4301. const unsigned char* ptr = reinterpret_cast<const unsigned char*>(&i);
  4302. return high_bit_count(*(ptr + 0)) + high_bit_count(*(ptr + 1)) +
  4303. high_bit_count(*(ptr + 2)) + high_bit_count(*(ptr + 3));
  4304. }
  4305. inline std::size_t high_bit_count(const long long int& ll)
  4306. {
  4307. const unsigned char* ptr = reinterpret_cast<const unsigned char*>(&ll);
  4308. return high_bit_count(*(ptr + 0)) + high_bit_count(*(ptr + 1)) +
  4309. high_bit_count(*(ptr + 2)) + high_bit_count(*(ptr + 3)) +
  4310. high_bit_count(*(ptr + 4)) + high_bit_count(*(ptr + 5)) +
  4311. high_bit_count(*(ptr + 6)) + high_bit_count(*(ptr + 7));
  4312. }
  4313. inline std::size_t high_bit_count(const unsigned char* begin, const unsigned char* end)
  4314. {
  4315. std::size_t count = 0;
  4316. const unsigned char* itr = begin;
  4317. while (end != itr)
  4318. {
  4319. count += high_bit_count(*itr++);
  4320. }
  4321. return count;
  4322. }
  4323. inline std::size_t high_bit_count(const char* begin, const char* end)
  4324. {
  4325. return high_bit_count(reinterpret_cast<const unsigned char*>(begin),
  4326. reinterpret_cast<const unsigned char*>(end));
  4327. }
  4328. inline std::size_t high_bit_count(const std::string& str)
  4329. {
  4330. return high_bit_count(str.data(),str.data() + str.size());
  4331. }
  4332. inline bool bit_state(const std::size_t& index, const unsigned char* ptr)
  4333. {
  4334. static const unsigned char bit_mask[] =
  4335. {
  4336. 0x01, //00000001
  4337. 0x02, //00000010
  4338. 0x04, //00000100
  4339. 0x08, //00001000
  4340. 0x10, //00010000
  4341. 0x20, //00100000
  4342. 0x40, //01000000
  4343. 0x80 //10000000
  4344. };
  4345. return (0 != (ptr[(index >> 3)] & bit_mask[index & 7]));
  4346. }
  4347. inline void set_bit_high(const std::size_t& index, unsigned char* const ptr)
  4348. {
  4349. static const unsigned char bit_mask[] =
  4350. {
  4351. 0x01, //00000001
  4352. 0x02, //00000010
  4353. 0x04, //00000100
  4354. 0x08, //00001000
  4355. 0x10, //00010000
  4356. 0x20, //00100000
  4357. 0x40, //01000000
  4358. 0x80 //10000000
  4359. };
  4360. ptr[(index >> 3)] |= bit_mask[index & 7];
  4361. }
  4362. inline void set_bit_low(const std::size_t& index, unsigned char* const ptr)
  4363. {
  4364. static const unsigned char bit_mask[] =
  4365. {
  4366. 0xFE, //11111110
  4367. 0xFD, //11111101
  4368. 0xFB, //11111011
  4369. 0xF7, //11110111
  4370. 0xEF, //11101111
  4371. 0xDF, //11011111
  4372. 0xBF, //10111111
  4373. 0x7F //01111111
  4374. };
  4375. ptr[(index >> 3)] &= bit_mask[index & 7];
  4376. }
  4377. inline std::size_t hamming_distance(const unsigned char* begin1, const unsigned char* end1,
  4378. const unsigned char* begin2, const unsigned char* end2)
  4379. {
  4380. if (std::distance(begin1,end1) != std::distance(begin2,end2))
  4381. {
  4382. return std::numeric_limits<std::size_t>::max();
  4383. }
  4384. std::size_t distance = 0;
  4385. const unsigned char* itr1 = begin1;
  4386. const unsigned char* itr2 = begin2;
  4387. while (end1 != itr1)
  4388. {
  4389. distance += high_bit_count(static_cast<unsigned char>(((*itr1++) ^ (*itr2++)) & 0xFF));
  4390. }
  4391. return distance;
  4392. }
  4393. inline std::size_t hamming_distance(const char* begin1, const char* end1,
  4394. const char* begin2, const char* end2)
  4395. {
  4396. return hamming_distance(reinterpret_cast<const unsigned char*>(begin1),
  4397. reinterpret_cast<const unsigned char*>(end1),
  4398. reinterpret_cast<const unsigned char*>(begin2),
  4399. reinterpret_cast<const unsigned char*>(end2));
  4400. }
  4401. inline std::size_t hamming_distance(const std::string& str1, const std::string& str2)
  4402. {
  4403. return hamming_distance(str1.data(), str1.data() + str1.size(),
  4404. str2.data(), str2.data() + str2.size());
  4405. }
  4406. template <typename Iterator>
  4407. inline std::size_t hamming_distance_elementwise(const Iterator begin1, const Iterator end1,
  4408. const Iterator begin2, const Iterator end2)
  4409. {
  4410. if (std::distance(begin1,end1) != std::distance(begin2,end2))
  4411. {
  4412. return std::numeric_limits<std::size_t>::max();
  4413. }
  4414. std::size_t distance = 0;
  4415. Iterator itr1 = begin1;
  4416. Iterator itr2 = begin2;
  4417. while (end1 != itr1)
  4418. {
  4419. if ((*itr1) != (*itr2))
  4420. ++distance;
  4421. }
  4422. return distance;
  4423. }
  4424. inline std::size_t hamming_distance_elementwise(const std::string& str1, const std::string& str2)
  4425. {
  4426. return hamming_distance_elementwise(str1.data(), str1.data() + str1.size(),
  4427. str2.data(), str2.data() + str2.size());
  4428. }
  4429. class token_grid
  4430. {
  4431. public:
  4432. typedef const unsigned char* iterator_t;
  4433. typedef unsigned int index_t;
  4434. typedef std::pair<iterator_t,iterator_t> range_t;
  4435. typedef std::deque<range_t> token_list_t;
  4436. typedef std::pair<index_t,index_t> row_index_range_t;
  4437. typedef std::deque<row_index_range_t> row_index_t;
  4438. typedef std::pair<index_t,index_t> row_range_t;
  4439. typedef std::pair<index_t,index_t> col_range_t;
  4440. private:
  4441. struct store
  4442. {
  4443. store()
  4444. : max_column(0)
  4445. {}
  4446. token_list_t token_list;
  4447. row_index_t row_index;
  4448. std::size_t max_column;
  4449. inline void clear()
  4450. {
  4451. token_list.clear();
  4452. row_index.clear();
  4453. }
  4454. inline range_t operator()(const std::size_t& col, const std::size_t& row) const
  4455. {
  4456. if (row < row_index.size())
  4457. {
  4458. const row_index_range_t& r = row_index[row];
  4459. if (col < (r.second - r.first + 1))
  4460. return *(token_list.begin() + (r.first + col));
  4461. else
  4462. return null_range();
  4463. }
  4464. else
  4465. return null_range();
  4466. }
  4467. inline bool remove_row(const std::size_t& row)
  4468. {
  4469. if (row >= row_index.size()) return false;
  4470. row_index_range_t& r = row_index[row];
  4471. std::size_t number_of_tokens = r.second - r.first + 1;
  4472. token_list_t::iterator remove_begin = token_list.begin() + r.first;
  4473. token_list_t::iterator remove_end = token_list.begin() + r.first + number_of_tokens;
  4474. token_list.erase(remove_begin,remove_end);
  4475. row_index.erase(row_index.begin() + row);
  4476. for (std::size_t i = row; i < row_index.size(); ++i)
  4477. {
  4478. row_index_range_t& r = row_index[i];
  4479. r.first -= static_cast<unsigned int>(number_of_tokens);
  4480. r.second -= static_cast<unsigned int>(number_of_tokens);
  4481. }
  4482. return true;
  4483. }
  4484. inline std::size_t token_count(const row_index_range_t& r) const
  4485. {
  4486. return (r.second - r.first + 1);
  4487. }
  4488. inline std::size_t token_count(const std::size_t& index) const
  4489. {
  4490. return token_count(row_index[index]);
  4491. }
  4492. inline bool remove_row_range(const std::size_t& r0, const std::size_t& r1)
  4493. {
  4494. if (r0 > r1)
  4495. return false;
  4496. else if (r0 >= row_index.size())
  4497. return false;
  4498. else if (r1 >= row_index.size())
  4499. return false;
  4500. std::size_t number_of_tokens = 0;
  4501. for (std::size_t i = r0; i <= r1; ++i)
  4502. {
  4503. row_index_range_t& r = row_index[i];
  4504. number_of_tokens += token_count(r);
  4505. }
  4506. row_index_range_t rr0 = row_index[r0];
  4507. token_list_t::iterator remove_begin = token_list.begin() + rr0.first;
  4508. token_list_t::iterator remove_end = token_list.begin() + rr0.first + number_of_tokens;
  4509. token_list.erase(remove_begin,remove_end);
  4510. row_index.erase(row_index.begin() + r0,row_index.begin() + r0 + (r1 - r0 + 1));
  4511. for (std::size_t i = r0; i < row_index.size(); ++i)
  4512. {
  4513. row_index_range_t& r = row_index[i];
  4514. r.first -= static_cast<unsigned int>(number_of_tokens);
  4515. r.second -= static_cast<unsigned int>(number_of_tokens);
  4516. }
  4517. return true;
  4518. }
  4519. struct remove_column_impl
  4520. {
  4521. std::size_t column;
  4522. std::size_t counter;
  4523. std::size_t remainder;
  4524. std::size_t current_row;
  4525. inline void update(store& idx)
  4526. {
  4527. current_row++;
  4528. while (current_row < idx.row_index.size())
  4529. {
  4530. std::size_t number_of_tokens = idx.token_count(current_row);
  4531. if (number_of_tokens > column)
  4532. break;
  4533. counter += number_of_tokens;
  4534. ++current_row;
  4535. }
  4536. if (current_row < idx.row_index.size())
  4537. {
  4538. counter += column + remainder;
  4539. row_index_range_t& r = idx.row_index[current_row];
  4540. remainder = (r.second - r.first) - column;
  4541. }
  4542. else
  4543. counter = std::numeric_limits<std::size_t>::max();
  4544. }
  4545. inline void process(store& idx)
  4546. {
  4547. token_list_t::iterator itr1 = idx.token_list.begin();
  4548. token_list_t::iterator itr2 = idx.token_list.begin();
  4549. token_list_t::iterator end = idx.token_list.end();
  4550. counter = 0;
  4551. remainder = 0;
  4552. current_row = static_cast<std::size_t>(-1);
  4553. update(idx);
  4554. while (end != itr1)
  4555. {
  4556. while ((end != itr1) && (0 != counter))
  4557. {
  4558. if (itr1 != itr2)
  4559. {
  4560. (*itr2) = (*itr1);
  4561. }
  4562. ++itr1;
  4563. ++itr2;
  4564. --counter;
  4565. }
  4566. if (0 == counter)
  4567. {
  4568. update(idx);
  4569. ++itr1;
  4570. }
  4571. }
  4572. std::size_t remove_count = 0;
  4573. idx.max_column = std::numeric_limits<std::size_t>::min();
  4574. for (std::size_t i = 0; i < idx.row_index.size(); ++i)
  4575. {
  4576. row_index_range_t& r = idx.row_index[i];
  4577. std::size_t token_count = (r.second - r.first + 1);
  4578. r.first -= static_cast<unsigned int>(remove_count);
  4579. if (token_count > column)
  4580. {
  4581. ++remove_count;
  4582. }
  4583. r.second -= static_cast<unsigned int>(remove_count);
  4584. token_count = (r.second - r.first + 1);
  4585. if (token_count > idx.max_column)
  4586. idx.max_column = token_count;
  4587. }
  4588. idx.token_list.resize(idx.token_list.size() - remove_count);
  4589. }
  4590. };
  4591. inline bool remove_column(const std::size_t& column)
  4592. {
  4593. if (column >= max_column) return false;
  4594. remove_column_impl rc;
  4595. rc.column = column;
  4596. rc.process(*this);
  4597. return true;
  4598. }
  4599. inline static range_t null_range()
  4600. {
  4601. static const range_t null_range_ = range_t(reinterpret_cast<const unsigned char*>(0),
  4602. reinterpret_cast<const unsigned char*>(0));
  4603. return null_range_;
  4604. }
  4605. };
  4606. template <typename DelimiterPredicate = multiple_char_delimiter_predicate>
  4607. struct row_processor
  4608. {
  4609. row_processor(store& idx,
  4610. DelimiterPredicate& tp,
  4611. const split_options::type split_mode = split_options::compress_delimiters)
  4612. : idx_(idx),
  4613. row_start_index_(0),
  4614. row_end_index_(0),
  4615. token_predicate_(tp),
  4616. split_mode_(split_mode)
  4617. {
  4618. idx_.max_column = std::numeric_limits<std::size_t>::min();
  4619. }
  4620. inline void operator()(const range_t& range)
  4621. {
  4622. if (0 == std::distance(range.first,range.second))
  4623. return;
  4624. row_start_index_ = static_cast<index_t>(idx_.token_list.size());
  4625. std::size_t token_count = split(token_predicate_,
  4626. range.first,range.second,
  4627. std::back_inserter(idx_.token_list),
  4628. split_mode_);
  4629. row_end_index_ = row_start_index_ + token_count - 1;
  4630. idx_.row_index.push_back(std::make_pair(row_start_index_,row_end_index_));
  4631. if (token_count > idx_.max_column)
  4632. idx_.max_column = token_count;
  4633. }
  4634. row_processor<DelimiterPredicate> operator=(const row_processor<DelimiterPredicate>&);
  4635. store& idx_;
  4636. index_t row_start_index_;
  4637. index_t row_end_index_;
  4638. DelimiterPredicate& token_predicate_;
  4639. split_options::type split_mode_;
  4640. };
  4641. public:
  4642. inline row_range_t range(std::size_t lower_bound,
  4643. std::size_t upper_bound = std::numeric_limits<std::size_t>::max()) const
  4644. {
  4645. if (upper_bound == std::numeric_limits<std::size_t>::max())
  4646. {
  4647. upper_bound = dsv_index_.token_list.size();
  4648. }
  4649. else if (upper_bound > dsv_index_.token_list.size())
  4650. {
  4651. return row_range_t(std::numeric_limits<std::size_t>::max(),std::numeric_limits<std::size_t>::max());
  4652. }
  4653. else if (lower_bound > upper_bound)
  4654. {
  4655. return row_range_t(std::numeric_limits<std::size_t>::max(),std::numeric_limits<std::size_t>::max());
  4656. }
  4657. return row_range_t(lower_bound,upper_bound);
  4658. }
  4659. struct options
  4660. {
  4661. options()
  4662. : row_split_option(split_options::compress_delimiters),
  4663. column_split_option(split_options::compress_delimiters),
  4664. row_delimiters("\n\r"),
  4665. column_delimiters(",|;\t "),
  4666. support_dquotes(false),
  4667. trim_dquotes(false)
  4668. {}
  4669. options(split_options::type sro,
  4670. split_options::type sco,
  4671. const std::string& rd,
  4672. const std::string& cd,
  4673. const bool support_dq = false,
  4674. const bool trim_dq = false)
  4675. : row_split_option(sro),
  4676. column_split_option(sco),
  4677. row_delimiters(rd),
  4678. column_delimiters(cd),
  4679. support_dquotes(support_dq),
  4680. trim_dquotes(trim_dq)
  4681. {}
  4682. inline options& set_column_split_option(const split_options::type& option)
  4683. {
  4684. column_split_option = option;
  4685. return *this;
  4686. }
  4687. inline options& set_row_split_option(const split_options::type& option)
  4688. {
  4689. row_split_option = option;
  4690. return *this;
  4691. }
  4692. inline options& set_column_delimiters(const std::string& delimiters)
  4693. {
  4694. column_delimiters = delimiters;
  4695. return *this;
  4696. }
  4697. inline options& set_row_delimiters(const std::string& delimiters)
  4698. {
  4699. row_delimiters = delimiters;
  4700. return *this;
  4701. }
  4702. split_options::type row_split_option;
  4703. split_options::type column_split_option;
  4704. std::string row_delimiters;
  4705. std::string column_delimiters;
  4706. bool support_dquotes;
  4707. bool trim_dquotes;
  4708. };
  4709. class row_type
  4710. {
  4711. private:
  4712. typedef std::pair<bool,row_type*> row_pair_type;
  4713. public:
  4714. row_type()
  4715. : index_(std::numeric_limits<std::size_t>::max()),
  4716. size_(0)
  4717. {}
  4718. row_type(const std::size_t& index,
  4719. const store& dsv_index)
  4720. : index_(index),
  4721. size_ (dsv_index.token_count(index)),
  4722. begin_(dsv_index.token_list.begin() + dsv_index.row_index[index].first)
  4723. {}
  4724. inline bool is_null(const std::size_t& index) const
  4725. {
  4726. const range_t& range = *(begin_ + index);
  4727. return (0 == std::distance(range.first,range.second));
  4728. }
  4729. template <typename T>
  4730. inline T operator[](const std::size_t& index) const
  4731. {
  4732. const range_t& range = *(begin_ + index);
  4733. return string_to_type_converter<T>(range.first,range.second);
  4734. }
  4735. template <typename T>
  4736. inline T get(const std::size_t& index) const
  4737. {
  4738. return operator[]<T>(index);
  4739. }
  4740. inline col_range_t all_columns() const
  4741. {
  4742. return col_range_t(0,static_cast<index_t>(size()));
  4743. }
  4744. inline range_t range() const
  4745. {
  4746. return range_t((*begin_).first,(*(begin_ + (size_ - 1))).second);
  4747. }
  4748. inline range_t token(const std::size_t& index) const
  4749. {
  4750. return *(begin_ + index);
  4751. }
  4752. inline std::size_t index() const
  4753. {
  4754. return index_;
  4755. }
  4756. inline std::size_t size() const
  4757. {
  4758. return size_;
  4759. }
  4760. inline std::size_t raw_length() const
  4761. {
  4762. std::size_t result = 0;
  4763. token_list_t::const_iterator itr = begin_;
  4764. for (std::size_t i = 0; i < size_; ++i, ++itr)
  4765. {
  4766. const range_t& range = (*itr);
  4767. result += std::distance(range.first,range.second);
  4768. }
  4769. return result;
  4770. }
  4771. inline std::size_t raw_length(const std::size_t& column_index) const
  4772. {
  4773. const range_t& range = *(begin_ + column_index);
  4774. return std::distance(range.first,range.second);
  4775. }
  4776. inline std::string as_string() const
  4777. {
  4778. std::string result;
  4779. result.reserve(std::distance(begin_->first,(begin_ + (size_ - 1))->second));
  4780. token_list_t::const_iterator itr = begin_;
  4781. for (std::size_t i = 0; i < size_; ++i, ++itr)
  4782. {
  4783. const range_t& range = (*itr);
  4784. result.append(range.first,range.second);
  4785. }
  4786. return result;
  4787. }
  4788. inline void as_string(std::string& out) const
  4789. {
  4790. out = as_string();
  4791. }
  4792. template <typename T0, typename T1, typename T2, typename T3,
  4793. typename T4, typename T5, typename T6, typename T7,
  4794. typename T8, typename T9>
  4795. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4796. const std::size_t& col2, const std::size_t& col3,
  4797. const std::size_t& col4, const std::size_t& col5,
  4798. const std::size_t& col6, const std::size_t& col7,
  4799. const std::size_t& col8, const std::size_t& col9,
  4800. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  4801. T6& t6, T7& t7, T8& t8, T9& t9) const
  4802. {
  4803. if (!process(*(begin_ + col0),t0)) return false;
  4804. if (!process(*(begin_ + col1),t1)) return false;
  4805. if (!process(*(begin_ + col2),t2)) return false;
  4806. if (!process(*(begin_ + col3),t3)) return false;
  4807. if (!process(*(begin_ + col4),t4)) return false;
  4808. if (!process(*(begin_ + col5),t5)) return false;
  4809. if (!process(*(begin_ + col6),t6)) return false;
  4810. if (!process(*(begin_ + col7),t7)) return false;
  4811. if (!process(*(begin_ + col8),t8)) return false;
  4812. if (!process(*(begin_ + col9),t9)) return false;
  4813. return true;
  4814. }
  4815. template <typename T0, typename T1, typename T2, typename T3,
  4816. typename T4, typename T5, typename T6, typename T7,
  4817. typename T8>
  4818. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4819. const std::size_t& col2, const std::size_t& col3,
  4820. const std::size_t& col4, const std::size_t& col5,
  4821. const std::size_t& col6, const std::size_t& col7,
  4822. const std::size_t& col8,
  4823. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  4824. T6& t6, T7& t7, T8& t8) const
  4825. {
  4826. if (!process(*(begin_ + col0),t0)) return false;
  4827. if (!process(*(begin_ + col1),t1)) return false;
  4828. if (!process(*(begin_ + col2),t2)) return false;
  4829. if (!process(*(begin_ + col3),t3)) return false;
  4830. if (!process(*(begin_ + col4),t4)) return false;
  4831. if (!process(*(begin_ + col5),t5)) return false;
  4832. if (!process(*(begin_ + col6),t6)) return false;
  4833. if (!process(*(begin_ + col7),t7)) return false;
  4834. if (!process(*(begin_ + col8),t8)) return false;
  4835. return true;
  4836. }
  4837. template <typename T0, typename T1, typename T2, typename T3,
  4838. typename T4, typename T5, typename T6, typename T7>
  4839. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4840. const std::size_t& col2, const std::size_t& col3,
  4841. const std::size_t& col4, const std::size_t& col5,
  4842. const std::size_t& col6, const std::size_t& col7,
  4843. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  4844. T6& t6, T7& t7) const
  4845. {
  4846. if (!process(*(begin_ + col0),t0)) return false;
  4847. if (!process(*(begin_ + col1),t1)) return false;
  4848. if (!process(*(begin_ + col2),t2)) return false;
  4849. if (!process(*(begin_ + col3),t3)) return false;
  4850. if (!process(*(begin_ + col4),t4)) return false;
  4851. if (!process(*(begin_ + col5),t5)) return false;
  4852. if (!process(*(begin_ + col6),t6)) return false;
  4853. if (!process(*(begin_ + col7),t7)) return false;
  4854. return true;
  4855. }
  4856. template <typename T0, typename T1, typename T2, typename T3,
  4857. typename T4, typename T5, typename T6>
  4858. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4859. const std::size_t& col2, const std::size_t& col3,
  4860. const std::size_t& col4, const std::size_t& col5,
  4861. const std::size_t& col6,
  4862. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  4863. T6& t6) const
  4864. {
  4865. if (!process(*(begin_ + col0),t0)) return false;
  4866. if (!process(*(begin_ + col1),t1)) return false;
  4867. if (!process(*(begin_ + col2),t2)) return false;
  4868. if (!process(*(begin_ + col3),t3)) return false;
  4869. if (!process(*(begin_ + col4),t4)) return false;
  4870. if (!process(*(begin_ + col5),t5)) return false;
  4871. if (!process(*(begin_ + col6),t6)) return false;
  4872. return true;
  4873. }
  4874. template <typename T0, typename T1, typename T2, typename T3,
  4875. typename T4, typename T5>
  4876. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4877. const std::size_t& col2, const std::size_t& col3,
  4878. const std::size_t& col4, const std::size_t& col5,
  4879. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const
  4880. {
  4881. if (!process(*(begin_ + col0),t0)) return false;
  4882. if (!process(*(begin_ + col1),t1)) return false;
  4883. if (!process(*(begin_ + col2),t2)) return false;
  4884. if (!process(*(begin_ + col3),t3)) return false;
  4885. if (!process(*(begin_ + col4),t4)) return false;
  4886. if (!process(*(begin_ + col5),t5)) return false;
  4887. return true;
  4888. }
  4889. template <typename T0, typename T1, typename T2, typename T3, typename T4>
  4890. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4891. const std::size_t& col2, const std::size_t& col3,
  4892. const std::size_t& col4,
  4893. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4) const
  4894. {
  4895. if (!process(*(begin_ + col0),t0)) return false;
  4896. if (!process(*(begin_ + col1),t1)) return false;
  4897. if (!process(*(begin_ + col2),t2)) return false;
  4898. if (!process(*(begin_ + col3),t3)) return false;
  4899. if (!process(*(begin_ + col4),t4)) return false;
  4900. return true;
  4901. }
  4902. template <typename T0, typename T1, typename T2, typename T3>
  4903. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4904. const std::size_t& col2, const std::size_t& col3,
  4905. T0& t0, T1& t1, T2& t2, T3& t3) const
  4906. {
  4907. if (!process(*(begin_ + col0),t0)) return false;
  4908. if (!process(*(begin_ + col1),t1)) return false;
  4909. if (!process(*(begin_ + col2),t2)) return false;
  4910. if (!process(*(begin_ + col3),t3)) return false;
  4911. return true;
  4912. }
  4913. template <typename T0, typename T1, typename T2>
  4914. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4915. const std::size_t& col2,
  4916. T0& t0, T1& t1, T2& t2) const
  4917. {
  4918. if (!process(*(begin_ + col0),t0)) return false;
  4919. if (!process(*(begin_ + col1),t1)) return false;
  4920. if (!process(*(begin_ + col2),t2)) return false;
  4921. return true;
  4922. }
  4923. template <typename T0, typename T1>
  4924. inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1,
  4925. T0& t0, T1& t1) const
  4926. {
  4927. if (!process(*(begin_ + col0),t0)) return false;
  4928. if (!process(*(begin_ + col1),t1)) return false;
  4929. return true;
  4930. }
  4931. template <typename T>
  4932. inline bool parse_with_index(const std::size_t& col, T& t) const
  4933. {
  4934. return process(*(begin_ + col),t);
  4935. }
  4936. template <typename T0, typename T1, typename T2, typename T3,
  4937. typename T4, typename T5, typename T6, typename T7,
  4938. typename T8, typename T9 >
  4939. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  4940. T4& t4, T5& t5, T6& t6, T7& t7,
  4941. T8& t8, T9& t9) const
  4942. {
  4943. if (!process(*(begin_ + 0),t0)) return false;
  4944. if (!process(*(begin_ + 1),t1)) return false;
  4945. if (!process(*(begin_ + 2),t2)) return false;
  4946. if (!process(*(begin_ + 3),t3)) return false;
  4947. if (!process(*(begin_ + 4),t4)) return false;
  4948. if (!process(*(begin_ + 5),t5)) return false;
  4949. if (!process(*(begin_ + 6),t6)) return false;
  4950. if (!process(*(begin_ + 7),t7)) return false;
  4951. if (!process(*(begin_ + 8),t8)) return false;
  4952. if (!process(*(begin_ + 9),t9)) return false;
  4953. return true;
  4954. }
  4955. template <typename T0, typename T1, typename T2, typename T3,
  4956. typename T4, typename T5, typename T6, typename T7,
  4957. typename T8>
  4958. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  4959. T4& t4, T5& t5, T6& t6, T7& t7,
  4960. T8& t8) const
  4961. {
  4962. if (!process(*(begin_ + 0),t0)) return false;
  4963. if (!process(*(begin_ + 1),t1)) return false;
  4964. if (!process(*(begin_ + 2),t2)) return false;
  4965. if (!process(*(begin_ + 3),t3)) return false;
  4966. if (!process(*(begin_ + 4),t4)) return false;
  4967. if (!process(*(begin_ + 5),t5)) return false;
  4968. if (!process(*(begin_ + 6),t6)) return false;
  4969. if (!process(*(begin_ + 7),t7)) return false;
  4970. if (!process(*(begin_ + 8),t8)) return false;
  4971. return true;
  4972. }
  4973. template <typename T0, typename T1, typename T2, typename T3,
  4974. typename T4, typename T5, typename T6, typename T7>
  4975. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  4976. T4& t4, T5& t5, T6& t6, T7& t7) const
  4977. {
  4978. if (!process(*(begin_ + 0),t0)) return false;
  4979. if (!process(*(begin_ + 1),t1)) return false;
  4980. if (!process(*(begin_ + 2),t2)) return false;
  4981. if (!process(*(begin_ + 3),t3)) return false;
  4982. if (!process(*(begin_ + 4),t4)) return false;
  4983. if (!process(*(begin_ + 5),t5)) return false;
  4984. if (!process(*(begin_ + 6),t6)) return false;
  4985. if (!process(*(begin_ + 7),t7)) return false;
  4986. return true;
  4987. }
  4988. template <typename T0, typename T1, typename T2, typename T3,
  4989. typename T4, typename T5, typename T6>
  4990. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  4991. T4& t4, T5& t5, T6& t6) const
  4992. {
  4993. if (!process(*(begin_ + 0),t0)) return false;
  4994. if (!process(*(begin_ + 1),t1)) return false;
  4995. if (!process(*(begin_ + 2),t2)) return false;
  4996. if (!process(*(begin_ + 3),t3)) return false;
  4997. if (!process(*(begin_ + 4),t4)) return false;
  4998. if (!process(*(begin_ + 5),t5)) return false;
  4999. if (!process(*(begin_ + 6),t6)) return false;
  5000. return true;
  5001. }
  5002. template <typename T0, typename T1, typename T2, typename T3,
  5003. typename T4, typename T5>
  5004. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3,
  5005. T4& t4, T5& t5) const
  5006. {
  5007. if (!process(*(begin_ + 0),t0)) return false;
  5008. if (!process(*(begin_ + 1),t1)) return false;
  5009. if (!process(*(begin_ + 2),t2)) return false;
  5010. if (!process(*(begin_ + 3),t3)) return false;
  5011. if (!process(*(begin_ + 4),t4)) return false;
  5012. if (!process(*(begin_ + 5),t5)) return false;
  5013. return true;
  5014. }
  5015. template <typename T0, typename T1,
  5016. typename T2, typename T3,typename T4>
  5017. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3, T4& t4) const
  5018. {
  5019. if (!process(*(begin_ + 0),t0)) return false;
  5020. if (!process(*(begin_ + 1),t1)) return false;
  5021. if (!process(*(begin_ + 2),t2)) return false;
  5022. if (!process(*(begin_ + 3),t3)) return false;
  5023. if (!process(*(begin_ + 4),t4)) return false;
  5024. return true;
  5025. }
  5026. template <typename T0, typename T1,
  5027. typename T2, typename T3>
  5028. inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3) const
  5029. {
  5030. if (!process(*(begin_ + 0),t0)) return false;
  5031. if (!process(*(begin_ + 1),t1)) return false;
  5032. if (!process(*(begin_ + 2),t2)) return false;
  5033. if (!process(*(begin_ + 3),t3)) return false;
  5034. return true;
  5035. }
  5036. template <typename T0, typename T1, typename T2>
  5037. inline bool parse(T0& t0, T1& t1, T2& t2) const
  5038. {
  5039. if (!process(*(begin_ + 0),t0)) return false;
  5040. if (!process(*(begin_ + 1),t1)) return false;
  5041. if (!process(*(begin_ + 2),t2)) return false;
  5042. return true;
  5043. }
  5044. template <typename T0, typename T1>
  5045. inline bool parse(T0& t0, T1& t1) const
  5046. {
  5047. if (!process(*(begin_ + 0),t0)) return false;
  5048. if (!process(*(begin_ + 1),t1)) return false;
  5049. return true;
  5050. }
  5051. template <typename T0>
  5052. inline bool parse(T0& t) const
  5053. {
  5054. return process(*begin_,t);
  5055. }
  5056. template <typename T, typename OutputIterator>
  5057. inline void parse(OutputIterator out) const
  5058. {
  5059. token_list_t::const_iterator itr = begin_;
  5060. const token_list_t::const_iterator end = begin_ + size_;
  5061. while (end != itr)
  5062. {
  5063. const range_t& range = (*itr);
  5064. *(out++) = string_to_type_converter<T>(range.first,range.second);
  5065. ++itr;
  5066. }
  5067. }
  5068. bool validate_column_range(const col_range_t& range) const
  5069. {
  5070. if ((range.first > size()) || (range.second > size()))
  5071. return false;
  5072. else if (range.first > range.second)
  5073. return false;
  5074. else
  5075. return true;
  5076. }
  5077. col_range_t range(const std::size_t& lower_bound,
  5078. const std::size_t& upper_bound = std::numeric_limits<std::size_t>::max()) const
  5079. {
  5080. if (std::numeric_limits<std::size_t>::max() != upper_bound)
  5081. return col_range_t(lower_bound,upper_bound);
  5082. else
  5083. return col_range_t(lower_bound,static_cast<index_t>(size()));
  5084. }
  5085. template <typename T,
  5086. typename Allocator,
  5087. template <typename,typename> class Sequence>
  5088. inline bool parse(const col_range_t& range,
  5089. Sequence<T,Allocator>& sequence) const
  5090. {
  5091. if (!validate_column_range(range))
  5092. return false;
  5093. token_list_t::const_iterator itr = (begin_ + range.first);
  5094. token_list_t::const_iterator end = (begin_ + range.second);
  5095. T t;
  5096. while (end != itr)
  5097. {
  5098. const range_t& range = (*itr);
  5099. if (string_to_type_converter(range.first,range.second,t))
  5100. sequence.push_back(t);
  5101. else
  5102. return false;
  5103. ++itr;
  5104. }
  5105. return true;
  5106. }
  5107. template <typename T,
  5108. typename Comparator,
  5109. typename Allocator>
  5110. inline bool parse(const col_range_t& range,
  5111. std::set<T,Comparator,Allocator>& set) const
  5112. {
  5113. if (!validate_column_range(range))
  5114. return false;
  5115. token_list_t::const_iterator itr = (begin_ + range.first);
  5116. token_list_t::const_iterator end = (begin_ + range.second);
  5117. T t;
  5118. while (end != itr)
  5119. {
  5120. const range_t& range = (*itr);
  5121. if (string_to_type_converter(range.first,range.second,t))
  5122. set.insert(t);
  5123. else
  5124. return false;
  5125. ++itr;
  5126. }
  5127. return true;
  5128. }
  5129. template <typename T,
  5130. typename Comparator,
  5131. typename Allocator>
  5132. inline bool parse(const col_range_t& range,
  5133. std::multiset<T,Comparator,Allocator>& multiset) const
  5134. {
  5135. if (!validate_column_range(range))
  5136. return false;
  5137. token_list_t::const_iterator itr = (begin_ + range.first);
  5138. token_list_t::const_iterator end = (begin_ + range.second);
  5139. T t;
  5140. while (end != itr)
  5141. {
  5142. const range_t& range = (*itr);
  5143. if (string_to_type_converter(range.first,range.second,t))
  5144. multiset.insert(t);
  5145. else
  5146. return false;
  5147. ++itr;
  5148. }
  5149. return true;
  5150. }
  5151. template <typename T, typename Container>
  5152. inline bool parse(const col_range_t& range,
  5153. std::queue<T,Container>& queue) const
  5154. {
  5155. if (!validate_column_range(range))
  5156. return false;
  5157. token_list_t::const_iterator itr = (begin_ + range.first);
  5158. token_list_t::const_iterator end = (begin_ + range.second);
  5159. T t;
  5160. while (end != itr)
  5161. {
  5162. const range_t& range = (*itr);
  5163. if (string_to_type_converter(range.first,range.second,t))
  5164. queue.push(t);
  5165. else
  5166. return false;
  5167. ++itr;
  5168. }
  5169. return true;
  5170. }
  5171. template <typename T, typename Container>
  5172. inline bool parse(const col_range_t& range,
  5173. std::stack<T,Container>& stack) const
  5174. {
  5175. if (!validate_column_range(range))
  5176. return false;
  5177. token_list_t::const_iterator itr = (begin_ + range.first);
  5178. token_list_t::const_iterator end = (begin_ + range.second);
  5179. T t;
  5180. while (end != itr)
  5181. {
  5182. const range_t& range = (*itr);
  5183. if (string_to_type_converter(range.first,range.second,t))
  5184. stack.push(t);
  5185. else
  5186. return false;
  5187. ++itr;
  5188. }
  5189. return true;
  5190. }
  5191. template <typename T,
  5192. typename Container,
  5193. typename Comparator>
  5194. inline bool parse(const col_range_t& range,
  5195. std::priority_queue<T,Container,Comparator>& priority_queue) const
  5196. {
  5197. if (!validate_column_range(range))
  5198. return false;
  5199. token_list_t::const_iterator itr = (begin_ + range.first);
  5200. token_list_t::const_iterator end = (begin_ + range.second);
  5201. T t;
  5202. while (end != itr)
  5203. {
  5204. const range_t& range = (*itr);
  5205. if (string_to_type_converter(range.first,range.second,t))
  5206. priority_queue.push(t);
  5207. else
  5208. return false;
  5209. ++itr;
  5210. }
  5211. return true;
  5212. }
  5213. template <typename T,
  5214. typename Allocator,
  5215. template <typename,typename> class Sequence>
  5216. inline bool parse(Sequence<T,Allocator>& sequence) const
  5217. {
  5218. return parse(range(0),sequence);
  5219. }
  5220. template <typename T,
  5221. typename Comparator,
  5222. typename Allocator>
  5223. inline bool parse(std::set<T,Comparator,Allocator>& set) const
  5224. {
  5225. return parse(range(0),set);
  5226. }
  5227. template <typename T,
  5228. typename Comparator,
  5229. typename Allocator>
  5230. inline bool parse(std::multiset<T,Comparator,Allocator>& multiset) const
  5231. {
  5232. return parse(range(0),multiset);
  5233. }
  5234. template <typename T, typename Container>
  5235. inline bool parse(std::queue<T,Container>& queue) const
  5236. {
  5237. return parse(range(0),queue);
  5238. }
  5239. template <typename T, typename Container>
  5240. inline bool parse(std::stack<T,Container>& stack) const
  5241. {
  5242. return parse(range(0),stack);
  5243. }
  5244. template <typename T,
  5245. typename Container,
  5246. typename Comparator>
  5247. inline bool parse(std::priority_queue<T,Container,Comparator>& priority_queue) const
  5248. {
  5249. return parse(range(0),priority_queue);
  5250. }
  5251. template <typename T,
  5252. typename Allocator,
  5253. template <typename,typename> class Sequence>
  5254. inline std::size_t parse_n(const std::size_t& n, Sequence<T,Allocator>& sequence) const
  5255. {
  5256. if (0 == n) return 0;
  5257. T t;
  5258. std::size_t count = 0;
  5259. token_list_t::const_iterator itr = begin_;
  5260. const token_list_t::const_iterator end = begin_ + size_;
  5261. while (end != itr)
  5262. {
  5263. const range_t& range = (*itr);
  5264. if (!string_to_type_converter(range.first,range.second,t))
  5265. return false;
  5266. else
  5267. sequence.push_back(t);
  5268. if (n == (++count))
  5269. break;
  5270. ++itr;
  5271. }
  5272. return count;
  5273. }
  5274. template <typename T, typename OutputIterator>
  5275. inline void parse_checked(OutputIterator out) const
  5276. {
  5277. T value;
  5278. token_list_t::const_iterator itr = begin_;
  5279. const token_list_t::const_iterator end = begin_ + size_;
  5280. while (end != itr)
  5281. {
  5282. const range_t& range = (*itr);
  5283. if (string_to_type_converter(range.first,range.second,value))
  5284. {
  5285. *(out++) = value;
  5286. }
  5287. ++itr;
  5288. }
  5289. }
  5290. template <typename T,
  5291. typename Allocator,
  5292. template <typename,typename> class Sequence>
  5293. inline void parse_checked(Sequence<T,Allocator>& sequence) const
  5294. {
  5295. parse_checked<T>(std::back_inserter(sequence));
  5296. }
  5297. template <typename T,
  5298. typename Comparator,
  5299. typename Allocator>
  5300. inline void parse_checked(std::set<T,Comparator,Allocator>& set) const
  5301. {
  5302. parse_checked<T>(std::inserter(set,set.end()));
  5303. }
  5304. template <typename T,
  5305. typename Comparator,
  5306. typename Allocator>
  5307. inline void parse_checked(std::multiset<T,Comparator,Allocator>& multiset) const
  5308. {
  5309. parse_checked<T>(std::inserter(multiset,multiset.end()));
  5310. }
  5311. template <typename T, typename Container>
  5312. inline void parse_checked(std::queue<T,Container>& queue) const
  5313. {
  5314. parse_checked<T>(push_inserter(queue));
  5315. }
  5316. template <typename T, typename Container>
  5317. inline void parse_checked(std::stack<T,Container>& stack) const
  5318. {
  5319. parse_checked<T>(push_inserter(stack));
  5320. }
  5321. template <typename T,
  5322. typename Container,
  5323. typename Comparator>
  5324. inline void parse_checked(std::priority_queue<T,Container,Comparator>& priority_queue) const
  5325. {
  5326. parse_checked<T>(push_inserter(priority_queue));
  5327. }
  5328. template <typename Function>
  5329. inline std::size_t for_each_column(const col_range_t& range, Function f) const
  5330. {
  5331. if (!validate_column_range(range))
  5332. return false;
  5333. token_list_t::const_iterator itr = begin_ + range.first;
  5334. token_list_t::const_iterator end = begin_ + range.second;
  5335. std::size_t col_count = 0;
  5336. while (end != itr)
  5337. {
  5338. const range_t& range = (*itr);
  5339. f(range);
  5340. ++itr;
  5341. ++col_count;
  5342. }
  5343. return col_count;
  5344. }
  5345. template <typename Function>
  5346. inline std::size_t for_each_column(Function f) const
  5347. {
  5348. return for_each_column(all_columns(),f);
  5349. }
  5350. private:
  5351. template <typename T>
  5352. inline bool process(const range_t& range, T& t) const
  5353. {
  5354. return string_to_type_converter(range.first,range.second,t);
  5355. }
  5356. private:
  5357. std::size_t index_;
  5358. std::size_t size_;
  5359. token_list_t::const_iterator begin_;
  5360. };
  5361. token_grid()
  5362. : file_name_(""),
  5363. buffer_(0),
  5364. buffer_size_(0),
  5365. min_column_count_(0),
  5366. max_column_count_(0),
  5367. load_from_file_(false),
  5368. state_(false)
  5369. {}
  5370. token_grid(const std::string& file_name,
  5371. const token_grid::options& options)
  5372. : file_name_(file_name),
  5373. buffer_(0),
  5374. buffer_size_(0),
  5375. min_column_count_(0),
  5376. max_column_count_(0),
  5377. options_(options),
  5378. load_from_file_(true),
  5379. state_(load())
  5380. {}
  5381. token_grid(const unsigned char* input_buffer,
  5382. const std::size_t& input_buffer_size,
  5383. const token_grid::options& options)
  5384. : file_name_(""),
  5385. buffer_(const_cast<unsigned char*>(input_buffer)),
  5386. buffer_size_(input_buffer_size),
  5387. min_column_count_(0),
  5388. max_column_count_(0),
  5389. options_(options),
  5390. load_from_file_(false),
  5391. state_(load())
  5392. {}
  5393. token_grid(const char* input_buffer,
  5394. const std::size_t& input_buffer_size,
  5395. const token_grid::options& options)
  5396. : file_name_(""),
  5397. buffer_(reinterpret_cast<unsigned char*>(const_cast<char*>(input_buffer))),
  5398. buffer_size_(input_buffer_size),
  5399. min_column_count_(0),
  5400. max_column_count_(0),
  5401. options_(options),
  5402. load_from_file_(false),
  5403. state_(load())
  5404. {}
  5405. token_grid(const std::string& input_buffer,
  5406. const std::size_t& input_buffer_size,
  5407. const token_grid::options& options)
  5408. : file_name_(""),
  5409. buffer_(reinterpret_cast<unsigned char*>(const_cast<char*>(input_buffer.data()))),
  5410. buffer_size_(input_buffer_size),
  5411. min_column_count_(0),
  5412. max_column_count_(0),
  5413. options_(options),
  5414. load_from_file_(false),
  5415. state_(load())
  5416. {}
  5417. token_grid(const std::string& file_name,
  5418. const std::string& column_delimiters = ",|;\t",
  5419. const std::string& row_delimiters = "\n\r")
  5420. : file_name_(file_name),
  5421. buffer_(0),
  5422. buffer_size_(0),
  5423. min_column_count_(0),
  5424. max_column_count_(0),
  5425. options_(split_options::compress_delimiters,
  5426. split_options::compress_delimiters,
  5427. row_delimiters,
  5428. column_delimiters),
  5429. load_from_file_(true),
  5430. state_(load())
  5431. {}
  5432. token_grid(const unsigned char* input_buffer,
  5433. const std::size_t& input_buffer_size,
  5434. const std::string& column_delimiters = ",|;\t",
  5435. const std::string& row_delimiters = "\n\r")
  5436. : file_name_(""),
  5437. buffer_(const_cast<unsigned char*>(input_buffer)),
  5438. buffer_size_(input_buffer_size),
  5439. min_column_count_(0),
  5440. max_column_count_(0),
  5441. options_(split_options::compress_delimiters,
  5442. split_options::compress_delimiters,
  5443. row_delimiters,
  5444. column_delimiters),
  5445. load_from_file_(false),
  5446. state_(load())
  5447. {}
  5448. token_grid(const char* input_buffer,
  5449. const std::size_t& input_buffer_size,
  5450. const std::string& column_delimiters = ",|;\t",
  5451. const std::string& row_delimiters = "\n\r")
  5452. : file_name_(""),
  5453. buffer_(reinterpret_cast<unsigned char*>(const_cast<char*>(input_buffer))),
  5454. buffer_size_(input_buffer_size),
  5455. min_column_count_(0),
  5456. max_column_count_(0),
  5457. options_(split_options::compress_delimiters,
  5458. split_options::compress_delimiters,
  5459. row_delimiters,
  5460. column_delimiters),
  5461. load_from_file_(false),
  5462. state_(load())
  5463. {}
  5464. token_grid(const std::string& input_buffer,
  5465. const std::size_t& input_buffer_size,
  5466. const std::string& column_delimiters = ",;|\t ",
  5467. const std::string& row_delimiters = "\n\r")
  5468. : file_name_(""),
  5469. buffer_(reinterpret_cast<unsigned char*>(const_cast<char*>(input_buffer.data()))),
  5470. buffer_size_(input_buffer_size),
  5471. min_column_count_(0),
  5472. max_column_count_(0),
  5473. options_(split_options::compress_delimiters,
  5474. split_options::compress_delimiters,
  5475. row_delimiters,
  5476. column_delimiters),
  5477. load_from_file_(false),
  5478. state_(load())
  5479. {}
  5480. ~token_grid()
  5481. {
  5482. if ((load_from_file_) && (0 != buffer_))
  5483. {
  5484. delete [] buffer_;
  5485. buffer_ = 0;
  5486. }
  5487. }
  5488. inline bool operator!() const
  5489. {
  5490. return !state_;
  5491. }
  5492. inline std::string source_file() const
  5493. {
  5494. return file_name_;
  5495. }
  5496. inline std::size_t row_count() const
  5497. {
  5498. return dsv_index_.row_index.size();
  5499. }
  5500. inline std::size_t min_column_count() const
  5501. {
  5502. return min_column_count_;
  5503. }
  5504. inline std::size_t max_column_count() const
  5505. {
  5506. return max_column_count_;
  5507. }
  5508. inline range_t token(const unsigned int& row, const std::size_t& col) const
  5509. {
  5510. return dsv_index_(col,row);
  5511. }
  5512. template <typename T>
  5513. inline T get(const unsigned int& row, const std::size_t& col)
  5514. {
  5515. range_t r = token(row,col);
  5516. return string_to_type_converter<T>(r.first,r.second);
  5517. }
  5518. inline row_type row(const unsigned int& row_index) const
  5519. {
  5520. return row_type(row_index,dsv_index_);
  5521. }
  5522. inline row_range_t all_rows() const
  5523. {
  5524. return row_range_t(0,static_cast<index_t>(dsv_index_.row_index.size()));
  5525. }
  5526. template <typename OutputIterator>
  5527. inline bool extract_column_checked(const row_range_t& row_range,
  5528. const std::size_t& index,
  5529. OutputIterator out) const
  5530. {
  5531. if (index > max_column_count_)
  5532. return false;
  5533. else if (row_range_invalid(row_range))
  5534. return false;
  5535. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5536. {
  5537. const row_index_range_t& row = dsv_index_.row_index[i];
  5538. if (index < dsv_index_.token_count(row))
  5539. {
  5540. dsv_index_.token_list.begin() + (row.first + index);
  5541. process_token_checked(*(dsv_index_.token_list.begin() + (row.first + index)),out);
  5542. }
  5543. }
  5544. return true;
  5545. }
  5546. template <typename OutputIterator>
  5547. inline bool extract_column_checked(const std::size_t& index,
  5548. OutputIterator out) const
  5549. {
  5550. return extract_column_checked(all_rows(),index,out);
  5551. }
  5552. template <typename T,
  5553. typename Allocator,
  5554. template <typename,typename> class Sequence>
  5555. inline void extract_column_checked(const std::size_t& index,
  5556. Sequence<T,Allocator>& sequence) const
  5557. {
  5558. extract_column_checked(index,back_inserter_with_valuetype(sequence));
  5559. }
  5560. template <typename T,
  5561. typename Comparator,
  5562. typename Allocator>
  5563. inline void extract_column_checked(const std::size_t& index,
  5564. std::set<T,Comparator,Allocator>& set) const
  5565. {
  5566. extract_column_checked(index,inserter_with_valuetype(set));
  5567. }
  5568. template <typename T,
  5569. typename Comparator,
  5570. typename Allocator>
  5571. inline void extract_column_checked(const std::size_t& index,
  5572. std::multiset<T,Comparator,Allocator>& multiset) const
  5573. {
  5574. extract_column_checked(index,inserter_with_valuetype(multiset));
  5575. }
  5576. template <typename OutputIterator>
  5577. inline bool extract_column(const row_range_t& row_range,
  5578. const std::size_t& index,
  5579. OutputIterator out) const
  5580. {
  5581. if (index > max_column_count_)
  5582. return false;
  5583. else if (row_range_invalid(row_range))
  5584. return false;
  5585. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5586. {
  5587. const row_index_range_t& row = dsv_index_.row_index[i];
  5588. if (index < dsv_index_.token_count(row))
  5589. {
  5590. process_token(*(dsv_index_.token_list.begin() + (row.first + index)),out);
  5591. }
  5592. }
  5593. return true;
  5594. }
  5595. template <typename OutputIterator>
  5596. inline bool extract_column(const std::size_t& index,
  5597. OutputIterator out) const
  5598. {
  5599. return extract_column(all_rows(),index,out);
  5600. }
  5601. template <typename OutputIterator0, typename OutputIterator1>
  5602. inline bool extract_column(const row_range_t& row_range,
  5603. const std::size_t& index0,
  5604. const std::size_t& index1,
  5605. OutputIterator0 out0,
  5606. OutputIterator1 out1) const
  5607. {
  5608. if ((index0 > max_column_count_) ||
  5609. (index1 > max_column_count_))
  5610. return false;
  5611. else if (row_range_invalid(row_range))
  5612. return false;
  5613. std::size_t max_index = std::max(index0,index1);
  5614. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5615. {
  5616. const row_index_range_t& row = dsv_index_.row_index[i];
  5617. if (max_index < dsv_index_.token_count(row))
  5618. {
  5619. process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0);
  5620. process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1);
  5621. }
  5622. }
  5623. return true;
  5624. }
  5625. template <typename OutputIterator0, typename OutputIterator1, typename OutputIterator2>
  5626. inline bool extract_column(const row_range_t& row_range,
  5627. const std::size_t& index0,
  5628. const std::size_t& index1,
  5629. const std::size_t& index2,
  5630. OutputIterator0 out0,
  5631. OutputIterator1 out1,
  5632. OutputIterator2 out2) const
  5633. {
  5634. if ((index0 > max_column_count_) ||
  5635. (index1 > max_column_count_) ||
  5636. (index2 > max_column_count_))
  5637. return false;
  5638. else if (row_range_invalid(row_range))
  5639. return false;
  5640. std::size_t max_index = std::max(index0,std::max(index1,index2));
  5641. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5642. {
  5643. const row_index_range_t& row = dsv_index_.row_index[i];
  5644. if (max_index < dsv_index_.token_count(row))
  5645. {
  5646. process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0);
  5647. process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1);
  5648. process_token(*(dsv_index_.token_list.begin() + (row.first + index2)),out2);
  5649. }
  5650. }
  5651. return true;
  5652. }
  5653. template <typename OutputIterator0, typename OutputIterator1,
  5654. typename OutputIterator2, typename OutputIterator3>
  5655. inline bool extract_column(const row_range_t& row_range,
  5656. const std::size_t& index0,
  5657. const std::size_t& index1,
  5658. const std::size_t& index2,
  5659. const std::size_t& index3,
  5660. OutputIterator0 out0,
  5661. OutputIterator1 out1,
  5662. OutputIterator2 out2,
  5663. OutputIterator3 out3) const
  5664. {
  5665. if ((index0 > max_column_count_) ||
  5666. (index1 > max_column_count_) ||
  5667. (index2 > max_column_count_) ||
  5668. (index3 > max_column_count_))
  5669. return false;
  5670. else if (row_range_invalid(row_range))
  5671. return false;
  5672. std::size_t max_index = std::max(std::max(index0,index1),std::max(index2,index3));
  5673. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5674. {
  5675. const row_index_range_t& row = dsv_index_.row_index[i];
  5676. if (max_index < dsv_index_.token_count(row))
  5677. {
  5678. process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0);
  5679. process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1);
  5680. process_token(*(dsv_index_.token_list.begin() + (row.first + index2)),out2);
  5681. process_token(*(dsv_index_.token_list.begin() + (row.first + index3)),out3);
  5682. }
  5683. }
  5684. return true;
  5685. }
  5686. template <typename OutputIterator0, typename OutputIterator1,
  5687. typename OutputIterator2, typename OutputIterator3,
  5688. typename OutputIterator4>
  5689. inline bool extract_column(const row_range_t& row_range,
  5690. const std::size_t& index0,
  5691. const std::size_t& index1,
  5692. const std::size_t& index2,
  5693. const std::size_t& index3,
  5694. const std::size_t& index4,
  5695. OutputIterator0 out0,
  5696. OutputIterator1 out1,
  5697. OutputIterator2 out2,
  5698. OutputIterator3 out3,
  5699. OutputIterator4 out4) const
  5700. {
  5701. if ((index0 > max_column_count_) ||
  5702. (index1 > max_column_count_) ||
  5703. (index2 > max_column_count_) ||
  5704. (index3 > max_column_count_) ||
  5705. (index4 > max_column_count_))
  5706. return false;
  5707. else if (row_range_invalid(row_range))
  5708. return false;
  5709. std::size_t max_index = std::max(index4,std::max(std::max(index0,index1),std::max(index2,index3)));
  5710. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5711. {
  5712. const row_index_range_t& row = dsv_index_.row_index[i];
  5713. if (max_index < dsv_index_.token_count(row))
  5714. {
  5715. process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0);
  5716. process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1);
  5717. process_token(*(dsv_index_.token_list.begin() + (row.first + index2)),out2);
  5718. process_token(*(dsv_index_.token_list.begin() + (row.first + index3)),out3);
  5719. process_token(*(dsv_index_.token_list.begin() + (row.first + index4)),out4);
  5720. }
  5721. }
  5722. return true;
  5723. }
  5724. inline void remove_row(const std::size_t& index)
  5725. {
  5726. if (index < dsv_index_.row_index.size())
  5727. {
  5728. dsv_index_.remove_row(index);
  5729. }
  5730. }
  5731. template <typename Predicate>
  5732. inline bool remove_row_if(const row_range_t& row_range, Predicate predicate)
  5733. {
  5734. if (row_range_invalid(row_range))
  5735. return false;
  5736. std::size_t removed_token_count = 0;
  5737. std::deque<std::size_t> remove_token_list;
  5738. std::deque<std::size_t> remove_row_list;
  5739. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5740. {
  5741. row_index_range_t& r = dsv_index_.row_index[i];
  5742. std::size_t temp_r_first = r.first - removed_token_count;
  5743. row_type row(i,dsv_index_);
  5744. if (predicate(row))
  5745. {
  5746. remove_row_list.push_back(i);
  5747. for (std::size_t j = r.first; j <= r.second; ++j)
  5748. {
  5749. remove_token_list.push_back(j);
  5750. }
  5751. removed_token_count += row.size();
  5752. }
  5753. r.first = static_cast<unsigned int>(temp_r_first);
  5754. r.second -= static_cast<unsigned int>(removed_token_count);
  5755. }
  5756. for (std::size_t i = row_range.second; i < dsv_index_.row_index.size(); ++i)
  5757. {
  5758. row_index_range_t& r = dsv_index_.row_index[i];
  5759. r.first -= static_cast<unsigned int>(removed_token_count);
  5760. r.second -= static_cast<unsigned int>(removed_token_count);
  5761. }
  5762. if (!remove_row_list.empty())
  5763. {
  5764. remove_inplace(index_remover(remove_row_list),dsv_index_.row_index);
  5765. }
  5766. if (!remove_token_list.empty())
  5767. {
  5768. remove_inplace(index_remover(remove_token_list),dsv_index_.token_list);
  5769. }
  5770. return true;
  5771. }
  5772. template <typename Predicate>
  5773. inline bool remove_row_if(Predicate predicate)
  5774. {
  5775. return remove_row_if(all_rows(),predicate);
  5776. }
  5777. template <typename Predicate>
  5778. inline std::size_t remove_token_if(const row_range_t& row_range, Predicate predicate)
  5779. {
  5780. if (row_range_invalid(row_range))
  5781. return 0;
  5782. std::size_t removed_token_count = 0;
  5783. std::deque<std::size_t> remove_token_list;
  5784. std::deque<std::size_t> remove_row_list;
  5785. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5786. {
  5787. row_index_range_t& r = dsv_index_.row_index[i];
  5788. std::size_t temp_r_first = r.first - removed_token_count;
  5789. row_type row(i,dsv_index_);
  5790. for (std::size_t j = 0; j < row.size(); ++j)
  5791. {
  5792. if (predicate(row.token(j)))
  5793. {
  5794. remove_token_list.push_back(r.first + j);
  5795. ++removed_token_count;
  5796. }
  5797. }
  5798. r.first = static_cast<unsigned int>(temp_r_first);
  5799. r.second -= static_cast<unsigned int>(removed_token_count);
  5800. if (0 == dsv_index_.token_count(r))
  5801. {
  5802. remove_row_list.push_back(i);
  5803. }
  5804. }
  5805. for (std::size_t i = row_range.second; i < dsv_index_.row_index.size(); ++i)
  5806. {
  5807. row_index_range_t& r = dsv_index_.row_index[i];
  5808. r.first -= static_cast<unsigned int>(removed_token_count);
  5809. r.second -= static_cast<unsigned int>(removed_token_count);
  5810. }
  5811. if (!remove_row_list.empty())
  5812. {
  5813. remove_inplace(index_remover(remove_row_list),dsv_index_.row_index);
  5814. }
  5815. if (!remove_token_list.empty())
  5816. {
  5817. remove_inplace(index_remover(remove_token_list),dsv_index_.token_list);
  5818. }
  5819. if (!remove_token_list.empty())
  5820. {
  5821. update_minmax_columns();
  5822. }
  5823. return remove_token_list.size();
  5824. }
  5825. inline std::size_t remove_empty_tokens(const row_range_t& range)
  5826. {
  5827. return remove_token_if(range,is_empty_token());
  5828. }
  5829. inline std::size_t remove_empty_tokens()
  5830. {
  5831. return remove_empty_tokens(all_rows());
  5832. }
  5833. inline void enforce_column_count(const row_range_t& row_range,
  5834. const std::size_t& column_count)
  5835. {
  5836. if (row_range_invalid(row_range))
  5837. return;
  5838. remove_row_if(insufficient_number_of_columns(column_count));
  5839. min_column_count_ = column_count;
  5840. max_column_count_ = column_count;
  5841. }
  5842. inline void enforce_column_count(const std::size_t& column_count)
  5843. {
  5844. enforce_column_count(all_rows(),column_count);
  5845. }
  5846. inline void enforce_min_max_column_count(const row_range_t& row_range,
  5847. const std::size_t& min_column_count,
  5848. const std::size_t& max_column_count)
  5849. {
  5850. if (row_range_invalid(row_range))
  5851. return;
  5852. remove_row_if(insufficient_number_of_minmax_columns(min_column_count,max_column_count));
  5853. min_column_count_ = min_column_count;
  5854. max_column_count_ = max_column_count;
  5855. }
  5856. inline void enforce_min_max_column_count(const std::size_t& min_column_count,
  5857. const std::size_t& max_column_count)
  5858. {
  5859. enforce_min_max_column_count(all_rows(),min_column_count,max_column_count);
  5860. }
  5861. inline void clear(const bool force_delete_buffer = false)
  5862. {
  5863. if (load_from_file_ || force_delete_buffer)
  5864. delete[] buffer_;
  5865. buffer_ = 0;
  5866. buffer_size_ = 0;
  5867. dsv_index_.clear();
  5868. min_column_count_ = 0;
  5869. max_column_count_ = 0;
  5870. state_ = false;
  5871. file_name_ = "";
  5872. }
  5873. inline std::size_t column_width(const std::size_t& col,
  5874. const row_range_t& row_range) const
  5875. {
  5876. if (col > max_column_count_)
  5877. return 0;
  5878. else if (row_range_invalid(row_range))
  5879. return 0;
  5880. std::size_t result = 0;
  5881. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5882. {
  5883. const row_index_range_t& r = dsv_index_.row_index[i];
  5884. if (col < dsv_index_.token_count(r))
  5885. {
  5886. const range_t& range = *(dsv_index_.token_list.begin() + r.first + col);
  5887. result = std::max<std::size_t>(std::distance(range.first,range.second),result);
  5888. }
  5889. }
  5890. return result;
  5891. }
  5892. inline std::size_t column_width(const std::size_t& col) const
  5893. {
  5894. return column_width(col,all_rows());
  5895. }
  5896. template <typename Allocator,
  5897. template <typename,typename> class Sequence>
  5898. inline void get_column_widths(Sequence<std::size_t,Allocator>& columns)
  5899. {
  5900. for (std::size_t c = 0; c < max_column_count(); ++c)
  5901. {
  5902. columns.push_back(column_width(c));
  5903. }
  5904. }
  5905. template <typename Allocator,
  5906. template <typename,typename> class Sequence>
  5907. inline void get_column_widths(Sequence<std::pair<std::size_t,std::size_t>,Allocator>& columns)
  5908. {
  5909. for (std::size_t c = 0; c < max_column_count(); ++c)
  5910. {
  5911. columns.push_back(std::make_pair(c,column_width(c)));
  5912. }
  5913. }
  5914. template <typename T>
  5915. inline std::size_t accumulate_row(const std::size_t& row, T& result) const
  5916. {
  5917. if (row >= dsv_index_.row_index.size())
  5918. return 0;
  5919. const row_index_range_t& r = dsv_index_.row_index[row];
  5920. token_list_t::const_iterator itr = dsv_index_.token_list.begin() + r.first;
  5921. token_list_t::const_iterator end = dsv_index_.token_list.begin() + r.second + 1;
  5922. std::size_t process_count = 0;
  5923. T current_value = T();
  5924. while (end != itr)
  5925. {
  5926. if (string_to_type_converter((*itr).first,(*itr).second,current_value))
  5927. {
  5928. result += current_value;
  5929. ++process_count;
  5930. }
  5931. else
  5932. return 0;
  5933. ++itr;
  5934. }
  5935. return process_count;
  5936. }
  5937. template <typename T>
  5938. inline std::size_t accumulate_column(const std::size_t& col,
  5939. const row_range_t& row_range,
  5940. T& result) const
  5941. {
  5942. if (col > max_column_count_)
  5943. return 0;
  5944. else if (row_range_invalid(row_range))
  5945. return 0;
  5946. std::size_t process_count = 0;
  5947. T current_value = T();
  5948. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5949. {
  5950. const row_index_range_t& r = dsv_index_.row_index[i];
  5951. if (col < dsv_index_.token_count(r))
  5952. {
  5953. const range_t& range = *(dsv_index_.token_list.begin() + r.first + col);
  5954. if (string_to_type_converter(range.first,range.second,current_value))
  5955. result += current_value;
  5956. else
  5957. return 0;
  5958. }
  5959. ++process_count;
  5960. }
  5961. return process_count;
  5962. }
  5963. template <typename T>
  5964. inline std::size_t accumulate_column(const std::size_t& col, T& result) const
  5965. {
  5966. return accumulate_column(col,all_rows(),result);
  5967. }
  5968. template <typename T, typename Predicate>
  5969. inline std::size_t accumulate_column(const std::size_t& col,
  5970. const row_range_t& row_range,
  5971. Predicate p,
  5972. T& result) const
  5973. {
  5974. if (col > max_column_count_)
  5975. return 0;
  5976. else if (row_range_invalid(row_range))
  5977. return 0;
  5978. std::size_t process_count = 0;
  5979. T current_value = T();
  5980. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  5981. {
  5982. const row_index_range_t& r = dsv_index_.row_index[i];
  5983. if (col < dsv_index_.token_count(r))
  5984. {
  5985. row_type row = row_type(i,dsv_index_);
  5986. if (p(row))
  5987. {
  5988. const range_t& range = row.token(col);
  5989. if (string_to_type_converter(range.first,range.second,current_value))
  5990. {
  5991. result += current_value;
  5992. ++process_count;
  5993. }
  5994. else
  5995. return 0;
  5996. }
  5997. }
  5998. }
  5999. return process_count;
  6000. }
  6001. template <typename T, typename Predicate>
  6002. inline std::size_t accumulate_column(const std::size_t& col,
  6003. Predicate p,
  6004. T& result) const
  6005. {
  6006. return accumulate_column(col,all_rows(),p,result);
  6007. }
  6008. inline bool join_row(const std::size_t& row,
  6009. const std::string& delimiter,
  6010. std::string& result)
  6011. {
  6012. if (row >= dsv_index_.row_index.size())
  6013. return false;
  6014. const row_index_range_t& r = dsv_index_.row_index[row];
  6015. token_list_t::const_iterator itr = dsv_index_.token_list.begin() + r.first;
  6016. token_list_t::const_iterator end = dsv_index_.token_list.begin() + r.second + (row < (dsv_index_.row_index.size() - 1) ? 1 : 0);
  6017. result.reserve(delimiter.size() * dsv_index_.token_count(r) + std::distance(itr->first,end->second));
  6018. bool appended = false;
  6019. while (end != itr)
  6020. {
  6021. if (!delimiter.empty() && appended)
  6022. result.append(delimiter);
  6023. appended = false;
  6024. if ((*itr).first != (*itr).second)
  6025. {
  6026. result.append((*itr).first,(*itr).second);
  6027. appended = true;
  6028. }
  6029. ++itr;
  6030. }
  6031. return true;
  6032. }
  6033. template <typename Predicate>
  6034. inline bool join_row(const std::size_t& row,
  6035. Predicate predicate,
  6036. const std::string& delimiter,
  6037. std::string& result)
  6038. {
  6039. if (row >= dsv_index_.row_index.size())
  6040. return false;
  6041. const row_index_range_t& r = dsv_index_.row_index[row];
  6042. token_list_t::const_iterator itr = (dsv_index_.token_list.begin() + r.first);
  6043. token_list_t::const_iterator end = dsv_index_.token_list.begin() + r.second + (row < (dsv_index_.row_index.size() - 1) ? 1 : 0);
  6044. result.reserve(delimiter.size() * dsv_index_.token_count(r) + std::distance(itr->first,end->second));
  6045. bool appended = false;
  6046. while (end != itr)
  6047. {
  6048. if (!delimiter.empty() && appended)
  6049. result.append(delimiter);
  6050. appended = false;
  6051. if ((*itr).first != (*itr).second)
  6052. {
  6053. if (predicate(*itr))
  6054. {
  6055. result.append((*itr).first,(*itr).second);
  6056. appended = true;
  6057. }
  6058. }
  6059. ++itr;
  6060. }
  6061. return true;
  6062. }
  6063. template <typename Predicate>
  6064. inline bool join_row(const std::size_t& row,
  6065. Predicate predicate,
  6066. const char* delimiter,
  6067. std::string& result)
  6068. {
  6069. return join_row(row,predicate,std::string(delimiter),result);
  6070. }
  6071. inline bool join_column(const std::size_t& col,
  6072. const row_range_t& row_range,
  6073. const std::string& delimiter,
  6074. std::string& result) const
  6075. {
  6076. if (col > max_column_count_)
  6077. return false;
  6078. else if (row_range_invalid(row_range))
  6079. return false;
  6080. bool appended = false;
  6081. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  6082. {
  6083. const row_index_range_t& r = dsv_index_.row_index[i];
  6084. if (col < dsv_index_.token_count(r))
  6085. {
  6086. row_type row = row_type(i,dsv_index_);
  6087. const range_t& range = row.token(col);
  6088. if (!delimiter.empty() && appended)
  6089. result.append(delimiter);
  6090. appended = false;
  6091. if (range.first != range.second)
  6092. {
  6093. result.append(range.first,range.second);
  6094. appended = true;
  6095. }
  6096. }
  6097. }
  6098. return true;
  6099. }
  6100. inline bool join_column(const std::size_t& col,
  6101. const std::string& delimiter,
  6102. std::string& result) const
  6103. {
  6104. return join_column(col,all_rows(),delimiter,result);
  6105. }
  6106. template <typename Predicate>
  6107. inline bool join_column(const std::size_t& col,
  6108. const row_range_t& row_range,
  6109. Predicate predicate,
  6110. const std::string& delimiter,
  6111. std::string& result) const
  6112. {
  6113. if (col > max_column_count_)
  6114. return false;
  6115. else if (row_range_invalid(row_range))
  6116. return false;
  6117. bool appended = false;
  6118. const std::size_t pre_end_index = row_range.second - 1;
  6119. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  6120. {
  6121. const row_index_range_t& r = dsv_index_.row_index[i];
  6122. if (col < dsv_index_.token_count(r))
  6123. {
  6124. row_type row = row_type(i,dsv_index_);
  6125. const range_t& range = row.token(col);
  6126. if (!delimiter.empty() && appended && (pre_end_index != i))
  6127. result.append(delimiter);
  6128. appended = false;
  6129. if (range.first != range.second)
  6130. {
  6131. if (predicate(row))
  6132. {
  6133. result.append(range.first,range.second);
  6134. appended = true;
  6135. }
  6136. }
  6137. }
  6138. }
  6139. return true;
  6140. }
  6141. template <typename Predicate>
  6142. inline bool join_column(const std::size_t& col,
  6143. Predicate p,
  6144. const std::string& delimiter,
  6145. std::string& result) const
  6146. {
  6147. return join_column(col,all_rows(),p,delimiter,result);
  6148. }
  6149. template <typename TransitionPredicate, typename Function>
  6150. inline bool sequential_partition(const row_range_t& row_range,
  6151. TransitionPredicate p,
  6152. Function f)
  6153. {
  6154. if (row_range_invalid(row_range))
  6155. return false;
  6156. row_range_t r(row_range.first,row_range.first);
  6157. for (row_range_t::first_type i = row_range.first; i < row_range.second; ++i)
  6158. {
  6159. if (p(row_type(i,dsv_index_)))
  6160. {
  6161. if (r.first != r.second)
  6162. {
  6163. r.second = i;
  6164. if (!f(*this,r))
  6165. return false;
  6166. }
  6167. r.first = r.second;
  6168. }
  6169. else
  6170. r.second = i;
  6171. }
  6172. if (r.first != row_range.second)
  6173. {
  6174. r.second = row_range.second;
  6175. if (!f(*this,r))
  6176. return false;
  6177. }
  6178. return true;
  6179. }
  6180. template <typename TransitionPredicate, typename Function>
  6181. inline bool sequential_partition(TransitionPredicate p, Function f)
  6182. {
  6183. return sequential_partition(all_rows(),p,f);
  6184. }
  6185. static inline token_grid::options default_options()
  6186. {
  6187. return options();
  6188. }
  6189. template <typename Function>
  6190. inline std::size_t for_each_row(const row_range_t& row_range, Function f) const
  6191. {
  6192. if (row_range_invalid(row_range))
  6193. return 0;
  6194. std::size_t row_count = 0;
  6195. for (std::size_t i = row_range.first; i < row_range.second; ++i)
  6196. {
  6197. f(row_type(i,dsv_index_));
  6198. ++row_count;
  6199. }
  6200. return row_count;
  6201. }
  6202. template <typename Function>
  6203. inline std::size_t for_each_row(Function f) const
  6204. {
  6205. return for_each_row(all_rows(),f);
  6206. }
  6207. bool load(const std::string& file_name,
  6208. const token_grid::options& options)
  6209. {
  6210. file_name_ = file_name;
  6211. if ((load_from_file_) && (0 != buffer_))
  6212. {
  6213. delete [] buffer_;
  6214. buffer_ = 0;
  6215. }
  6216. buffer_size_ = 0;
  6217. min_column_count_ = 0;
  6218. max_column_count_ = 0;
  6219. options_ = options;
  6220. load_from_file_ = true;
  6221. state_ = load();
  6222. if (state_)
  6223. return true;
  6224. else
  6225. {
  6226. file_name_ = "";
  6227. if ((load_from_file_) && (0 != buffer_))
  6228. {
  6229. delete [] buffer_;
  6230. buffer_ = 0;
  6231. }
  6232. return false;
  6233. }
  6234. }
  6235. bool load(unsigned char* buffer,
  6236. const std::size_t buffer_size,
  6237. const token_grid::options& options)
  6238. {
  6239. file_name_ = "";
  6240. if ((load_from_file_) && (0 != buffer_))
  6241. {
  6242. delete [] buffer_;
  6243. buffer_ = 0;
  6244. }
  6245. min_column_count_ = 0;
  6246. max_column_count_ = 0;
  6247. options_ = options;
  6248. load_from_file_ = false;
  6249. buffer_ = buffer;
  6250. buffer_size_ = buffer_size;
  6251. state_ = load();
  6252. if (state_)
  6253. return true;
  6254. else
  6255. {
  6256. file_name_ = "";
  6257. if ((load_from_file_) && (0 != buffer_))
  6258. {
  6259. delete [] buffer_;
  6260. buffer_ = 0;
  6261. }
  6262. return false;
  6263. }
  6264. }
  6265. private:
  6266. token_grid(const token_grid& tg);
  6267. token_grid& operator=(const token_grid& tg);
  6268. struct is_empty_token
  6269. {
  6270. inline bool operator()(const range_t& r) const
  6271. {
  6272. return r.first == r.second;
  6273. }
  6274. };
  6275. struct insufficient_number_of_columns
  6276. {
  6277. insufficient_number_of_columns(const std::size_t& noc)
  6278. : num_of_cols(noc)
  6279. {}
  6280. inline bool operator()(const row_type& row) const
  6281. {
  6282. return (num_of_cols != row.size());
  6283. }
  6284. std::size_t num_of_cols;
  6285. };
  6286. struct insufficient_number_of_minmax_columns
  6287. {
  6288. insufficient_number_of_minmax_columns(const std::size_t& min_col, const std::size_t& max_col)
  6289. : min_column_count(min_col),
  6290. max_column_count(max_col)
  6291. {}
  6292. inline bool operator()(const row_type& row) const
  6293. {
  6294. return (row.size() < min_column_count) || (max_column_count < row.size());
  6295. }
  6296. std::size_t min_column_count;
  6297. std::size_t max_column_count;
  6298. };
  6299. class double_quotes_predicate
  6300. {
  6301. public:
  6302. double_quotes_predicate(const std::string& delimiters)
  6303. : in_bracket_range_(false),
  6304. mdp_(delimiters)
  6305. {}
  6306. inline bool operator()(const unsigned char c) const
  6307. {
  6308. if ('"' == c)
  6309. {
  6310. in_bracket_range_ = !in_bracket_range_;
  6311. return false;
  6312. }
  6313. else if (in_bracket_range_)
  6314. return false;
  6315. else
  6316. return mdp_(c);
  6317. }
  6318. inline void reset()
  6319. {
  6320. in_bracket_range_ = false;
  6321. }
  6322. private:
  6323. mutable bool in_bracket_range_;
  6324. mutable strtk::multiple_char_delimiter_predicate mdp_;
  6325. };
  6326. inline bool load()
  6327. {
  6328. if (load_from_file_ && !load_buffer_from_file())
  6329. return false;
  6330. dsv_index_.token_list.clear();
  6331. dsv_index_.row_index.clear();
  6332. multiple_char_delimiter_predicate text_newline_predicate(options_.row_delimiters);
  6333. if (!options_.support_dquotes)
  6334. {
  6335. multiple_char_delimiter_predicate token_predicate(options_.column_delimiters);
  6336. strtk::split(text_newline_predicate,
  6337. buffer_, buffer_ + buffer_size_,
  6338. strtk::functional_inserter(
  6339. row_processor<multiple_char_delimiter_predicate>(dsv_index_,token_predicate,options_.column_split_option)),
  6340. strtk::split_options::compress_delimiters);
  6341. }
  6342. else
  6343. {
  6344. double_quotes_predicate token_predicate_dblq(options_.column_delimiters);
  6345. strtk::split(text_newline_predicate,
  6346. buffer_, buffer_ + buffer_size_,
  6347. strtk::functional_inserter(
  6348. row_processor<double_quotes_predicate>(dsv_index_,token_predicate_dblq,options_.column_split_option)),
  6349. strtk::split_options::compress_delimiters);
  6350. if (options_.trim_dquotes)
  6351. {
  6352. for (std::size_t i = 0; i < dsv_index_.token_list.size(); ++i)
  6353. {
  6354. if (
  6355. ((*(dsv_index_.token_list[i].first )) == '"') &&
  6356. ((*(dsv_index_.token_list[i].second - 1)) == '"')
  6357. )
  6358. {
  6359. ++dsv_index_.token_list[i].first;
  6360. --dsv_index_.token_list[i].second;
  6361. }
  6362. }
  6363. }
  6364. }
  6365. update_minmax_columns();
  6366. return true;
  6367. }
  6368. inline bool load_buffer_from_file()
  6369. {
  6370. std::ifstream stream(file_name_.c_str(),std::ios::binary);
  6371. if (!stream)
  6372. return false;
  6373. stream.seekg (0,std::ios::end);
  6374. buffer_size_ = static_cast<std::size_t>(stream.tellg());
  6375. if (0 == buffer_size_)
  6376. return false;
  6377. stream.seekg (0,std::ios::beg);
  6378. buffer_ = new unsigned char[buffer_size_];
  6379. stream.read(reinterpret_cast<char*>(buffer_),static_cast<std::streamsize>(buffer_size_));
  6380. stream.close();
  6381. return true;
  6382. }
  6383. template <typename OutputIterator>
  6384. inline void process_token(const range_t& range, OutputIterator out) const
  6385. {
  6386. typedef typename std::iterator_traits<OutputIterator>::value_type output_type;
  6387. (*out) = string_to_type_converter<output_type>(range.first,range.second);
  6388. ++out;
  6389. }
  6390. template <typename OutputIterator>
  6391. inline void process_token_checked(const range_t& range, OutputIterator out) const
  6392. {
  6393. typedef typename std::iterator_traits<OutputIterator>::value_type output_type;
  6394. output_type value;
  6395. if (string_to_type_converter(range.first,range.second,value))
  6396. {
  6397. (*out) = value;
  6398. ++out;
  6399. }
  6400. }
  6401. inline bool row_range_invalid(const row_range_t& row_range) const
  6402. {
  6403. if (row_range.first > dsv_index_.row_index.size())
  6404. return true;
  6405. else if (row_range.second > dsv_index_.row_index.size())
  6406. return true;
  6407. else if (row_range.first > row_range.second)
  6408. return true;
  6409. else
  6410. return false;
  6411. }
  6412. inline void update_minmax_columns()
  6413. {
  6414. min_column_count_ = std::numeric_limits<std::size_t>::max();
  6415. max_column_count_ = std::numeric_limits<std::size_t>::min();
  6416. for (std::size_t i = 0; i < dsv_index_.row_index.size(); ++i)
  6417. {
  6418. const row_index_range_t& r = dsv_index_.row_index[i];
  6419. const std::size_t number_of_tokens = dsv_index_.token_count(r);
  6420. if (number_of_tokens > max_column_count_)
  6421. max_column_count_ = number_of_tokens;
  6422. if (number_of_tokens < min_column_count_)
  6423. min_column_count_ = number_of_tokens;
  6424. }
  6425. }
  6426. private:
  6427. store dsv_index_;
  6428. std::string file_name_;
  6429. unsigned char* buffer_;
  6430. std::size_t buffer_size_;
  6431. std::size_t min_column_count_;
  6432. std::size_t max_column_count_;
  6433. options options_;
  6434. bool load_from_file_;
  6435. bool state_;
  6436. };
  6437. template <typename T>
  6438. inline bool convert_string_range(const std::pair<std::string::const_iterator,std::string::const_iterator>& range, T& t)
  6439. {
  6440. if (range.first == range.second) return false;
  6441. t = string_to_type_converter<T>(std::string(range.first,range.second));
  6442. return true;
  6443. }
  6444. struct empty_range
  6445. {
  6446. public:
  6447. template <typename InputIterator>
  6448. inline bool operator()(const InputIterator begin, const InputIterator end)
  6449. {
  6450. return (0 == std::distance(begin,end));
  6451. }
  6452. };
  6453. struct nonempty_range
  6454. {
  6455. public:
  6456. template <typename InputIterator>
  6457. inline bool operator()(const InputIterator begin, const InputIterator end)
  6458. {
  6459. return (0 != std::distance(begin,end));
  6460. }
  6461. };
  6462. template <typename OutputIterator>
  6463. struct filter_non_empty_range
  6464. {
  6465. public:
  6466. filter_non_empty_range(OutputIterator out)
  6467. : out_(out)
  6468. {}
  6469. template <typename Iterator>
  6470. inline void operator() (const std::pair<Iterator,Iterator>& range)
  6471. {
  6472. if (range.first != range.second)
  6473. {
  6474. *out_++ = range;
  6475. }
  6476. }
  6477. private:
  6478. OutputIterator out_;
  6479. };
  6480. template <typename OutputPredicate>
  6481. struct filter_on_wildcard_match
  6482. {
  6483. public:
  6484. filter_on_wildcard_match(const std::string& match_pattern,
  6485. OutputPredicate& predicate,
  6486. bool allow_through_on_match = true)
  6487. : allow_through_on_match_(allow_through_on_match),
  6488. match_pattern_(match_pattern),
  6489. predicate_(predicate)
  6490. {}
  6491. template <typename Iterator>
  6492. inline void operator() (const std::pair<Iterator,Iterator>& range) const
  6493. {
  6494. if (match(match_pattern_.begin(),match_pattern_.end(),range.first,range.second,'*','?') ^ allow_through_on_match_)
  6495. {
  6496. predicate_(range);
  6497. }
  6498. }
  6499. inline void operator() (const std::string& s) const
  6500. {
  6501. if (match(match_pattern_,s) ^ allow_through_on_match_)
  6502. {
  6503. predicate_(s);
  6504. }
  6505. }
  6506. private:
  6507. filter_on_wildcard_match(const filter_on_wildcard_match& fom);
  6508. filter_on_wildcard_match& operator=(const filter_on_wildcard_match& fom);
  6509. bool allow_through_on_match_;
  6510. std::string match_pattern_;
  6511. OutputPredicate& predicate_;
  6512. };
  6513. template <typename OutputPredicate>
  6514. struct filter_on_match
  6515. {
  6516. public:
  6517. filter_on_match(const std::string* begin, const std::string* end,
  6518. OutputPredicate predicate,
  6519. bool case_insensitive,
  6520. bool allow_through_on_match = true)
  6521. : case_insensitive_(case_insensitive),
  6522. allow_through_on_match_(allow_through_on_match),
  6523. begin_(begin),
  6524. end_(end),
  6525. predicate_(predicate)
  6526. {}
  6527. template <typename Iterator>
  6528. inline void operator() (const std::pair<Iterator,Iterator>& range) const
  6529. {
  6530. for (const std::string* itr = begin_; end_ != itr; ++itr)
  6531. {
  6532. if (
  6533. (case_insensitive_ &&
  6534. (imatch((*itr).data(),(*itr).data() + (*itr).size(),range.first,range.second))) ||
  6535. (!case_insensitive_ && std::equal((*itr).begin(),(*itr).end(),range.first))
  6536. )
  6537. {
  6538. if (allow_through_on_match_)
  6539. {
  6540. predicate_(range);
  6541. }
  6542. return;
  6543. }
  6544. }
  6545. if (!allow_through_on_match_)
  6546. {
  6547. predicate_(range);
  6548. }
  6549. }
  6550. inline void operator() (const std::string& s) const
  6551. {
  6552. for (const std::string* itr = begin_; end_ != itr; ++itr)
  6553. {
  6554. if (
  6555. (case_insensitive_ &&
  6556. (imatch((*itr).begin(),(*itr).end(),s.begin(),s.end()))) ||
  6557. (!case_insensitive_ && std::equal((*itr).begin(),(*itr).end(),s.begin()))
  6558. )
  6559. {
  6560. if (allow_through_on_match_)
  6561. {
  6562. predicate_(s);
  6563. return;
  6564. }
  6565. }
  6566. }
  6567. if (!allow_through_on_match_)
  6568. {
  6569. predicate_(s);
  6570. return;
  6571. }
  6572. }
  6573. private:
  6574. filter_on_match& operator=(const filter_on_match& fom);
  6575. private:
  6576. bool case_insensitive_;
  6577. bool allow_through_on_match_;
  6578. const std::string* begin_;
  6579. const std::string* end_;
  6580. OutputPredicate predicate_;
  6581. };
  6582. template <typename Iterator, typename MatchPredicate>
  6583. inline void skip_while_matching(Iterator& itr,
  6584. const Iterator& end,
  6585. const MatchPredicate& predicate)
  6586. {
  6587. while (end != itr)
  6588. {
  6589. if (predicate(*itr))
  6590. ++itr;
  6591. else
  6592. break;
  6593. }
  6594. }
  6595. template <std::size_t length>
  6596. struct size_equal_to
  6597. {
  6598. template <typename Iterator>
  6599. inline bool operator()(const Iterator begin, const Iterator end) const
  6600. {
  6601. return length == std::distance(begin,end);
  6602. }
  6603. template <typename Iterator>
  6604. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6605. {
  6606. return length == std::distance(range.first,range.second);
  6607. }
  6608. template <typename T,
  6609. typename Allocator,
  6610. template <typename,typename> class Sequence>
  6611. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6612. {
  6613. return length == sequence.size();
  6614. }
  6615. template <typename T,
  6616. typename Comparator,
  6617. typename Allocator>
  6618. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6619. {
  6620. return length == set.size();
  6621. }
  6622. template <typename T,
  6623. typename Comparator,
  6624. typename Allocator>
  6625. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6626. {
  6627. return length == multiset.size();
  6628. }
  6629. inline bool operator()(const std::string& str) const
  6630. {
  6631. return length == str.size();
  6632. }
  6633. };
  6634. template <std::size_t length>
  6635. struct size_less_than
  6636. {
  6637. template <typename Iterator>
  6638. inline bool operator()(const Iterator begin, const Iterator end) const
  6639. {
  6640. return std::distance(begin,end) < static_cast<typename std::iterator_traits<Iterator>::difference_type>(length);
  6641. }
  6642. template <typename Iterator>
  6643. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6644. {
  6645. return std::distance(range.first,range.second) < static_cast<typename std::iterator_traits<Iterator>::difference_type>(length);
  6646. }
  6647. template <typename T,
  6648. typename Allocator,
  6649. template <typename,typename> class Sequence>
  6650. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6651. {
  6652. return sequence.size() < length;
  6653. }
  6654. template <typename T,
  6655. typename Comparator,
  6656. typename Allocator>
  6657. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6658. {
  6659. return set.size() < length;
  6660. }
  6661. template <typename T,
  6662. typename Comparator,
  6663. typename Allocator>
  6664. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6665. {
  6666. return multiset.size() < length;
  6667. }
  6668. inline bool operator()(const std::string& str) const
  6669. {
  6670. return str.size() < length;
  6671. }
  6672. };
  6673. template <std::size_t length>
  6674. struct size_greater_than
  6675. {
  6676. template <typename Iterator>
  6677. inline bool operator()(const Iterator begin, const Iterator end) const
  6678. {
  6679. return std::distance(begin,end) > static_cast<typename std::iterator_traits<Iterator>::difference_type>(length);
  6680. }
  6681. template <typename Iterator>
  6682. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6683. {
  6684. return std::distance(range.first,range.second) > static_cast<typename std::iterator_traits<Iterator>::difference_type>(length);
  6685. }
  6686. template <typename T,
  6687. typename Allocator,
  6688. template <typename,typename> class Sequence>
  6689. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6690. {
  6691. return sequence.size() > length;
  6692. }
  6693. template <typename T,
  6694. typename Comparator,
  6695. typename Allocator>
  6696. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6697. {
  6698. return set.size() > length;
  6699. }
  6700. template <typename T,
  6701. typename Comparator,
  6702. typename Allocator>
  6703. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6704. {
  6705. return multiset.size() > length;
  6706. }
  6707. inline bool operator()(const std::string& str) const
  6708. {
  6709. return str.size() > length;
  6710. }
  6711. };
  6712. struct size_is_even
  6713. {
  6714. template <typename Iterator>
  6715. inline bool operator()(const Iterator begin, const Iterator end) const
  6716. {
  6717. return 0 == (std::distance(begin,end) % 2);
  6718. }
  6719. template <typename Iterator>
  6720. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6721. {
  6722. return 0 == (std::distance(range.first,range.second) % 2);
  6723. }
  6724. template <typename T,
  6725. typename Allocator,
  6726. template <typename,typename> class Sequence>
  6727. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6728. {
  6729. return 0 == (sequence.size() % 2);
  6730. }
  6731. template <typename T,
  6732. typename Comparator,
  6733. typename Allocator>
  6734. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6735. {
  6736. return 0 == (set.size() % 2);
  6737. }
  6738. template <typename T,
  6739. typename Comparator,
  6740. typename Allocator>
  6741. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6742. {
  6743. return 0 == (multiset.size() % 2);
  6744. }
  6745. inline bool operator()(const std::string& str) const
  6746. {
  6747. return 0 == (str.size() % 2);
  6748. }
  6749. };
  6750. struct size_is_odd
  6751. {
  6752. template <typename Iterator>
  6753. inline bool operator()(const Iterator begin, const Iterator end) const
  6754. {
  6755. return 0 != (std::distance(begin,end) % 2);
  6756. }
  6757. template <typename Iterator>
  6758. inline bool operator()(const std::pair<Iterator,Iterator>& range) const
  6759. {
  6760. return 0 != (std::distance(range.first,range.second) % 2);
  6761. }
  6762. template <typename T,
  6763. typename Allocator,
  6764. template <typename,typename> class Sequence>
  6765. inline bool operator()(const Sequence<T,Allocator>& sequence) const
  6766. {
  6767. return 0 != (sequence.size() % 2);
  6768. }
  6769. template <typename T,
  6770. typename Comparator,
  6771. typename Allocator>
  6772. inline bool operator()(const std::set<T,Comparator,Allocator>& set) const
  6773. {
  6774. return 0 != (set.size() % 2);
  6775. }
  6776. template <typename T,
  6777. typename Comparator,
  6778. typename Allocator>
  6779. inline bool operator()(const std::multiset<T,Comparator,Allocator>& multiset) const
  6780. {
  6781. return 0 != (multiset.size() % 2);
  6782. }
  6783. inline bool operator()(const std::string& str) const
  6784. {
  6785. return 0 != (str.size() % 2);
  6786. }
  6787. };
  6788. template <typename InputIterator,
  6789. typename T1, typename T2, typename T3, typename T4,
  6790. typename T5, typename T6, typename T7, typename T8,
  6791. typename T9, typename T10, typename T11, typename T12>
  6792. inline bool parse(const InputIterator begin,
  6793. const InputIterator end,
  6794. const std::string& delimiters,
  6795. T1& t1, T2& t2, T3& t3, T4& t4,
  6796. T5& t5, T6& t6, T7& t7, T8& t8,
  6797. T9& t9, T10& t10, T11& t11, T12& t12)
  6798. {
  6799. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6800. details::convert_type_assert<itr_type>();
  6801. static const std::size_t token_count = 12;
  6802. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6803. typedef iterator_type* iterator_type_ptr;
  6804. iterator_type token_list[token_count];
  6805. const std::size_t parsed_token_count = split_n(delimiters,
  6806. begin,end,
  6807. token_count,
  6808. token_list,
  6809. split_options::compress_delimiters);
  6810. if (token_count > parsed_token_count)
  6811. return false;
  6812. iterator_type_ptr itr = token_list;
  6813. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  6814. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  6815. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  6816. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  6817. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  6818. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  6819. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  6820. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  6821. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  6822. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr;
  6823. if (!string_to_type_converter((*itr).first,(*itr).second,t11)) return false; ++itr;
  6824. if (!string_to_type_converter((*itr).first,(*itr).second,t12)) return false;
  6825. return true;
  6826. }
  6827. template <typename InputIterator,
  6828. typename T1, typename T2, typename T3, typename T4,
  6829. typename T5, typename T6, typename T7, typename T8,
  6830. typename T9, typename T10, typename T11>
  6831. inline bool parse(const InputIterator begin,
  6832. const InputIterator end,
  6833. const std::string& delimiters,
  6834. T1& t1, T2& t2, T3& t3, T4& t4,
  6835. T5& t5, T6& t6, T7& t7, T8& t8,
  6836. T9& t9, T10& t10, T11& t11)
  6837. {
  6838. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6839. details::convert_type_assert<itr_type>();
  6840. static const std::size_t token_count = 11;
  6841. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6842. typedef iterator_type* iterator_type_ptr;
  6843. iterator_type token_list[token_count];
  6844. const std::size_t parsed_token_count = split_n(delimiters,
  6845. begin,end,
  6846. token_count,
  6847. token_list,
  6848. split_options::compress_delimiters);
  6849. if (token_count > parsed_token_count)
  6850. return false;
  6851. iterator_type_ptr itr = token_list;
  6852. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  6853. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  6854. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  6855. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  6856. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  6857. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  6858. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  6859. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  6860. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  6861. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr;
  6862. if (!string_to_type_converter((*itr).first,(*itr).second,t11)) return false;
  6863. return true;
  6864. }
  6865. template <typename InputIterator,
  6866. typename T1, typename T2, typename T3, typename T4,
  6867. typename T5, typename T6, typename T7, typename T8,
  6868. typename T9, typename T10>
  6869. inline bool parse(const InputIterator begin,
  6870. const InputIterator end,
  6871. const std::string& delimiters,
  6872. T1& t1, T2& t2, T3& t3, T4& t4,
  6873. T5& t5, T6& t6, T7& t7, T8& t8,
  6874. T9& t9, T10& t10)
  6875. {
  6876. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6877. details::convert_type_assert<itr_type>();
  6878. static const std::size_t token_count = 10;
  6879. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6880. typedef iterator_type* iterator_type_ptr;
  6881. iterator_type token_list[token_count];
  6882. const std::size_t parsed_token_count = split_n(delimiters,
  6883. begin,end,
  6884. token_count,
  6885. token_list,
  6886. split_options::compress_delimiters);
  6887. if (token_count > parsed_token_count)
  6888. return false;
  6889. iterator_type_ptr itr = token_list;
  6890. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  6891. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  6892. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  6893. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  6894. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  6895. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  6896. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  6897. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  6898. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  6899. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false;
  6900. return true;
  6901. }
  6902. template <typename InputIterator,
  6903. typename T1, typename T2, typename T3, typename T4,
  6904. typename T5, typename T6, typename T7, typename T8,
  6905. typename T9>
  6906. inline bool parse(const InputIterator begin,
  6907. const InputIterator end,
  6908. const std::string& delimiters,
  6909. T1& t1, T2& t2, T3& t3, T4& t4,
  6910. T5& t5, T6& t6, T7& t7, T8& t8,
  6911. T9& t9)
  6912. {
  6913. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6914. details::convert_type_assert<itr_type>();
  6915. static const std::size_t token_count = 9;
  6916. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6917. typedef iterator_type* iterator_type_ptr;
  6918. iterator_type token_list[token_count];
  6919. const std::size_t parsed_token_count = split_n(delimiters,
  6920. begin,end,
  6921. token_count,
  6922. token_list,
  6923. split_options::compress_delimiters);
  6924. if (token_count > parsed_token_count)
  6925. return false;
  6926. iterator_type_ptr itr = token_list;
  6927. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6928. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  6929. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  6930. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  6931. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  6932. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  6933. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  6934. if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false; ++itr;
  6935. if (!string_to_type_converter((*itr).first,(*itr).second,t9)) return false;
  6936. return true;
  6937. }
  6938. template <typename InputIterator,
  6939. typename T1, typename T2, typename T3, typename T4,
  6940. typename T5, typename T6, typename T7, typename T8>
  6941. inline bool parse(const InputIterator begin,
  6942. const InputIterator end,
  6943. const std::string& delimiters,
  6944. T1& t1, T2& t2, T3& t3, T4& t4,
  6945. T5& t5, T6& t6, T7& t7, T8& t8)
  6946. {
  6947. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6948. details::convert_type_assert<itr_type>();
  6949. static const std::size_t token_count = 8;
  6950. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6951. typedef iterator_type* iterator_type_ptr;
  6952. iterator_type token_list[token_count];
  6953. const std::size_t parsed_token_count = split_n(delimiters,
  6954. begin,end,
  6955. token_count,
  6956. token_list,
  6957. split_options::compress_delimiters);
  6958. if (token_count > parsed_token_count)
  6959. return false;
  6960. iterator_type_ptr itr = token_list;
  6961. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6962. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  6963. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  6964. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  6965. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  6966. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  6967. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  6968. if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false;
  6969. return true;
  6970. }
  6971. template <typename InputIterator,
  6972. typename T1, typename T2, typename T3, typename T4,
  6973. typename T5, typename T6, typename T7>
  6974. inline bool parse(const InputIterator begin,
  6975. const InputIterator end,
  6976. const std::string& delimiters,
  6977. T1& t1, T2& t2, T3& t3, T4& t4,
  6978. T5& t5, T6& t6, T7& t7)
  6979. {
  6980. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  6981. details::convert_type_assert<itr_type>();
  6982. static const std::size_t token_count = 7;
  6983. typedef std::pair<InputIterator,InputIterator> iterator_type;
  6984. typedef iterator_type* iterator_type_ptr;
  6985. iterator_type token_list[token_count];
  6986. const std::size_t parsed_token_count = split_n(delimiters,
  6987. begin,end,
  6988. token_count,
  6989. token_list,
  6990. split_options::compress_delimiters);
  6991. if (token_count > parsed_token_count)
  6992. return false;
  6993. iterator_type_ptr itr = token_list;
  6994. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  6995. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  6996. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  6997. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  6998. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  6999. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7000. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false;
  7001. return true;
  7002. }
  7003. template <typename InputIterator,
  7004. typename T1, typename T2, typename T3, typename T4,
  7005. typename T5, typename T6>
  7006. inline bool parse(const InputIterator begin,
  7007. const InputIterator end,
  7008. const std::string& delimiters,
  7009. T1& t1, T2& t2, T3& t3, T4& t4,
  7010. T5& t5, T6& t6)
  7011. {
  7012. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7013. details::convert_type_assert<itr_type>();
  7014. static const std::size_t token_count = 6;
  7015. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7016. typedef iterator_type* iterator_type_ptr;
  7017. iterator_type token_list[token_count];
  7018. const std::size_t parsed_token_count = split_n(delimiters,
  7019. begin,end,
  7020. token_count,
  7021. token_list,
  7022. split_options::compress_delimiters);
  7023. if (token_count > parsed_token_count)
  7024. return false;
  7025. iterator_type_ptr itr = token_list;
  7026. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7027. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7028. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7029. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7030. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7031. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false;
  7032. return true;
  7033. }
  7034. template <typename InputIterator,
  7035. typename T1, typename T2, typename T3, typename T4,
  7036. typename T5>
  7037. inline bool parse(const InputIterator begin,
  7038. const InputIterator end,
  7039. const std::string& delimiters,
  7040. T1& t1, T2& t2, T3& t3, T4& t4,
  7041. T5& t5)
  7042. {
  7043. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7044. details::convert_type_assert<itr_type>();
  7045. static const std::size_t token_count = 5;
  7046. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7047. typedef iterator_type* iterator_type_ptr;
  7048. iterator_type token_list[token_count];
  7049. const std::size_t parsed_token_count = split_n(delimiters,
  7050. begin,end,
  7051. token_count,
  7052. token_list,
  7053. split_options::compress_delimiters);
  7054. if (token_count > parsed_token_count)
  7055. return false;
  7056. iterator_type_ptr itr = token_list;
  7057. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7058. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7059. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7060. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7061. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false;
  7062. return true;
  7063. }
  7064. template <typename InputIterator,
  7065. typename T1, typename T2, typename T3, typename T4>
  7066. inline bool parse(const InputIterator begin,
  7067. const InputIterator end,
  7068. const std::string& delimiters,
  7069. T1& t1, T2& t2, T3& t3, T4& t4)
  7070. {
  7071. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7072. details::convert_type_assert<itr_type>();
  7073. static const std::size_t token_count = 4;
  7074. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7075. typedef iterator_type* iterator_type_ptr;
  7076. iterator_type token_list[token_count];
  7077. const std::size_t parsed_token_count = split_n(delimiters,
  7078. begin,end,
  7079. token_count,
  7080. token_list,
  7081. split_options::compress_delimiters);
  7082. if (token_count > parsed_token_count)
  7083. return false;
  7084. iterator_type_ptr itr = token_list;
  7085. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7086. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7087. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7088. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false;
  7089. return true;
  7090. }
  7091. template <typename InputIterator,
  7092. typename T1, typename T2, typename T3>
  7093. inline bool parse(const InputIterator begin,
  7094. const InputIterator end,
  7095. const std::string& delimiters,
  7096. T1& t1, T2& t2, T3& t3)
  7097. {
  7098. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7099. details::convert_type_assert<itr_type>();
  7100. static const std::size_t token_count = 3;
  7101. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7102. typedef iterator_type* iterator_type_ptr;
  7103. iterator_type token_list[token_count];
  7104. const std::size_t parsed_token_count = split_n(delimiters,
  7105. begin,end,
  7106. token_count,
  7107. token_list,
  7108. split_options::compress_delimiters);
  7109. if (token_count > parsed_token_count)
  7110. return false;
  7111. iterator_type_ptr itr = token_list;
  7112. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7113. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7114. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false;
  7115. return true;
  7116. }
  7117. template <typename InputIterator, typename T1, typename T2>
  7118. inline bool parse(const InputIterator begin,
  7119. const InputIterator end,
  7120. const std::string& delimiters,
  7121. T1& t1, T2& t2)
  7122. {
  7123. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7124. details::convert_type_assert<itr_type>();
  7125. static const std::size_t token_count = 2;
  7126. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7127. typedef iterator_type* iterator_type_ptr;
  7128. iterator_type token_list[token_count];
  7129. const std::size_t parsed_token_count = split_n(delimiters,
  7130. begin,end,
  7131. token_count,
  7132. token_list,
  7133. split_options::compress_delimiters);
  7134. if (token_count > parsed_token_count)
  7135. return false;
  7136. iterator_type_ptr itr = token_list;
  7137. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7138. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false;
  7139. return true;
  7140. }
  7141. template <typename InputIterator, typename T>
  7142. inline bool parse(const InputIterator begin,
  7143. const InputIterator end,
  7144. const std::string& delimiters,
  7145. T& t)
  7146. {
  7147. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7148. details::convert_type_assert<itr_type>();
  7149. static const std::size_t token_count = 1;
  7150. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7151. typedef iterator_type* iterator_type_ptr;
  7152. iterator_type token_list[token_count];
  7153. const std::size_t parsed_token_count = split_n(delimiters,
  7154. begin,end,
  7155. token_count,
  7156. token_list,
  7157. split_options::compress_delimiters);
  7158. if (token_count > parsed_token_count)
  7159. return false;
  7160. iterator_type_ptr itr = token_list;
  7161. return string_to_type_converter((*itr).first,(*itr).second,t);
  7162. }
  7163. template <typename InputIterator,
  7164. typename T,
  7165. typename Allocator,
  7166. template <typename,typename> class Sequence>
  7167. inline std::size_t parse(const InputIterator begin,
  7168. const InputIterator end,
  7169. const std::string& delimiters,
  7170. Sequence<T,Allocator>& sequence,
  7171. const split_options::type& split_option = split_options::compress_delimiters)
  7172. {
  7173. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7174. details::convert_type_assert<itr_type>();
  7175. if (1 == delimiters.size())
  7176. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7177. begin,end,
  7178. range_to_type_back_inserter(sequence),
  7179. split_option);
  7180. else
  7181. return split(multiple_char_delimiter_predicate(delimiters),
  7182. begin, end,
  7183. range_to_type_back_inserter(sequence),
  7184. split_option);
  7185. }
  7186. template <typename InputIterator,
  7187. typename T,
  7188. typename Comparator,
  7189. typename Allocator>
  7190. inline std::size_t parse(const InputIterator begin,
  7191. const InputIterator end,
  7192. const std::string& delimiters,
  7193. std::set<T,Comparator,Allocator>& set,
  7194. const split_options::type& split_option = split_options::compress_delimiters)
  7195. {
  7196. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7197. details::convert_type_assert<itr_type>();
  7198. if (1 == delimiters.size())
  7199. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7200. begin,end,
  7201. range_to_type_inserter(set),
  7202. split_option);
  7203. else
  7204. return split(multiple_char_delimiter_predicate(delimiters),
  7205. begin,end,
  7206. range_to_type_inserter(set),
  7207. split_option);
  7208. }
  7209. template <typename InputIterator,
  7210. typename T,
  7211. typename Comparator,
  7212. typename Allocator>
  7213. inline std::size_t parse(const InputIterator begin,
  7214. const InputIterator end,
  7215. const std::string& delimiters,
  7216. std::multiset<T,Comparator,Allocator>& multiset,
  7217. const split_options::type& split_option = split_options::compress_delimiters)
  7218. {
  7219. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7220. details::convert_type_assert<itr_type>();
  7221. if (1 == delimiters.size())
  7222. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7223. begin,end,
  7224. range_to_type_inserter(multiset),
  7225. split_option);
  7226. else
  7227. return split(multiple_char_delimiter_predicate(delimiters),
  7228. begin,end,
  7229. range_to_type_inserter(multiset),
  7230. split_option);
  7231. }
  7232. template <typename InputIterator,
  7233. typename T,
  7234. typename Container>
  7235. inline std::size_t parse(const InputIterator begin,
  7236. const InputIterator end,
  7237. const std::string& delimiters,
  7238. std::queue<T,Container>& queue,
  7239. const split_options::type& split_option = split_options::compress_delimiters)
  7240. {
  7241. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7242. details::convert_type_assert<itr_type>();
  7243. if (1 == delimiters.size())
  7244. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7245. begin,end,
  7246. range_to_type_push_inserter(queue),
  7247. split_option);
  7248. else
  7249. return split(multiple_char_delimiter_predicate(delimiters),
  7250. begin,end,
  7251. range_to_type_push_inserter(queue),
  7252. split_option);
  7253. }
  7254. template <typename InputIterator,
  7255. typename T,
  7256. typename Container>
  7257. inline std::size_t parse(const InputIterator begin,
  7258. const InputIterator end,
  7259. const std::string& delimiters,
  7260. std::stack<T,Container>& stack,
  7261. const split_options::type& split_option = split_options::compress_delimiters)
  7262. {
  7263. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7264. details::convert_type_assert<itr_type>();
  7265. if (1 == delimiters.size())
  7266. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7267. begin,end,
  7268. range_to_type_push_inserter(stack),
  7269. split_option);
  7270. else
  7271. return split(multiple_char_delimiter_predicate(delimiters),
  7272. begin, end,
  7273. range_to_type_push_inserter(stack),
  7274. split_option);
  7275. }
  7276. template <typename InputIterator,
  7277. typename T,
  7278. typename Container,
  7279. typename Comparator>
  7280. inline std::size_t parse(const InputIterator begin,
  7281. const InputIterator end,
  7282. const std::string& delimiters,
  7283. std::priority_queue<T,Container,Comparator>& priority_queue,
  7284. const split_options::type& split_option = split_options::compress_delimiters)
  7285. {
  7286. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7287. details::convert_type_assert<itr_type>();
  7288. if (1 == delimiters.size())
  7289. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7290. begin,end,
  7291. range_to_type_push_inserter(priority_queue),
  7292. split_option);
  7293. else
  7294. return split(multiple_char_delimiter_predicate(delimiters),
  7295. begin,end,
  7296. range_to_type_push_inserter(priority_queue),
  7297. split_option);
  7298. }
  7299. template <typename InputIterator,
  7300. typename T,
  7301. typename Allocator,
  7302. template <typename,typename> class Sequence>
  7303. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7304. const std::string& delimiters,
  7305. Sequence<T,Allocator>& sequence,
  7306. const split_options::type& split_option = split_options::compress_delimiters)
  7307. {
  7308. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7309. details::convert_type_assert<itr_type>();
  7310. if (1 == delimiters.size())
  7311. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7312. range.first,range.second,
  7313. range_to_type_back_inserter(sequence),
  7314. split_option);
  7315. else
  7316. return split(multiple_char_delimiter_predicate(delimiters),
  7317. range.first,range.second,
  7318. range_to_type_back_inserter(sequence),
  7319. split_option);
  7320. }
  7321. template <typename InputIterator,
  7322. typename T,
  7323. typename Comparator,
  7324. typename Allocator>
  7325. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7326. const std::string& delimiters,
  7327. std::set<T,Comparator,Allocator>& set,
  7328. const split_options::type& split_option = split_options::compress_delimiters)
  7329. {
  7330. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7331. details::convert_type_assert<itr_type>();
  7332. if (1 == delimiters.size())
  7333. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7334. range.first,range.second,
  7335. range_to_type_inserter(set),
  7336. split_option);
  7337. else
  7338. return split(multiple_char_delimiter_predicate(delimiters),
  7339. range.first,range.second,
  7340. range_to_type_inserter(set),
  7341. split_option);
  7342. }
  7343. template <typename InputIterator,
  7344. typename T,
  7345. typename Comparator,
  7346. typename Allocator>
  7347. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7348. const std::string& delimiters,
  7349. std::multiset<T,Comparator,Allocator>& multiset,
  7350. const split_options::type& split_option = split_options::compress_delimiters)
  7351. {
  7352. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7353. details::convert_type_assert<itr_type>();
  7354. if (1 == delimiters.size())
  7355. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7356. range.first,range.second,
  7357. range_to_type_inserter(multiset),
  7358. split_option);
  7359. else
  7360. return split(multiple_char_delimiter_predicate(delimiters),
  7361. range.first,range.second,
  7362. range_to_type_inserter(multiset),
  7363. split_option);
  7364. }
  7365. template <typename InputIterator,
  7366. typename T,
  7367. typename Container>
  7368. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7369. const std::string& delimiters,
  7370. std::queue<T,Container>& queue,
  7371. const split_options::type& split_option = split_options::compress_delimiters)
  7372. {
  7373. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7374. details::convert_type_assert<itr_type>();
  7375. if (1 == delimiters.size())
  7376. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7377. range.first,range.second,
  7378. range_to_type_push_inserter(queue),
  7379. split_option);
  7380. else
  7381. return split(multiple_char_delimiter_predicate(delimiters),
  7382. range.first,range.second,
  7383. range_to_type_push_inserter(queue),
  7384. split_option);
  7385. }
  7386. template <typename InputIterator,
  7387. typename T,
  7388. typename Container>
  7389. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7390. const std::string& delimiters,
  7391. std::stack<T,Container>& stack,
  7392. const split_options::type& split_option = split_options::compress_delimiters)
  7393. {
  7394. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7395. details::convert_type_assert<itr_type>();
  7396. if (1 == delimiters.size())
  7397. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7398. range.first,range.second,
  7399. range_to_type_push_inserter(stack),
  7400. split_option);
  7401. else
  7402. return split(multiple_char_delimiter_predicate(delimiters),
  7403. range.first,range.second,
  7404. range_to_type_push_inserter(stack),
  7405. split_option);
  7406. }
  7407. template <typename InputIterator,
  7408. typename T,
  7409. typename Container,
  7410. typename Comparator>
  7411. inline std::size_t parse(const std::pair<InputIterator,InputIterator>& range,
  7412. const std::string& delimiters,
  7413. std::priority_queue<T,Container,Comparator>& priority_queue,
  7414. const split_options::type& split_option = split_options::compress_delimiters)
  7415. {
  7416. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7417. details::convert_type_assert<itr_type>();
  7418. if (1 == delimiters.size())
  7419. return split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7420. range.first,range.second,
  7421. range_to_type_push_inserter(priority_queue),
  7422. split_option);
  7423. else
  7424. return split(multiple_char_delimiter_predicate(delimiters),
  7425. range.first,range.second,
  7426. range_to_type_push_inserter(priority_queue),
  7427. split_option);
  7428. }
  7429. namespace details
  7430. {
  7431. class container_adder
  7432. {
  7433. private:
  7434. class container_adder_base
  7435. {
  7436. public:
  7437. typedef const char* itr_type;
  7438. virtual ~container_adder_base(){}
  7439. template <typename InputIterator>
  7440. inline bool add(const InputIterator begin, const InputIterator end) const
  7441. {
  7442. return add_impl(begin,end);
  7443. }
  7444. template <typename InputIterator>
  7445. inline bool add(const std::pair<InputIterator,InputIterator>& range) const
  7446. {
  7447. return add(range.first,range.second);
  7448. }
  7449. protected:
  7450. virtual bool add_impl(const itr_type begin, const itr_type end) const = 0;
  7451. };
  7452. template <typename T,
  7453. typename Allocator,
  7454. template <typename,typename> class Sequence>
  7455. class sequence_adder_impl : public container_adder_base
  7456. {
  7457. public:
  7458. typedef Sequence<T,Allocator> sequence_t;
  7459. sequence_adder_impl(sequence_t& seq)
  7460. : sequence_(seq)
  7461. {}
  7462. protected:
  7463. bool add_impl(const itr_type begin, const itr_type end) const
  7464. {
  7465. T t;
  7466. if (!string_to_type_converter(begin,end,t)) return false;
  7467. sequence_.push_back(t);
  7468. return true;
  7469. }
  7470. private:
  7471. sequence_adder_impl operator=(const sequence_adder_impl&);
  7472. sequence_t& sequence_;
  7473. };
  7474. template <typename T,
  7475. typename Comparator,
  7476. typename Allocator,
  7477. template <typename,typename,typename> class Set>
  7478. class set_adder_impl : public container_adder_base
  7479. {
  7480. public:
  7481. set_adder_impl(Set<T,Comparator,Allocator>& set)
  7482. : set_(set)
  7483. {}
  7484. bool add_impl(const itr_type begin, const itr_type end) const
  7485. {
  7486. T t;
  7487. if (!string_to_type_converter(begin,end,t)) return false;
  7488. set_.insert(t);
  7489. return true;
  7490. }
  7491. private:
  7492. set_adder_impl operator=(const set_adder_impl&);
  7493. Set<T,Comparator,Allocator>& set_;
  7494. };
  7495. template <typename T,
  7496. typename Container,
  7497. typename Comparator>
  7498. class pq_adder_impl : public container_adder_base
  7499. {
  7500. public:
  7501. pq_adder_impl(std::priority_queue<T,Container,Comparator>& pq)
  7502. : pq_(pq)
  7503. {}
  7504. bool add_impl(const itr_type begin, const itr_type end) const
  7505. {
  7506. T t;
  7507. if (!string_to_type_converter(begin,end,t)) return false;
  7508. pq_.push(t);
  7509. return true;
  7510. }
  7511. private:
  7512. pq_adder_impl operator=(const pq_adder_impl&);
  7513. std::priority_queue<T,Container,Comparator>& pq_;
  7514. };
  7515. template <typename T,
  7516. typename Container,
  7517. template <typename,typename> class SContainer>
  7518. class stack_queue_adder_impl : public container_adder_base
  7519. {
  7520. public:
  7521. stack_queue_adder_impl(SContainer<T,Container>& container)
  7522. : container_(container)
  7523. {}
  7524. bool add_impl(const itr_type begin, const itr_type end) const
  7525. {
  7526. T t;
  7527. if (!string_to_type_converter(begin,end,t)) return false;
  7528. container_.push(t);
  7529. return true;
  7530. }
  7531. private:
  7532. stack_queue_adder_impl operator=(const stack_queue_adder_impl&);
  7533. SContainer<T,Container>& container_;
  7534. };
  7535. public:
  7536. template <typename T, typename Allocator>
  7537. container_adder(std::vector<T,Allocator>& vec)
  7538. : container_adder_base_(new(buffer)sequence_adder_impl<T,Allocator,std::vector>(vec))
  7539. {}
  7540. template <typename T, typename Allocator>
  7541. container_adder(std::deque<T,Allocator>& deq)
  7542. : container_adder_base_(new(buffer)sequence_adder_impl<T,Allocator,std::deque>(deq))
  7543. {}
  7544. template <typename T, typename Allocator>
  7545. container_adder(std::list<T,Allocator>& list)
  7546. : container_adder_base_(new(buffer)sequence_adder_impl<T,Allocator,std::list>(list))
  7547. {}
  7548. template <typename T, typename Comparator, typename Allocator>
  7549. container_adder(std::set<T,Comparator,Allocator>& set)
  7550. : container_adder_base_(new(buffer)set_adder_impl<T,Comparator,Allocator,std::set>(set))
  7551. {}
  7552. template <typename T, typename Comparator, typename Allocator>
  7553. container_adder(std::multiset<T,Comparator,Allocator>& multiset)
  7554. : container_adder_base_(new(buffer)set_adder_impl<T,Comparator,Allocator,std::multiset>(multiset))
  7555. {}
  7556. template <typename T, typename Container, typename Comparator>
  7557. container_adder(std::priority_queue<T,Container,Comparator>& pq)
  7558. : container_adder_base_(new(buffer)pq_adder_impl<T,Container,Comparator>(pq))
  7559. {}
  7560. template <typename T, typename Container>
  7561. container_adder(std::queue<T,Container>& queue)
  7562. : container_adder_base_(new(buffer)stack_queue_adder_impl<T,Container,std::queue>(queue))
  7563. {}
  7564. template <typename T, typename Container>
  7565. container_adder(std::stack<T,Container>& stack)
  7566. : container_adder_base_(new(buffer)stack_queue_adder_impl<T,Container,std::stack>(stack))
  7567. {}
  7568. template <typename InputIterator>
  7569. inline bool add(InputIterator begin, InputIterator end) const
  7570. {
  7571. return container_adder_base_->add(begin,end);
  7572. }
  7573. template <typename InputIterator>
  7574. inline bool add(std::pair<InputIterator,InputIterator>& range) const
  7575. {
  7576. return add(range.first,range.second);
  7577. }
  7578. template <typename InputIterator>
  7579. inline bool operator()(const InputIterator begin, const InputIterator end)
  7580. {
  7581. InputIterator itr = begin;
  7582. while (end != itr)
  7583. {
  7584. if (!add(*itr)) return false;
  7585. ++itr;
  7586. }
  7587. return true;
  7588. }
  7589. private:
  7590. mutable container_adder_base* container_adder_base_;
  7591. unsigned char buffer[64];
  7592. };
  7593. template <typename T,typename is_stl_container_result>
  7594. struct ca_type { typedef T& type; };
  7595. template <typename T>
  7596. struct ca_type <T,details::yes_t> { typedef details::container_adder type; };
  7597. }
  7598. template <typename InputIterator,
  7599. typename T1, typename T2, typename T3,
  7600. typename T4, typename T5, typename T6,
  7601. typename T7, typename T8, typename T9,
  7602. typename T10, typename T11>
  7603. inline bool parse(const InputIterator begin, const InputIterator end,
  7604. const std::string& delimiters,
  7605. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7,
  7606. T8& t8, T9& t9, T10& t10, T11& t11,
  7607. details::container_adder ca)
  7608. {
  7609. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7610. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7611. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7612. details::convert_type_assert<itr_type>();
  7613. std::deque<iterator_type> token_list;
  7614. if (1 == delimiters.size())
  7615. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7616. begin,end,
  7617. std::back_inserter(token_list),
  7618. split_options::compress_delimiters);
  7619. else
  7620. split(multiple_char_delimiter_predicate(delimiters),
  7621. begin,end,
  7622. std::back_inserter(token_list),
  7623. split_options::compress_delimiters);
  7624. if (token_list.size() < 12) return false;
  7625. iterator_type_ptr itr = token_list.begin();
  7626. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  7627. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  7628. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  7629. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  7630. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  7631. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  7632. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  7633. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  7634. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  7635. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr;
  7636. if (!string_to_type_converter((*itr).first,(*itr).second,t11)) return false; ++itr;
  7637. return ca(itr,token_list.end());
  7638. }
  7639. template <typename InputIterator,
  7640. typename T1, typename T2, typename T3,
  7641. typename T4, typename T5, typename T6,
  7642. typename T7, typename T8, typename T9,
  7643. typename T10>
  7644. inline bool parse(const InputIterator begin, const InputIterator end,
  7645. const std::string& delimiters,
  7646. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9, T10& t10,
  7647. details::container_adder ca)
  7648. {
  7649. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7650. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7651. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7652. details::convert_type_assert<itr_type>();
  7653. std::deque<iterator_type> token_list;
  7654. if (1 == delimiters.size())
  7655. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7656. begin,end,
  7657. std::back_inserter(token_list),
  7658. split_options::compress_delimiters);
  7659. else
  7660. split(multiple_char_delimiter_predicate(delimiters),
  7661. begin,end,
  7662. std::back_inserter(token_list),
  7663. split_options::compress_delimiters);
  7664. if (token_list.size() < 11) return false;
  7665. iterator_type_ptr itr = token_list.begin();
  7666. if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr;
  7667. if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr;
  7668. if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr;
  7669. if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr;
  7670. if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr;
  7671. if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr;
  7672. if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr;
  7673. if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr;
  7674. if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr;
  7675. if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr;
  7676. return ca(itr,token_list.end());
  7677. }
  7678. template <typename InputIterator,
  7679. typename T1, typename T2, typename T3,
  7680. typename T4, typename T5, typename T6,
  7681. typename T7, typename T8, typename T9>
  7682. inline bool parse(const InputIterator begin, const InputIterator end,
  7683. const std::string& delimiters,
  7684. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9,
  7685. details::container_adder ca)
  7686. {
  7687. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7688. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7689. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7690. details::convert_type_assert<itr_type>();
  7691. std::deque<iterator_type> token_list;
  7692. if (1 == delimiters.size())
  7693. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7694. begin,end,
  7695. std::back_inserter(token_list),
  7696. split_options::compress_delimiters);
  7697. else
  7698. split(multiple_char_delimiter_predicate(delimiters),
  7699. begin,end,
  7700. std::back_inserter(token_list),
  7701. split_options::compress_delimiters);
  7702. if (token_list.size() < 10) return false;
  7703. iterator_type_ptr itr = token_list.begin();
  7704. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7705. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7706. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7707. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7708. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7709. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7710. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  7711. if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false; ++itr;
  7712. if (!string_to_type_converter((*itr).first,(*itr).second,t9)) return false; ++itr;
  7713. return ca(itr,token_list.end());
  7714. }
  7715. template <typename InputIterator,
  7716. typename T1, typename T2, typename T3,
  7717. typename T4, typename T5, typename T6,
  7718. typename T7, typename T8>
  7719. inline bool parse(const InputIterator begin, const InputIterator end,
  7720. const std::string& delimiters,
  7721. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8,
  7722. details::container_adder ca)
  7723. {
  7724. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7725. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7726. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7727. details::convert_type_assert<itr_type>();
  7728. std::deque<iterator_type> token_list;
  7729. if (1 == delimiters.size())
  7730. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7731. begin,end,
  7732. std::back_inserter(token_list),
  7733. split_options::compress_delimiters);
  7734. else
  7735. split(multiple_char_delimiter_predicate(delimiters),
  7736. begin,end,
  7737. std::back_inserter(token_list),
  7738. split_options::compress_delimiters);
  7739. if (token_list.size() < 9) return false;
  7740. iterator_type_ptr itr = token_list.begin();
  7741. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7742. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7743. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7744. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7745. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7746. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7747. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  7748. if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false; ++itr;
  7749. return ca(itr,token_list.end());
  7750. }
  7751. template <typename InputIterator,
  7752. typename T1, typename T2, typename T3,
  7753. typename T4, typename T5, typename T6, typename T7>
  7754. inline bool parse(const InputIterator begin, const InputIterator end,
  7755. const std::string& delimiters,
  7756. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7,
  7757. details::container_adder ca)
  7758. {
  7759. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7760. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7761. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7762. details::convert_type_assert<itr_type>();
  7763. std::deque<iterator_type> token_list;
  7764. if (1 == delimiters.size())
  7765. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7766. begin,end,
  7767. std::back_inserter(token_list),
  7768. split_options::compress_delimiters);
  7769. else
  7770. split(multiple_char_delimiter_predicate(delimiters),
  7771. begin,end,
  7772. std::back_inserter(token_list),
  7773. split_options::compress_delimiters);
  7774. if (token_list.size() < 8) return false;
  7775. iterator_type_ptr itr = token_list.begin();
  7776. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7777. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7778. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7779. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7780. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7781. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7782. if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr;
  7783. return ca(itr,token_list.end());
  7784. }
  7785. template <typename InputIterator,
  7786. typename T1, typename T2, typename T3,
  7787. typename T4, typename T5, typename T6>
  7788. inline bool parse(const InputIterator begin, const InputIterator end,
  7789. const std::string& delimiters,
  7790. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  7791. details::container_adder ca)
  7792. {
  7793. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7794. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7795. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7796. details::convert_type_assert<itr_type>();
  7797. std::deque<iterator_type> token_list;
  7798. if (1 == delimiters.size())
  7799. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7800. begin,end,
  7801. std::back_inserter(token_list),
  7802. split_options::compress_delimiters);
  7803. else
  7804. split(multiple_char_delimiter_predicate(delimiters),
  7805. begin,end,
  7806. std::back_inserter(token_list),
  7807. split_options::compress_delimiters);
  7808. if (token_list.size() < 7) return false;
  7809. iterator_type_ptr itr = token_list.begin();
  7810. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7811. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7812. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7813. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7814. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7815. if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr;
  7816. return ca(itr,token_list.end());
  7817. }
  7818. template <typename InputIterator,
  7819. typename T1, typename T2, typename T3,
  7820. typename T4, typename T5>
  7821. inline bool parse(const InputIterator begin, const InputIterator end,
  7822. const std::string& delimiters,
  7823. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  7824. details::container_adder ca)
  7825. {
  7826. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7827. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7828. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7829. details::convert_type_assert<itr_type>();
  7830. std::deque<iterator_type> token_list;
  7831. if (1 == delimiters.size())
  7832. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7833. begin,end,
  7834. std::back_inserter(token_list),
  7835. split_options::compress_delimiters);
  7836. else
  7837. split(multiple_char_delimiter_predicate(delimiters),
  7838. begin,end,
  7839. std::back_inserter(token_list),
  7840. split_options::compress_delimiters);
  7841. if (token_list.size() < 6) return false;
  7842. iterator_type_ptr itr = token_list.begin();
  7843. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7844. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7845. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7846. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7847. if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr;
  7848. return ca(itr,token_list.end());
  7849. }
  7850. template <typename InputIterator,
  7851. typename T1, typename T2, typename T3, typename T4>
  7852. inline bool parse(const InputIterator begin, const InputIterator end,
  7853. const std::string& delimiters,
  7854. T1& t1, T2& t2, T3& t3, T4& t4,
  7855. details::container_adder ca)
  7856. {
  7857. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7858. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7859. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7860. details::convert_type_assert<itr_type>();
  7861. std::deque<iterator_type> token_list;
  7862. if (1 == delimiters.size())
  7863. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7864. begin,end,
  7865. std::back_inserter(token_list),
  7866. split_options::compress_delimiters);
  7867. else
  7868. split(multiple_char_delimiter_predicate(delimiters),
  7869. begin,end,
  7870. std::back_inserter(token_list),
  7871. split_options::compress_delimiters);
  7872. if (token_list.size() < 5) return false;
  7873. iterator_type_ptr itr = token_list.begin();
  7874. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7875. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7876. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7877. if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr;
  7878. return ca(itr,token_list.end());
  7879. }
  7880. template <typename InputIterator,
  7881. typename T1, typename T2, typename T3>
  7882. inline bool parse(const InputIterator begin, const InputIterator end,
  7883. const std::string& delimiters,
  7884. T1& t1, T2& t2, T3& t3,
  7885. details::container_adder ca)
  7886. {
  7887. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7888. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7889. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7890. details::convert_type_assert<itr_type>();
  7891. std::deque<iterator_type> token_list;
  7892. if (1 == delimiters.size())
  7893. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7894. begin,end,
  7895. std::back_inserter(token_list),
  7896. split_options::compress_delimiters);
  7897. else
  7898. split(multiple_char_delimiter_predicate(delimiters),
  7899. begin,end,
  7900. std::back_inserter(token_list),
  7901. split_options::compress_delimiters);
  7902. if (token_list.size() < 4) return false;
  7903. iterator_type_ptr itr = token_list.begin();
  7904. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7905. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7906. if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr;
  7907. return ca(itr,token_list.end());
  7908. }
  7909. template <typename InputIterator,
  7910. typename T1, typename T2>
  7911. inline bool parse(const InputIterator begin, const InputIterator end,
  7912. const std::string& delimiters,
  7913. T1& t1, T2& t2,
  7914. details::container_adder ca)
  7915. {
  7916. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7917. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7918. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7919. details::convert_type_assert<itr_type>();
  7920. std::deque<iterator_type> token_list;
  7921. if (1 == delimiters.size())
  7922. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7923. begin,end,
  7924. std::back_inserter(token_list),
  7925. split_options::compress_delimiters);
  7926. else
  7927. split(multiple_char_delimiter_predicate(delimiters),
  7928. begin,end,
  7929. std::back_inserter(token_list),
  7930. split_options::compress_delimiters);
  7931. if (token_list.size() < 3) return false;
  7932. iterator_type_ptr itr = token_list.begin();
  7933. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7934. if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr;
  7935. return ca(itr,token_list.end());
  7936. }
  7937. template <typename InputIterator, typename T1>
  7938. inline bool parse(const InputIterator begin, const InputIterator end,
  7939. const std::string& delimiters,
  7940. T1& t1,
  7941. details::container_adder ca)
  7942. {
  7943. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7944. typedef std::pair<InputIterator,InputIterator> iterator_type;
  7945. typedef typename std::deque<iterator_type>::iterator iterator_type_ptr;
  7946. details::convert_type_assert<itr_type>();
  7947. std::deque<iterator_type> token_list;
  7948. if (1 == delimiters.size())
  7949. split(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7950. begin,end,
  7951. std::back_inserter(token_list),
  7952. split_options::compress_delimiters);
  7953. else
  7954. split(multiple_char_delimiter_predicate(delimiters),
  7955. begin,end,
  7956. std::back_inserter(token_list),
  7957. split_options::compress_delimiters);
  7958. if (token_list.size() < 2) return false;
  7959. iterator_type_ptr itr = token_list.begin();
  7960. if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr;
  7961. return ca(itr,token_list.end());
  7962. }
  7963. template <typename InputIterator,
  7964. typename T,
  7965. typename Allocator,
  7966. template <typename,typename> class Sequence>
  7967. inline std::size_t parse_n(const InputIterator begin,
  7968. const InputIterator end,
  7969. const std::string& delimiters,
  7970. const std::size_t& n,
  7971. Sequence<T,Allocator>& sequence,
  7972. const split_options::type& split_option = split_options::compress_delimiters)
  7973. {
  7974. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  7975. const std::size_t original_size = sequence.size();
  7976. details::convert_type_assert<itr_type>();
  7977. if (1 == delimiters.size())
  7978. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  7979. begin,end,
  7980. n,
  7981. range_to_type_back_inserter(sequence),
  7982. split_option);
  7983. else
  7984. split_n(multiple_char_delimiter_predicate(delimiters),
  7985. begin,end,
  7986. n,
  7987. range_to_type_back_inserter(sequence),
  7988. split_option);
  7989. return sequence.size() - original_size;
  7990. }
  7991. template <typename InputIterator,
  7992. typename T,
  7993. typename Comparator,
  7994. typename Allocator>
  7995. inline std::size_t parse_n(const InputIterator begin,
  7996. const InputIterator end,
  7997. const std::string& delimiters,
  7998. const std::size_t& n,
  7999. std::set<T,Comparator,Allocator>& set,
  8000. const split_options::type& split_option = split_options::compress_delimiters)
  8001. {
  8002. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  8003. const std::size_t original_size = set.size();
  8004. details::convert_type_assert<itr_type>();
  8005. if (1 == delimiters.size())
  8006. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  8007. begin,end,
  8008. n,
  8009. range_to_type_inserter(set),
  8010. split_option);
  8011. else
  8012. split_n(multiple_char_delimiter_predicate(delimiters),
  8013. begin,end,
  8014. n,
  8015. range_to_type_inserter(set),
  8016. split_option);
  8017. return set.size() - original_size;
  8018. }
  8019. template <typename InputIterator,
  8020. typename T,
  8021. typename Comparator,
  8022. typename Allocator>
  8023. inline std::size_t parse_n(const InputIterator begin,
  8024. const InputIterator end,
  8025. const std::string& delimiters,
  8026. const std::size_t& n,
  8027. std::multiset<T,Comparator,Allocator>& multiset,
  8028. const split_options::type& split_option = split_options::compress_delimiters)
  8029. {
  8030. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  8031. const std::size_t original_size = multiset.size();
  8032. details::convert_type_assert<itr_type>();
  8033. if (1 == delimiters.size())
  8034. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  8035. begin,end,
  8036. n,
  8037. range_to_type_inserter(multiset),
  8038. split_option);
  8039. else
  8040. split_n(multiple_char_delimiter_predicate(delimiters),
  8041. begin,end,
  8042. n,
  8043. range_to_type_inserter(multiset),
  8044. split_option);
  8045. return multiset.size() - original_size;
  8046. }
  8047. template <typename InputIterator,
  8048. typename T,
  8049. typename Container>
  8050. inline std::size_t parse_n(const InputIterator begin,
  8051. const InputIterator end,
  8052. const std::string& delimiters,
  8053. const std::size_t& n,
  8054. std::queue<T,Container>& queue,
  8055. const split_options::type& split_option = split_options::compress_delimiters)
  8056. {
  8057. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  8058. const std::size_t original_size = queue.size();
  8059. details::convert_type_assert<itr_type>();
  8060. if (1 == delimiters.size())
  8061. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  8062. begin,end,
  8063. n,
  8064. range_to_type_push_inserter(queue),
  8065. split_option);
  8066. else
  8067. split_n(multiple_char_delimiter_predicate(delimiters),
  8068. begin,end,
  8069. n,
  8070. range_to_type_push_inserter(queue),
  8071. split_option);
  8072. return queue.size() - original_size;
  8073. }
  8074. template <typename InputIterator,
  8075. typename T,
  8076. typename Container>
  8077. inline std::size_t parse_n(const InputIterator begin,
  8078. const InputIterator end,
  8079. const std::string& delimiters,
  8080. const std::size_t& n,
  8081. std::stack<T,Container>& stack,
  8082. const split_options::type& split_option = split_options::compress_delimiters)
  8083. {
  8084. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  8085. const std::size_t original_size = stack.size();
  8086. details::convert_type_assert<itr_type>();
  8087. if (1 == delimiters.size())
  8088. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  8089. begin,end,
  8090. n,
  8091. range_to_type_push_inserter(stack),
  8092. split_option);
  8093. else
  8094. split_n(multiple_char_delimiter_predicate(delimiters),
  8095. begin,end,
  8096. n,
  8097. range_to_type_push_inserter(stack),
  8098. split_option);
  8099. return stack.size() - original_size;
  8100. }
  8101. template <typename InputIterator,
  8102. typename T,
  8103. typename Container,
  8104. typename Comparator>
  8105. inline std::size_t parse_n(const InputIterator begin,
  8106. const InputIterator end,
  8107. const std::string& delimiters,
  8108. const std::size_t& n,
  8109. std::priority_queue<T,Container,Comparator>& priority_queue,
  8110. const split_options::type& split_option = split_options::compress_delimiters)
  8111. {
  8112. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  8113. const std::size_t original_size = priority_queue.size();
  8114. details::convert_type_assert<itr_type>();
  8115. if (1 == delimiters.size())
  8116. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  8117. begin,end,
  8118. n,
  8119. range_to_type_push_inserter(priority_queue),
  8120. split_option);
  8121. else
  8122. split_n(multiple_char_delimiter_predicate(delimiters),
  8123. begin,end,
  8124. n,
  8125. range_to_type_push_inserter(priority_queue),
  8126. split_option);
  8127. return priority_queue.size() - original_size;
  8128. }
  8129. template <typename InputIterator, typename T>
  8130. inline std::size_t parse_n(const InputIterator begin,
  8131. const InputIterator end,
  8132. const std::string& delimiters,
  8133. const std::size_t& n,
  8134. T* out,
  8135. const split_options::type& split_option = split_options::compress_delimiters)
  8136. {
  8137. typedef typename details::is_valid_iterator<InputIterator>::type itr_type;
  8138. std::size_t insert_count = 0;
  8139. details::convert_type_assert<itr_type>();
  8140. if (1 == delimiters.size())
  8141. split_n(single_delimiter_predicate<std::string::value_type>(delimiters[0]),
  8142. begin,end,
  8143. n,
  8144. range_to_ptr_type(out,insert_count),
  8145. split_option);
  8146. else
  8147. split_n(multiple_char_delimiter_predicate(delimiters),
  8148. begin,end,
  8149. n,
  8150. range_to_ptr_type(out,insert_count),
  8151. split_option);
  8152. return insert_count;
  8153. }
  8154. template <typename InputIterator,
  8155. typename T,
  8156. typename Allocator,
  8157. template <typename,typename> class Sequence>
  8158. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8159. const std::string& delimiters,
  8160. const std::size_t& n,
  8161. Sequence<T,Allocator>& sequence,
  8162. const split_options::type& split_option = split_options::compress_delimiters)
  8163. {
  8164. return parse(range.first,range.second,delimiters,n,sequence,split_option);
  8165. }
  8166. template <typename InputIterator,
  8167. typename T,
  8168. typename Comparator,
  8169. typename Allocator>
  8170. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8171. const std::string& delimiters,
  8172. const std::size_t& n,
  8173. std::set<T,Comparator,Allocator>& set,
  8174. const split_options::type& split_option = split_options::compress_delimiters)
  8175. {
  8176. return parse(range.first,range.second,delimiters,n,set,split_option);
  8177. }
  8178. template <typename InputIterator,
  8179. typename T,
  8180. typename Comparator,
  8181. typename Allocator>
  8182. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8183. const std::string& delimiters,
  8184. const std::size_t& n,
  8185. std::multiset<T,Comparator,Allocator>& multiset,
  8186. const split_options::type& split_option = split_options::compress_delimiters)
  8187. {
  8188. return parse(range.first,range.second,delimiters,n,multiset,split_option);
  8189. }
  8190. template <typename InputIterator,
  8191. typename T,
  8192. typename Container>
  8193. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8194. const std::string& delimiters,
  8195. const std::size_t& n,
  8196. std::queue<T,Container>& queue,
  8197. const split_options::type& split_option = split_options::compress_delimiters)
  8198. {
  8199. return parse(range.first,range.second,delimiters,n,queue,split_option);
  8200. }
  8201. template <typename InputIterator,
  8202. typename T,
  8203. typename Container>
  8204. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8205. const std::string& delimiters,
  8206. const std::size_t& n,
  8207. std::stack<T,Container>& stack,
  8208. const split_options::type& split_option = split_options::compress_delimiters)
  8209. {
  8210. return parse(range.first,range.second,delimiters,n,stack,split_option);
  8211. }
  8212. template <typename InputIterator,
  8213. typename T,
  8214. typename Container,
  8215. typename Comparator>
  8216. inline std::size_t parse_n(const std::pair<InputIterator,InputIterator>& range,
  8217. const std::string& delimiters,
  8218. const std::size_t& n,
  8219. std::priority_queue<T,Container,Comparator>& priority_queue,
  8220. const split_options::type& split_option = split_options::compress_delimiters)
  8221. {
  8222. return parse(range.first,range.second,delimiters,n,priority_queue,split_option);
  8223. }
  8224. template <typename T1, typename T2, typename T3, typename T4,
  8225. typename T5, typename T6, typename T7, typename T8,
  8226. typename T9, typename T10, typename T11, typename T12>
  8227. inline bool parse(const std::string& data,
  8228. const std::string& delimiters,
  8229. T1& t1, T2& t2, T3& t3, T4& t4,
  8230. T5& t5, T6& t6, T7& t7, T8& t8,
  8231. T9& t9, T10& t10, T11& t11, T12& t12)
  8232. {
  8233. return parse(data.data(),
  8234. data.data() + data.size(),
  8235. delimiters,
  8236. t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,
  8237. typename details::ca_type<T12, typename details::is_stl_container<T12>::result_t>::type(t12));
  8238. }
  8239. template <typename T1, typename T2, typename T3, typename T4,
  8240. typename T5, typename T6, typename T7, typename T8,
  8241. typename T9, typename T10, typename T11>
  8242. inline bool parse(const std::string& data,
  8243. const std::string& delimiters,
  8244. T1& t1, T2& t2, T3& t3, T4& t4,
  8245. T5& t5, T6& t6, T7& t7, T8& t8,
  8246. T9& t9, T10& t10, T11& t11)
  8247. {
  8248. return parse(data.data(),
  8249. data.data() + data.size(),
  8250. delimiters,
  8251. t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,
  8252. typename details::ca_type<T11, typename details::is_stl_container<T11>::result_t>::type(t11));
  8253. }
  8254. template <typename T1, typename T2, typename T3, typename T4,
  8255. typename T5, typename T6, typename T7, typename T8,
  8256. typename T9, typename T10>
  8257. inline bool parse(const std::string& data,
  8258. const std::string& delimiters,
  8259. T1& t1, T2& t2, T3& t3, T4& t4,
  8260. T5& t5, T6& t6, T7& t7, T8& t8,
  8261. T9& t9, T10& t10)
  8262. {
  8263. return parse(data.data(),
  8264. data.data() + data.size(),
  8265. delimiters,
  8266. t1,t2,t3,t4,t5,t6,t7,t8,t9,
  8267. typename details::ca_type<T10, typename details::is_stl_container<T10>::result_t>::type(t10));
  8268. }
  8269. template <typename T1, typename T2, typename T3, typename T4,
  8270. typename T5, typename T6, typename T7, typename T8,
  8271. typename T9>
  8272. inline bool parse(const std::string& data,
  8273. const std::string& delimiters,
  8274. T1& t1, T2& t2, T3& t3, T4& t4,
  8275. T5& t5, T6& t6, T7& t7, T8& t8,
  8276. T9& t9)
  8277. {
  8278. return parse(data.data(),
  8279. data.data() + data.size(),
  8280. delimiters,
  8281. t1,t2,t3,t4,t5,t6,t7,t8,
  8282. typename details::ca_type<T9, typename details::is_stl_container<T9>::result_t>::type(t9));
  8283. }
  8284. template <typename T1, typename T2, typename T3, typename T4,
  8285. typename T5, typename T6, typename T7, typename T8>
  8286. inline bool parse(const std::string& data,
  8287. const std::string& delimiters,
  8288. T1& t1, T2& t2, T3& t3, T4& t4,
  8289. T5& t5, T6& t6, T7& t7, T8& t8)
  8290. {
  8291. return parse(data.data(),
  8292. data.data() + data.size(),
  8293. delimiters,
  8294. t1,t2,t3,t4,t5,t6,t7,
  8295. typename details::ca_type<T8, typename details::is_stl_container<T8>::result_t>::type(t8));
  8296. }
  8297. template <typename T1, typename T2, typename T3, typename T4,
  8298. typename T5, typename T6, typename T7>
  8299. inline bool parse(const std::string& data,
  8300. const std::string& delimiters,
  8301. T1& t1, T2& t2, T3& t3, T4& t4,
  8302. T5& t5, T6& t6, T7& t7)
  8303. {
  8304. return parse(data.data(),
  8305. data.data() + data.size(),
  8306. delimiters,
  8307. t1,t2,t3,t4,t5,t6,
  8308. typename details::ca_type<T7, typename details::is_stl_container<T7>::result_t>::type(t7));
  8309. }
  8310. template <typename T1, typename T2, typename T3, typename T4,
  8311. typename T5, typename T6>
  8312. inline bool parse(const std::string& data,
  8313. const std::string& delimiters,
  8314. T1& t1, T2& t2, T3& t3, T4& t4,
  8315. T5& t5, T6& t6)
  8316. {
  8317. return parse(data.data(),
  8318. data.data() + data.size(),
  8319. delimiters,
  8320. t1,t2,t3,t4,t5,
  8321. typename details::ca_type<T6,typename details::is_stl_container<T6>::result_t>::type(t6));
  8322. }
  8323. template <typename T1, typename T2, typename T3, typename T4,
  8324. typename T5>
  8325. inline bool parse(const std::string& data,
  8326. const std::string& delimiters,
  8327. T1& t1, T2& t2, T3& t3, T4& t4,
  8328. T5& t5)
  8329. {
  8330. return parse(data.data(),
  8331. data.data() + data.size(),
  8332. delimiters,
  8333. t1,t2,t3,t4,
  8334. typename details::ca_type<T5, typename details::is_stl_container<T5>::result_t>::type(t5));
  8335. }
  8336. template <typename T1, typename T2, typename T3, typename T4>
  8337. inline bool parse(const std::string& data,
  8338. const std::string& delimiters,
  8339. T1& t1, T2& t2, T3& t3, T4& t4)
  8340. {
  8341. return parse(data.data(),
  8342. data.data() + data.size(),
  8343. delimiters,
  8344. t1,t2,t3,
  8345. typename details::ca_type<T4, typename details::is_stl_container<T4>::result_t>::type(t4));
  8346. }
  8347. template <typename T1, typename T2, typename T3>
  8348. inline bool parse(const std::string& data,
  8349. const std::string& delimiters,
  8350. T1& t1, T2& t2, T3& t3)
  8351. {
  8352. return parse(data.data(),
  8353. data.data() + data.size(),
  8354. delimiters,
  8355. t1,t2,
  8356. typename details::ca_type<T3, typename details::is_stl_container<T3>::result_t>::type(t3));
  8357. }
  8358. template <typename T1, typename T2>
  8359. inline bool parse(const std::string& data,
  8360. const std::string& delimiters,
  8361. T1& t1, T2& t2)
  8362. {
  8363. return parse(data.data(),
  8364. data.data() + data.size(),
  8365. delimiters,
  8366. t1,
  8367. typename details::ca_type<T2, typename details::is_stl_container<T2>::result_t>::type(t2));
  8368. }
  8369. template <typename T>
  8370. inline bool parse(const std::string& data,
  8371. const std::string& delimiters,
  8372. T& t)
  8373. {
  8374. return parse(data.data(),
  8375. data.data() + data.size(),
  8376. delimiters,
  8377. typename details::ca_type<T,typename details::is_stl_container<T>::result_t>::type(t));
  8378. }
  8379. template <typename T,
  8380. typename Allocator,
  8381. template <typename,typename> class Sequence>
  8382. inline std::size_t parse(const std::string& data,
  8383. const std::string& delimiters,
  8384. Sequence<T,Allocator>& sequence,
  8385. const split_options::type& split_option = split_options::compress_delimiters)
  8386. {
  8387. return parse(data.data(),
  8388. data.data() + data.size(),
  8389. delimiters,
  8390. sequence,
  8391. split_option);
  8392. }
  8393. template <typename T,
  8394. typename Comparator,
  8395. typename Allocator>
  8396. inline std::size_t parse(const std::string& data,
  8397. const std::string& delimiters,
  8398. std::set<T,Comparator,Allocator>& set,
  8399. const split_options::type& split_option = split_options::compress_delimiters)
  8400. {
  8401. return parse(data.data(),
  8402. data.data() + data.size(),
  8403. delimiters,
  8404. set,
  8405. split_option);
  8406. }
  8407. template <typename T,
  8408. typename Comparator,
  8409. typename Allocator>
  8410. inline std::size_t parse(const std::string& data,
  8411. const std::string& delimiters,
  8412. std::multiset<T,Comparator,Allocator>& multiset,
  8413. const split_options::type& split_option = split_options::compress_delimiters)
  8414. {
  8415. return parse(data.data(),
  8416. data.data() + data.size(),
  8417. delimiters,
  8418. multiset,
  8419. split_option);
  8420. }
  8421. template <typename T,
  8422. typename Container>
  8423. inline std::size_t parse(const std::string& data,
  8424. const std::string& delimiters,
  8425. std::queue<T,Container>& queue,
  8426. const split_options::type& split_option = split_options::compress_delimiters)
  8427. {
  8428. return parse(data.data(),
  8429. data.data() + data.size(),
  8430. delimiters,
  8431. queue,
  8432. split_option);
  8433. }
  8434. template <typename T,
  8435. typename Container>
  8436. inline std::size_t parse(const std::string& data,
  8437. const std::string& delimiters,
  8438. std::stack<T,Container>& stack,
  8439. const split_options::type& split_option = split_options::compress_delimiters)
  8440. {
  8441. return parse(data.data(),
  8442. data.data() + data.size(),
  8443. delimiters,
  8444. stack,
  8445. split_option);
  8446. }
  8447. template <typename T,
  8448. typename Container,
  8449. typename Comparator>
  8450. inline std::size_t parse(const std::string& data,
  8451. const std::string& delimiters,
  8452. std::priority_queue<T,Container,Comparator>& priority_queue,
  8453. const split_options::type& split_option = split_options::compress_delimiters)
  8454. {
  8455. return parse(data.data(),
  8456. data.data() + data.size(),
  8457. delimiters,
  8458. priority_queue,
  8459. split_option);
  8460. }
  8461. template <typename T,
  8462. typename Allocator,
  8463. template <typename,typename> class Sequence>
  8464. inline std::size_t parse(const int& argc, char* argv[],
  8465. Sequence<T,Allocator>& sequence,
  8466. const bool break_on_fail = true)
  8467. {
  8468. T tmp;
  8469. for (int i = 0; i < argc; ++i)
  8470. {
  8471. if (!string_to_type_converter(std::string(argv[i]),tmp))
  8472. {
  8473. if (break_on_fail)
  8474. return i;
  8475. else
  8476. continue;
  8477. }
  8478. sequence.push_back(tmp);
  8479. }
  8480. return argc;
  8481. }
  8482. template <typename T1, typename T2, typename T3, typename T4,
  8483. typename T5, typename T6, typename T7, typename T8,
  8484. typename T9>
  8485. inline std::size_t parse(const int& argc, char* argv[],
  8486. T1& t1, T2& t2, T3& t3, T4& t4,
  8487. T5& t5, T6& t6, T7& t7, T8& t8,
  8488. T9& t9)
  8489. {
  8490. if (9 != argc) return 0;
  8491. std::size_t result = 0;
  8492. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8493. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8494. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8495. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8496. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8497. if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result;
  8498. if (!string_to_type_converter(std::string(argv[6]),t7)) return result; ++result;
  8499. if (!string_to_type_converter(std::string(argv[7]),t8)) return result; ++result;
  8500. if (!string_to_type_converter(std::string(argv[8]),t9)) return result; ++result;
  8501. return result;
  8502. }
  8503. template <typename T1, typename T2, typename T3, typename T4,
  8504. typename T5, typename T6, typename T7, typename T8>
  8505. inline std::size_t parse(const int& argc, char* argv[],
  8506. T1& t1, T2& t2, T3& t3, T4& t4,
  8507. T5& t5, T6& t6, T7& t7, T8& t8)
  8508. {
  8509. if (8 != argc) return 0;
  8510. std::size_t result = 0;
  8511. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8512. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8513. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8514. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8515. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8516. if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result;
  8517. if (!string_to_type_converter(std::string(argv[6]),t7)) return result; ++result;
  8518. if (!string_to_type_converter(std::string(argv[7]),t8)) return result; ++result;
  8519. return result;
  8520. }
  8521. template <typename T1, typename T2, typename T3, typename T4,
  8522. typename T5, typename T6, typename T7>
  8523. inline std::size_t parse(const int& argc, char* argv[],
  8524. T1& t1, T2& t2, T3& t3, T4& t4,
  8525. T5& t5, T6& t6, T7& t7)
  8526. {
  8527. if (7 != argc) return 0;
  8528. std::size_t result = 0;
  8529. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8530. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8531. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8532. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8533. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8534. if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result;
  8535. if (!string_to_type_converter(std::string(argv[6]),t7)) return result; ++result;
  8536. return result;
  8537. }
  8538. template <typename T1, typename T2, typename T3, typename T4,
  8539. typename T5, typename T6>
  8540. inline std::size_t parse(const int& argc, char* argv[],
  8541. T1& t1, T2& t2, T3& t3, T4& t4,
  8542. T5& t5, T6& t6)
  8543. {
  8544. if (6 != argc) return 0;
  8545. std::size_t result = 0;
  8546. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8547. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8548. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8549. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8550. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8551. if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result;
  8552. return result;
  8553. }
  8554. template <typename T1, typename T2, typename T3, typename T4, typename T5>
  8555. inline std::size_t parse(const int& argc, char* argv[],
  8556. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5)
  8557. {
  8558. if (5 != argc) return 0;
  8559. std::size_t result = 0;
  8560. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8561. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8562. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8563. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8564. if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result;
  8565. return result;
  8566. }
  8567. template <typename T1, typename T2, typename T3, typename T4>
  8568. inline std::size_t parse(const int& argc, char* argv[],
  8569. T1& t1, T2& t2, T3& t3, T4& t4)
  8570. {
  8571. if (4 != argc) return 0;
  8572. std::size_t result = 0;
  8573. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8574. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8575. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8576. if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result;
  8577. return result;
  8578. }
  8579. template <typename T1, typename T2, typename T3>
  8580. inline std::size_t parse(const int& argc, char* argv[],
  8581. T1& t1, T2& t2, T3& t3)
  8582. {
  8583. if (3 != argc) return 0;
  8584. std::size_t result = 0;
  8585. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8586. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8587. if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result;
  8588. return result;
  8589. }
  8590. template <typename T1, typename T2>
  8591. inline std::size_t parse(const int& argc, char* argv[],
  8592. T1& t1, T2& t2)
  8593. {
  8594. if (2 != argc) return 0;
  8595. std::size_t result = 0;
  8596. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8597. if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result;
  8598. return result;
  8599. }
  8600. template <typename T1>
  8601. inline std::size_t parse(const int& argc, char* argv[],
  8602. T1& t1)
  8603. {
  8604. if (1 != argc) return 0;
  8605. std::size_t result = 0;
  8606. if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result;
  8607. return result;
  8608. }
  8609. #define strtk_parse_begin(Type) \
  8610. namespace strtk { \
  8611. bool parse(const std::string& data, const std::string& delimiters, Type& t)\
  8612. { return parse(data,delimiters \
  8613. #define strtk_parse_type(T) \
  8614. ,t.T \
  8615. #define strtk_parse_hex_type(T) \
  8616. ,t.T \
  8617. #define strtk_parse_ignore_token() \
  8618. ,ignore_token() \
  8619. #define strtk_parse_end() \
  8620. );}} \
  8621. template <typename T,
  8622. typename Allocator,
  8623. template <typename,typename> class Sequence>
  8624. inline std::size_t parse_n(const std::string& data,
  8625. const std::string& delimiters,
  8626. const std::size_t& n,
  8627. Sequence<T,Allocator>& sequence,
  8628. const split_options::type& split_option = split_options::compress_delimiters)
  8629. {
  8630. return parse_n(data.data(),
  8631. data.data() + data.size(),
  8632. delimiters,
  8633. n,
  8634. sequence,
  8635. split_option);
  8636. }
  8637. template <typename T,
  8638. typename Comparator,
  8639. typename Allocator>
  8640. inline std::size_t parse_n(const std::string& data,
  8641. const std::string& delimiters,
  8642. const std::size_t& n,
  8643. std::set<T,Comparator,Allocator>& set,
  8644. const split_options::type& split_option = split_options::compress_delimiters)
  8645. {
  8646. return parse_n(data.data(),
  8647. data.data() + data.size(),
  8648. delimiters,
  8649. n,
  8650. set,
  8651. split_option);
  8652. }
  8653. template <typename T,
  8654. typename Comparator,
  8655. typename Allocator>
  8656. inline std::size_t parse_n(const std::string& data,
  8657. const std::string& delimiters,
  8658. const std::size_t& n,
  8659. std::multiset<T,Comparator,Allocator>& multiset,
  8660. const split_options::type& split_option = split_options::compress_delimiters)
  8661. {
  8662. return parse_n(data.data(),
  8663. data.data() + data.size(),
  8664. delimiters,
  8665. n,
  8666. multiset,
  8667. split_option);
  8668. }
  8669. template <typename T,
  8670. typename Container>
  8671. inline std::size_t parse_n(const std::string& data,
  8672. const std::string& delimiters,
  8673. const std::size_t& n,
  8674. std::queue<T,Container>& queue,
  8675. const split_options::type& split_option = split_options::compress_delimiters)
  8676. {
  8677. return parse_n(data.data(),
  8678. data.data() + data.size(),
  8679. delimiters,
  8680. n,
  8681. queue,
  8682. split_option);
  8683. }
  8684. template <typename T,
  8685. typename Container>
  8686. inline std::size_t parse_n(const std::string& data,
  8687. const std::string& delimiters,
  8688. const std::size_t& n,
  8689. std::stack<T,Container>& stack,
  8690. const split_options::type& split_option = split_options::compress_delimiters)
  8691. {
  8692. return parse_n(data.data(),
  8693. data.data() + data.size(),
  8694. delimiters,
  8695. n,
  8696. stack,
  8697. split_option);
  8698. }
  8699. template <typename T,
  8700. typename Container,
  8701. typename Comparator>
  8702. inline std::size_t parse_n(const std::string& data,
  8703. const std::string& delimiters,
  8704. const std::size_t& n,
  8705. std::priority_queue<T,Container,Comparator>& priority_queue,
  8706. const split_options::type& split_option = split_options::compress_delimiters)
  8707. {
  8708. return parse_n(data.data(),
  8709. data.data() + data.size(),
  8710. delimiters,
  8711. n,
  8712. priority_queue,
  8713. split_option);
  8714. }
  8715. template <typename T>
  8716. inline std::size_t parse_n(const std::string& data,
  8717. const std::string& delimiters,
  8718. const std::size_t& n,
  8719. T* out,
  8720. const split_options::type& split_option = split_options::compress_delimiters)
  8721. {
  8722. return parse_n(data.data(),
  8723. data.data() + data.size(),
  8724. delimiters,
  8725. n,
  8726. out,
  8727. split_option);
  8728. }
  8729. template <typename T1, typename T2, typename T3, typename T4,
  8730. typename T5, typename T6, typename T7, typename T8,
  8731. typename T9, typename T10, typename T11, typename T12>
  8732. inline bool parse_line(std::ifstream& stream,
  8733. const std::string& delimiters,
  8734. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8735. T7& t7, T8& t8, T9& t9, T10& t10, T11& t11, T12& t12)
  8736. {
  8737. if (!stream)
  8738. return false;
  8739. std::string data;
  8740. data.reserve(strtk::one_kilobyte);
  8741. if (!std::getline(stream,data))
  8742. return false;
  8743. if (data.empty() || delimiters.empty())
  8744. return false;
  8745. return strtk::parse(data.data(),
  8746. data.data() + data.size(),
  8747. delimiters,
  8748. t1,t2,t3,t4,t5,t6,
  8749. t7,t8,t9,t10,t11,t12);
  8750. }
  8751. template <typename T1, typename T2, typename T3, typename T4,
  8752. typename T5, typename T6, typename T7, typename T8,
  8753. typename T9, typename T10, typename T11>
  8754. inline bool parse_line(std::ifstream& stream,
  8755. const std::string& delimiters,
  8756. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8757. T7& t7, T8& t8, T9& t9, T10& t10, T11& t11)
  8758. {
  8759. if (!stream)
  8760. return false;
  8761. std::string data;
  8762. data.reserve(strtk::one_kilobyte);
  8763. if (!std::getline(stream,data))
  8764. return false;
  8765. if (data.empty() || delimiters.empty())
  8766. return false;
  8767. return strtk::parse(data.data(),
  8768. data.data() + data.size(),
  8769. delimiters,
  8770. t1,t2,t3,t4,t5,t6,
  8771. t7,t8,t9,t10,t11);
  8772. }
  8773. template <typename T1, typename T2, typename T3, typename T4,
  8774. typename T5, typename T6, typename T7, typename T8,
  8775. typename T9, typename T10>
  8776. inline bool parse_line(std::ifstream& stream,
  8777. const std::string& delimiters,
  8778. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8779. T7& t7, T8& t8, T9& t9, T10& t10)
  8780. {
  8781. if (!stream)
  8782. return false;
  8783. std::string data;
  8784. data.reserve(strtk::one_kilobyte);
  8785. if (!std::getline(stream,data))
  8786. return false;
  8787. if (data.empty() || delimiters.empty())
  8788. return false;
  8789. return strtk::parse(data.data(),
  8790. data.data() + data.size(),
  8791. delimiters,
  8792. t1,t2,t3,t4,t5,t6,
  8793. t7,t8,t9,t10);
  8794. }
  8795. template <typename T1, typename T2, typename T3, typename T4,
  8796. typename T5, typename T6, typename T7, typename T8,
  8797. typename T9>
  8798. inline bool parse_line(std::ifstream& stream,
  8799. const std::string& delimiters,
  8800. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8801. T7& t7, T8& t8, T9& t9)
  8802. {
  8803. if (!stream)
  8804. return false;
  8805. std::string data;
  8806. data.reserve(strtk::one_kilobyte);
  8807. if (!std::getline(stream,data))
  8808. return false;
  8809. if (data.empty() || delimiters.empty())
  8810. return false;
  8811. return strtk::parse(data.data(),
  8812. data.data() + data.size(),
  8813. delimiters,
  8814. t1,t2,t3,t4,t5,t6,
  8815. t7,t8,t9);
  8816. }
  8817. template <typename T1, typename T2, typename T3, typename T4,
  8818. typename T5, typename T6, typename T7, typename T8>
  8819. inline bool parse_line(std::ifstream& stream,
  8820. const std::string& delimiters,
  8821. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8822. T7& t7, T8& t8)
  8823. {
  8824. if (!stream)
  8825. return false;
  8826. std::string data;
  8827. data.reserve(strtk::one_kilobyte);
  8828. if (!std::getline(stream,data))
  8829. return false;
  8830. if (data.empty() || delimiters.empty())
  8831. return false;
  8832. return strtk::parse(data.data(),
  8833. data.data() + data.size(),
  8834. delimiters,
  8835. t1,t2,t3,t4,t5,t6,
  8836. t7,t8);
  8837. }
  8838. template <typename T1, typename T2, typename T3, typename T4,
  8839. typename T5, typename T6, typename T7>
  8840. inline bool parse_line(std::ifstream& stream,
  8841. const std::string& delimiters,
  8842. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  8843. T7& t7)
  8844. {
  8845. if (!stream)
  8846. return false;
  8847. std::string data;
  8848. data.reserve(strtk::one_kilobyte);
  8849. if (!std::getline(stream,data))
  8850. return false;
  8851. if (data.empty() || delimiters.empty())
  8852. return false;
  8853. return strtk::parse(data.data(),
  8854. data.data() + data.size(),
  8855. delimiters,
  8856. t1,t2,t3,t4,t5,t6,t7);
  8857. }
  8858. template <typename T1, typename T2, typename T3, typename T4,
  8859. typename T5, typename T6>
  8860. inline bool parse_line(std::ifstream& stream,
  8861. const std::string& delimiters,
  8862. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6)
  8863. {
  8864. if (!stream)
  8865. return false;
  8866. std::string data;
  8867. data.reserve(strtk::one_kilobyte);
  8868. if (!std::getline(stream,data))
  8869. return false;
  8870. if (data.empty() || delimiters.empty())
  8871. return false;
  8872. return strtk::parse(data.data(),
  8873. data.data() + data.size(),
  8874. delimiters,
  8875. t1,t2,t3,t4,t5,t6);
  8876. }
  8877. template <typename T1, typename T2, typename T3, typename T4,
  8878. typename T5>
  8879. inline bool parse_line(std::ifstream& stream,
  8880. const std::string& delimiters,
  8881. T1& t1, T2& t2, T3& t3, T4& t4, T5& t5)
  8882. {
  8883. if (!stream)
  8884. return false;
  8885. std::string data;
  8886. data.reserve(strtk::one_kilobyte);
  8887. if (!std::getline(stream,data))
  8888. return false;
  8889. if (data.empty() || delimiters.empty())
  8890. return false;
  8891. return strtk::parse(data.data(),
  8892. data.data() + data.size(),
  8893. delimiters,
  8894. t1,t2,t3,t4,t5);
  8895. }
  8896. template <typename T1, typename T2, typename T3, typename T4>
  8897. inline bool parse_line(std::ifstream& stream,
  8898. const std::string& delimiters,
  8899. T1& t1, T2& t2, T3& t3, T4& t4)
  8900. {
  8901. if (!stream)
  8902. return false;
  8903. std::string data;
  8904. data.reserve(strtk::one_kilobyte);
  8905. if (!std::getline(stream,data))
  8906. return false;
  8907. if (data.empty() || delimiters.empty())
  8908. return false;
  8909. return strtk::parse(data.data(),
  8910. data.data() + data.size(),
  8911. delimiters,
  8912. t1,t2,t3,t4);
  8913. }
  8914. template <typename T1, typename T2, typename T3>
  8915. inline bool parse_line(std::ifstream& stream,
  8916. const std::string& delimiters,
  8917. T1& t1, T2& t2, T3& t3)
  8918. {
  8919. if (!stream)
  8920. return false;
  8921. std::string data;
  8922. data.reserve(strtk::one_kilobyte);
  8923. if (!std::getline(stream,data))
  8924. return false;
  8925. if (data.empty() || delimiters.empty())
  8926. return false;
  8927. return strtk::parse(data.data(),
  8928. data.data() + data.size(),
  8929. delimiters,
  8930. t1,t2,t3);
  8931. }
  8932. template <typename T1, typename T2>
  8933. inline bool parse_line(std::ifstream& stream,
  8934. const std::string& delimiters,
  8935. T1& t1, T2& t2)
  8936. {
  8937. if (!stream)
  8938. return false;
  8939. std::string data;
  8940. data.reserve(strtk::one_kilobyte);
  8941. if (!std::getline(stream,data))
  8942. return false;
  8943. if (data.empty() || delimiters.empty())
  8944. return false;
  8945. return strtk::parse(data.data(),
  8946. data.data() + data.size(),
  8947. delimiters,
  8948. t1,t2);
  8949. }
  8950. template <typename T1>
  8951. inline bool parse_line(std::ifstream& stream,
  8952. const std::string& delimiters,
  8953. T1& t1)
  8954. {
  8955. if (!stream)
  8956. return false;
  8957. std::string data;
  8958. data.reserve(strtk::one_kilobyte);
  8959. if (!std::getline(stream,data))
  8960. return false;
  8961. if (data.empty() || delimiters.empty())
  8962. return false;
  8963. return strtk::parse(data.data(),
  8964. data.data() + data.size(),
  8965. delimiters,
  8966. t1);
  8967. }
  8968. template <typename T,
  8969. typename Allocator,
  8970. template <typename,typename> class Sequence>
  8971. inline std::size_t parse_line(std::ifstream& stream,
  8972. const std::string& delimiters,
  8973. Sequence<T,Allocator>& sequence,
  8974. const split_options::type& split_option = split_options::compress_delimiters)
  8975. {
  8976. if (!stream)
  8977. return 0;
  8978. std::string data;
  8979. data.reserve(strtk::one_kilobyte);
  8980. if (!std::getline(stream,data))
  8981. return 0;
  8982. if (data.empty() || delimiters.empty())
  8983. return false;
  8984. return strtk::parse(data.data(),
  8985. data.data() + data.size(),
  8986. delimiters,
  8987. sequence,
  8988. split_option);
  8989. }
  8990. template <typename T,
  8991. typename Comparator,
  8992. typename Allocator>
  8993. inline std::size_t parse_line(std::ifstream& stream,
  8994. const std::string& delimiters,
  8995. std::set<T,Comparator,Allocator>& set,
  8996. const split_options::type& split_option = split_options::compress_delimiters)
  8997. {
  8998. if (!stream)
  8999. return 0;
  9000. std::string data;
  9001. data.reserve(strtk::one_kilobyte);
  9002. if (!std::getline(stream,data))
  9003. return 0;
  9004. if (data.empty() || delimiters.empty())
  9005. return false;
  9006. return strtk::parse(data.data(),
  9007. data.data() + data.size(),
  9008. delimiters,
  9009. set,
  9010. split_option);
  9011. }
  9012. template <typename T,
  9013. typename Comparator,
  9014. typename Allocator>
  9015. inline std::size_t parse_line(std::ifstream& stream,
  9016. const std::string& delimiters,
  9017. std::multiset<T,Comparator,Allocator>& multiset,
  9018. const split_options::type& split_option = split_options::compress_delimiters)
  9019. {
  9020. if (!stream)
  9021. return 0;
  9022. std::string data;
  9023. data.reserve(strtk::one_kilobyte);
  9024. if (!std::getline(stream,data))
  9025. return 0;
  9026. if (data.empty() || delimiters.empty())
  9027. return false;
  9028. return strtk::parse(data.data(),
  9029. data.data() + data.size(),
  9030. delimiters,
  9031. multiset,
  9032. split_option);
  9033. }
  9034. template <typename T,
  9035. typename Container>
  9036. inline std::size_t parse_line(std::ifstream& stream,
  9037. const std::string& delimiters,
  9038. std::queue<T,Container>& queue,
  9039. const split_options::type& split_option = split_options::compress_delimiters)
  9040. {
  9041. if (!stream)
  9042. return 0;
  9043. std::string data;
  9044. data.reserve(strtk::one_kilobyte);
  9045. if (!std::getline(stream,data))
  9046. return 0;
  9047. if (data.empty() || delimiters.empty())
  9048. return false;
  9049. return strtk::parse(data.data(),
  9050. data.data() + data.size(),
  9051. delimiters,
  9052. queue,
  9053. split_option);
  9054. }
  9055. template <typename T,
  9056. typename Container>
  9057. inline std::size_t parse_line(std::ifstream& stream,
  9058. const std::string& delimiters,
  9059. std::stack<T,Container>& stack,
  9060. const split_options::type& split_option = split_options::compress_delimiters)
  9061. {
  9062. if (!stream)
  9063. return 0;
  9064. std::string data;
  9065. data.reserve(strtk::one_kilobyte);
  9066. if (!std::getline(stream,data))
  9067. return 0;
  9068. if (data.empty() || delimiters.empty())
  9069. return false;
  9070. return strtk::parse(data.data(),
  9071. data.data() + data.size(),
  9072. delimiters,
  9073. stack,
  9074. split_option);
  9075. }
  9076. template <typename T,
  9077. typename Container,
  9078. typename Comparator>
  9079. inline std::size_t parse_line(std::ifstream& stream,
  9080. const std::string& delimiters,
  9081. std::priority_queue<T,Container,Comparator>& priority_queue,
  9082. const split_options::type& split_option = split_options::compress_delimiters)
  9083. {
  9084. if (!stream)
  9085. return 0;
  9086. std::string data;
  9087. data.reserve(strtk::one_kilobyte);
  9088. if (!std::getline(stream,data))
  9089. return 0;
  9090. if (data.empty() || delimiters.empty())
  9091. return false;
  9092. return strtk::parse(data.data(),
  9093. data.data() + data.size(),
  9094. delimiters,
  9095. priority_queue,
  9096. split_option);
  9097. }
  9098. template <typename T,
  9099. typename Allocator,
  9100. template <typename,typename> class Sequence>
  9101. inline std::size_t parse_line_n(std::ifstream& stream,
  9102. const std::string& delimiters,
  9103. const std::size_t& n,
  9104. Sequence<T,Allocator>& sequence,
  9105. const split_options::type& split_option = split_options::compress_delimiters)
  9106. {
  9107. if (!stream)
  9108. return 0;
  9109. std::string data;
  9110. data.reserve(strtk::one_kilobyte);
  9111. if (!std::getline(stream,data))
  9112. return 0;
  9113. if (data.empty() || delimiters.empty())
  9114. return 0;
  9115. return strtk::parse_n(data.data(),
  9116. data.data() + data.size(),
  9117. delimiters,
  9118. n,
  9119. sequence,
  9120. split_option);
  9121. }
  9122. template <typename T,
  9123. typename Comparator,
  9124. typename Allocator>
  9125. inline std::size_t parse_line_n(std::ifstream& stream,
  9126. const std::string& delimiters,
  9127. const std::size_t& n,
  9128. std::set<T,Comparator,Allocator>& set,
  9129. const split_options::type& split_option = split_options::compress_delimiters)
  9130. {
  9131. if (!stream)
  9132. return 0;
  9133. std::string data;
  9134. data.reserve(strtk::one_kilobyte);
  9135. if (!std::getline(stream,data))
  9136. return 0;
  9137. if (data.empty() || delimiters.empty())
  9138. return 0;
  9139. return strtk::parse_n(data.data(),
  9140. data.data() + data.size(),
  9141. delimiters,
  9142. n,
  9143. set,
  9144. split_option);
  9145. }
  9146. template <typename T,
  9147. typename Comparator,
  9148. typename Allocator>
  9149. inline std::size_t parse_line_n(std::ifstream& stream,
  9150. const std::string& delimiters,
  9151. const std::size_t& n,
  9152. std::multiset<T,Comparator,Allocator>& multiset,
  9153. const split_options::type& split_option = split_options::compress_delimiters)
  9154. {
  9155. if (!stream)
  9156. return 0;
  9157. std::string data;
  9158. data.reserve(strtk::one_kilobyte);
  9159. if (!std::getline(stream,data))
  9160. return 0;
  9161. if (data.empty() || delimiters.empty())
  9162. return 0;
  9163. return strtk::parse_n(data.data(),
  9164. data.data() + data.size(),
  9165. delimiters,
  9166. n,
  9167. multiset,
  9168. split_option);
  9169. }
  9170. template <typename T,
  9171. typename Container>
  9172. inline std::size_t parse_line_n(std::ifstream& stream,
  9173. const std::string& delimiters,
  9174. const std::size_t& n,
  9175. std::queue<T,Container>& queue,
  9176. const split_options::type& split_option = split_options::compress_delimiters)
  9177. {
  9178. if (!stream)
  9179. return 0;
  9180. std::string data;
  9181. data.reserve(strtk::one_kilobyte);
  9182. if (!std::getline(stream,data))
  9183. return 0;
  9184. if (data.empty() || delimiters.empty())
  9185. return 0;
  9186. return strtk::parse_n(data.data(),
  9187. data.data() + data.size(),
  9188. delimiters,
  9189. n,
  9190. queue,
  9191. split_option);
  9192. }
  9193. template <typename T,
  9194. typename Container>
  9195. inline std::size_t parse_line_n(std::ifstream& stream,
  9196. const std::string& delimiters,
  9197. const std::size_t& n,
  9198. std::stack<T,Container>& stack,
  9199. const split_options::type& split_option = split_options::compress_delimiters)
  9200. {
  9201. if (!stream)
  9202. return 0;
  9203. std::string data;
  9204. data.reserve(strtk::one_kilobyte);
  9205. if (!std::getline(stream,data))
  9206. return 0;
  9207. if (data.empty() || delimiters.empty())
  9208. return 0;
  9209. return strtk::parse_n(data.data(),
  9210. data.data() + data.size(),
  9211. delimiters,
  9212. n,
  9213. stack,
  9214. split_option);
  9215. }
  9216. template <typename T,
  9217. typename Container,
  9218. typename Comparator>
  9219. inline std::size_t parse_line_n(std::ifstream& stream,
  9220. const std::string& delimiters,
  9221. const std::size_t& n,
  9222. std::priority_queue<T,Container,Comparator>& priority_queue,
  9223. const split_options::type& split_option = split_options::compress_delimiters)
  9224. {
  9225. if (!stream)
  9226. return 0;
  9227. std::string data;
  9228. data.reserve(strtk::one_kilobyte);
  9229. if (!std::getline(stream,data))
  9230. return 0;
  9231. if (data.empty() || delimiters.empty())
  9232. return 0;
  9233. return strtk::parse_n(data.data(),
  9234. data.data() + data.size(),
  9235. delimiters,
  9236. n,
  9237. priority_queue,
  9238. split_option);
  9239. }
  9240. template <typename T1, typename T2, typename T3, typename T4,
  9241. typename T5, typename T6, typename T7, typename T8,
  9242. typename T9, typename T10, typename T11, typename T12>
  9243. inline void construct(std::string& output,
  9244. const std::string& delimiter,
  9245. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9246. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  9247. const T9& t9, const T10& t10, const T11& t11, const T12& t12)
  9248. {
  9249. output += type_to_string( t1); output += delimiter;
  9250. output += type_to_string( t2); output += delimiter;
  9251. output += type_to_string( t3); output += delimiter;
  9252. output += type_to_string( t4); output += delimiter;
  9253. output += type_to_string( t5); output += delimiter;
  9254. output += type_to_string( t6); output += delimiter;
  9255. output += type_to_string( t7); output += delimiter;
  9256. output += type_to_string( t8); output += delimiter;
  9257. output += type_to_string( t9); output += delimiter;
  9258. output += type_to_string(t10); output += delimiter;
  9259. output += type_to_string(t11); output += delimiter;
  9260. output += type_to_string(t12);
  9261. }
  9262. template <typename T1, typename T2, typename T3, typename T4,
  9263. typename T5, typename T6, typename T7, typename T8,
  9264. typename T9, typename T10, typename T11>
  9265. inline void construct(std::string& output,
  9266. const std::string& delimiter,
  9267. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9268. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  9269. const T9& t9, const T10& t10, const T11& t11)
  9270. {
  9271. output += type_to_string( t1); output += delimiter;
  9272. output += type_to_string( t2); output += delimiter;
  9273. output += type_to_string( t3); output += delimiter;
  9274. output += type_to_string( t4); output += delimiter;
  9275. output += type_to_string( t5); output += delimiter;
  9276. output += type_to_string( t6); output += delimiter;
  9277. output += type_to_string( t7); output += delimiter;
  9278. output += type_to_string( t8); output += delimiter;
  9279. output += type_to_string( t9); output += delimiter;
  9280. output += type_to_string(t10); output += delimiter;
  9281. output += type_to_string(t11);
  9282. }
  9283. template <typename T1, typename T2, typename T3, typename T4,
  9284. typename T5, typename T6, typename T7, typename T8,
  9285. typename T9, typename T10>
  9286. inline void construct(std::string& output,
  9287. const std::string& delimiter,
  9288. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9289. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  9290. const T9& t9, const T10& t10)
  9291. {
  9292. output += type_to_string(t1); output += delimiter;
  9293. output += type_to_string(t2); output += delimiter;
  9294. output += type_to_string(t3); output += delimiter;
  9295. output += type_to_string(t4); output += delimiter;
  9296. output += type_to_string(t5); output += delimiter;
  9297. output += type_to_string(t6); output += delimiter;
  9298. output += type_to_string(t7); output += delimiter;
  9299. output += type_to_string(t8); output += delimiter;
  9300. output += type_to_string(t9); output += delimiter;
  9301. output += type_to_string(t10);
  9302. }
  9303. template <typename T1, typename T2, typename T3, typename T4,
  9304. typename T5, typename T6, typename T7, typename T8,
  9305. typename T9>
  9306. inline void construct(std::string& output,
  9307. const std::string& delimiter,
  9308. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9309. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  9310. const T9& t9)
  9311. {
  9312. output += type_to_string(t1); output += delimiter;
  9313. output += type_to_string(t2); output += delimiter;
  9314. output += type_to_string(t3); output += delimiter;
  9315. output += type_to_string(t4); output += delimiter;
  9316. output += type_to_string(t5); output += delimiter;
  9317. output += type_to_string(t6); output += delimiter;
  9318. output += type_to_string(t7); output += delimiter;
  9319. output += type_to_string(t8); output += delimiter;
  9320. output += type_to_string(t9);
  9321. }
  9322. template <typename T1, typename T2, typename T3, typename T4,
  9323. typename T5, typename T6, typename T7, typename T8>
  9324. inline void construct(std::string& output,
  9325. const std::string& delimiter,
  9326. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9327. const T5& t5, const T6& t6, const T7& t7, const T8& t8)
  9328. {
  9329. output += type_to_string(t1); output += delimiter;
  9330. output += type_to_string(t2); output += delimiter;
  9331. output += type_to_string(t3); output += delimiter;
  9332. output += type_to_string(t4); output += delimiter;
  9333. output += type_to_string(t5); output += delimiter;
  9334. output += type_to_string(t6); output += delimiter;
  9335. output += type_to_string(t7); output += delimiter;
  9336. output += type_to_string(t8);
  9337. }
  9338. template <typename T1, typename T2, typename T3, typename T4,
  9339. typename T5, typename T6, typename T7>
  9340. inline void construct(std::string& output,
  9341. const std::string& delimiter,
  9342. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9343. const T5& t5, const T6& t6, const T7& t7)
  9344. {
  9345. output += type_to_string(t1); output += delimiter;
  9346. output += type_to_string(t2); output += delimiter;
  9347. output += type_to_string(t3); output += delimiter;
  9348. output += type_to_string(t4); output += delimiter;
  9349. output += type_to_string(t5); output += delimiter;
  9350. output += type_to_string(t6); output += delimiter;
  9351. output += type_to_string(t7);
  9352. }
  9353. template <typename T1, typename T2, typename T3, typename T4,
  9354. typename T5,typename T6>
  9355. inline void construct(std::string& output,
  9356. const std::string& delimiter,
  9357. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9358. const T5& t5, const T6& t6)
  9359. {
  9360. output += type_to_string(t1); output += delimiter;
  9361. output += type_to_string(t2); output += delimiter;
  9362. output += type_to_string(t3); output += delimiter;
  9363. output += type_to_string(t4); output += delimiter;
  9364. output += type_to_string(t5); output += delimiter;
  9365. output += type_to_string(t6);
  9366. }
  9367. template <typename T1, typename T2, typename T3, typename T4,
  9368. typename T5>
  9369. inline void construct(std::string& output,
  9370. const std::string& delimiter,
  9371. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  9372. const T5& t5)
  9373. {
  9374. output += type_to_string(t1); output += delimiter;
  9375. output += type_to_string(t2); output += delimiter;
  9376. output += type_to_string(t3); output += delimiter;
  9377. output += type_to_string(t4); output += delimiter;
  9378. output += type_to_string(t5);
  9379. }
  9380. template <typename T1, typename T2, typename T3, typename T4>
  9381. inline void construct(std::string& output,
  9382. const std::string& delimiter,
  9383. const T1& t1, const T2& t2, const T3& t3, const T4& t4)
  9384. {
  9385. output += type_to_string(t1); output += delimiter;
  9386. output += type_to_string(t2); output += delimiter;
  9387. output += type_to_string(t3); output += delimiter;
  9388. output += type_to_string(t4);
  9389. }
  9390. template <typename T1, typename T2, typename T3>
  9391. inline void construct(std::string& output,
  9392. const std::string& delimiter,
  9393. const T1& t1, const T2& t2, const T3& t3)
  9394. {
  9395. output += type_to_string(t1); output += delimiter;
  9396. output += type_to_string(t2); output += delimiter;
  9397. output += type_to_string(t3);
  9398. }
  9399. template <typename T1, typename T2>
  9400. inline void construct(std::string& output,
  9401. const std::string& delimiter,
  9402. const T1& t1, const T2& t2)
  9403. {
  9404. output += type_to_string(t1); output += delimiter;
  9405. output += type_to_string(t2);
  9406. }
  9407. template <typename InputIterator>
  9408. inline void join(std::string& output,
  9409. const std::string& delimiter,
  9410. const InputIterator begin,
  9411. const InputIterator end)
  9412. {
  9413. InputIterator itr = begin;
  9414. while (end != itr)
  9415. {
  9416. output += type_to_string(*itr);
  9417. if (end == (++itr))
  9418. break;
  9419. else
  9420. output += delimiter;
  9421. }
  9422. }
  9423. template <typename InputIterator>
  9424. inline void join(std::string& output,
  9425. const std::string& delimiter,
  9426. const std::pair<InputIterator,InputIterator>& range)
  9427. {
  9428. InputIterator itr = range.first;
  9429. while (range.second != itr)
  9430. {
  9431. output += type_to_string(*itr);
  9432. if (range.second == (++itr))
  9433. break;
  9434. else
  9435. output += delimiter;
  9436. }
  9437. }
  9438. template <typename T,
  9439. typename Allocator,
  9440. template <typename,typename> class Sequence>
  9441. inline void join(std::string& output,
  9442. const std::string& delimiter,
  9443. const Sequence<T,Allocator>& sequence)
  9444. {
  9445. join(output,delimiter,sequence.begin(),sequence.end());
  9446. }
  9447. template <typename T,
  9448. typename Comparator,
  9449. typename Allocator>
  9450. inline void join(std::string& output,
  9451. const std::string& delimiter,
  9452. const std::set<T,Comparator,Allocator>& set)
  9453. {
  9454. join(output,delimiter,set.begin(),set.end());
  9455. }
  9456. template <typename T,
  9457. typename Comparator,
  9458. typename Allocator>
  9459. inline void join(std::string& output,
  9460. const std::string& delimiter,
  9461. const std::multiset<T,Comparator,Allocator>& multiset)
  9462. {
  9463. join(output,delimiter,multiset.begin(),multiset.end());
  9464. }
  9465. inline void join(std::string& output,
  9466. const std::string& delimiter,
  9467. int argc, char* argv[])
  9468. {
  9469. for (int i = 0; i < argc; ++i)
  9470. {
  9471. output += argv[i];
  9472. if (i < (argc - 1))
  9473. output += delimiter;
  9474. }
  9475. }
  9476. template <typename InputIterator>
  9477. inline std::string join(const std::string& delimiter,
  9478. const InputIterator begin,
  9479. const InputIterator end)
  9480. {
  9481. std::string output;
  9482. output.reserve(one_kilobyte);
  9483. join(output,delimiter,begin,end);
  9484. return output;
  9485. }
  9486. template <typename InputIterator>
  9487. inline std::string join(const std::string& delimiter,
  9488. const std::pair<InputIterator,InputIterator>& range)
  9489. {
  9490. std::string output;
  9491. output.reserve(one_kilobyte);
  9492. join(output,delimiter,range.first,range.second);
  9493. return output;
  9494. }
  9495. template <typename T,
  9496. typename Allocator,
  9497. template <typename,typename> class Sequence>
  9498. inline std::string join(const std::string& delimiter,
  9499. const Sequence<T,Allocator>& sequence)
  9500. {
  9501. if (sequence.empty())
  9502. return "";
  9503. else
  9504. return join(delimiter,sequence.begin(),sequence.end());
  9505. }
  9506. template <typename T,
  9507. typename Comparator,
  9508. typename Allocator>
  9509. inline std::string join(const std::string& delimiter,
  9510. const std::set<T,Comparator,Allocator>& set)
  9511. {
  9512. if (set.empty())
  9513. return "";
  9514. else
  9515. return join(delimiter,set.begin(),set.end());
  9516. }
  9517. template <typename T,
  9518. typename Comparator,
  9519. typename Allocator>
  9520. inline std::string join(const std::string& delimiter,
  9521. const std::multiset<T,Comparator,Allocator>& multiset)
  9522. {
  9523. if (multiset.empty())
  9524. return "";
  9525. else
  9526. return join(delimiter,multiset.begin(),multiset.end());
  9527. }
  9528. inline std::string join(const std::string& delimiter, int argc, char* argv[])
  9529. {
  9530. std::string result;
  9531. result.reserve(one_kilobyte);
  9532. join(result,delimiter,argc,argv);
  9533. return result;
  9534. }
  9535. template <typename InputIterator, typename Predicate>
  9536. inline void join_if(std::string& output,
  9537. const std::string& delimiter,
  9538. Predicate predicate,
  9539. const InputIterator begin,
  9540. const InputIterator end)
  9541. {
  9542. InputIterator itr = begin;
  9543. bool first_time = true;
  9544. while (end != itr)
  9545. {
  9546. if (predicate(*itr))
  9547. {
  9548. if (!first_time)
  9549. output += delimiter;
  9550. else
  9551. first_time = false;
  9552. output += type_to_string(*itr);
  9553. }
  9554. if (end == (++itr))
  9555. break;
  9556. }
  9557. }
  9558. template <typename InputIterator, typename Predicate>
  9559. inline void join_if(std::string& output,
  9560. const std::string& delimiter,
  9561. Predicate predicate,
  9562. const std::pair<InputIterator,InputIterator>& range)
  9563. {
  9564. InputIterator itr = range.first;
  9565. bool first_time = true;
  9566. while (range.second != itr)
  9567. {
  9568. if (predicate(*itr))
  9569. {
  9570. if (!first_time)
  9571. output += delimiter;
  9572. else
  9573. first_time = false;
  9574. output += type_to_string(*itr);
  9575. }
  9576. if (range.second == (++itr))
  9577. break;
  9578. }
  9579. }
  9580. template <typename T,
  9581. typename Predicate,
  9582. typename Allocator,
  9583. template <typename,typename> class Sequence>
  9584. inline void join_if(std::string& output,
  9585. const std::string& delimiter,
  9586. Predicate predicate,
  9587. const Sequence<T,Allocator>& sequence)
  9588. {
  9589. join_if(output,delimiter,predicate,sequence.begin(),sequence.end());
  9590. }
  9591. template <typename T,
  9592. typename Predicate,
  9593. typename Comparator,
  9594. typename Allocator>
  9595. inline void join_if(std::string& output,
  9596. const std::string& delimiter,
  9597. Predicate predicate,
  9598. const std::set<T,Comparator,Allocator>& set)
  9599. {
  9600. join_if(output,delimiter,predicate,set.begin(),set.end());
  9601. }
  9602. template <typename T,
  9603. typename Predicate,
  9604. typename Comparator,
  9605. typename Allocator>
  9606. inline void join_if(std::string& output,
  9607. const std::string& delimiter,
  9608. Predicate predicate,
  9609. const std::multiset<T,Comparator,Allocator>& multiset)
  9610. {
  9611. join_if(output,delimiter,predicate,multiset.begin(),multiset.end());
  9612. }
  9613. template <typename InputIterator, typename Predicate>
  9614. inline std::string join_if(const std::string& delimiter,
  9615. Predicate predicate,
  9616. const InputIterator begin,
  9617. const InputIterator end)
  9618. {
  9619. std::string output;
  9620. output.reserve(one_kilobyte);
  9621. join_if(output,delimiter,predicate,begin,end);
  9622. return output;
  9623. }
  9624. template <typename InputIterator, typename Predicate>
  9625. inline std::string join_if(const std::string& delimiter,
  9626. Predicate predicate,
  9627. const std::pair<InputIterator,InputIterator>& range)
  9628. {
  9629. std::string output;
  9630. output.reserve(one_kilobyte);
  9631. join_if(output,delimiter,predicate,range.first,range.second);
  9632. return output;
  9633. }
  9634. template <typename T,
  9635. typename Predicate,
  9636. typename Allocator,
  9637. template <typename,typename> class Sequence>
  9638. inline std::string join_if(const std::string& delimiter,
  9639. Predicate predicate,
  9640. const Sequence<T,Allocator>& sequence)
  9641. {
  9642. return join(delimiter,predicate,sequence.begin(),sequence.end());
  9643. }
  9644. template <typename T,
  9645. typename Predicate,
  9646. typename Comparator,
  9647. typename Allocator>
  9648. inline std::string join_if(const std::string& delimiter,
  9649. Predicate predicate,
  9650. const std::set<T,Comparator,Allocator>& set)
  9651. {
  9652. return join_if(delimiter,predicate,set.begin(),set.end());
  9653. }
  9654. template <typename T,
  9655. typename Predicate,
  9656. typename Comparator,
  9657. typename Allocator>
  9658. inline std::string join_if(const std::string& delimiter,
  9659. Predicate predicate,
  9660. const std::multiset<T,Comparator,Allocator>& multiset)
  9661. {
  9662. return join_if(delimiter,predicate,multiset.begin(),multiset.end());
  9663. }
  9664. class build_string
  9665. {
  9666. public:
  9667. build_string(const std::size_t& initial_size = 64)
  9668. {
  9669. data_.reserve(initial_size);
  9670. }
  9671. template <typename T>
  9672. inline build_string& operator << (const T& t)
  9673. {
  9674. data_ += type_to_string(t);
  9675. return (*this);
  9676. }
  9677. inline build_string& operator << (const std::string& s)
  9678. {
  9679. data_ += s;
  9680. return (*this);
  9681. }
  9682. inline std::string to_str() const
  9683. {
  9684. return data_;
  9685. }
  9686. inline operator const char* () const
  9687. {
  9688. return data_.data();
  9689. }
  9690. private:
  9691. std::string data_;
  9692. };
  9693. inline void replicate(const std::size_t& n,
  9694. const std::string& str,
  9695. std::string& output)
  9696. {
  9697. if (0 == n) return;
  9698. output.reserve(output.size() + (str.size() * n));
  9699. for (std::size_t i = 0; i < n; ++i)
  9700. {
  9701. output.append(str);
  9702. }
  9703. }
  9704. inline std::string replicate(const std::size_t& n,
  9705. const std::string& str)
  9706. {
  9707. std::string output;
  9708. replicate(n,str,output);
  9709. return output;
  9710. }
  9711. inline void replicate_inplace(const std::size_t& n,
  9712. std::string& str)
  9713. {
  9714. std::string temp_str = str;
  9715. str.reserve(str.size() + (str.size() * n));
  9716. for (std::size_t i = 0; i < n; ++i)
  9717. {
  9718. str.append(temp_str);
  9719. }
  9720. }
  9721. template <typename InputIterator>
  9722. inline void bracketize(std::string& output,
  9723. const std::string& pre,
  9724. const std::string& post,
  9725. const InputIterator begin,
  9726. const InputIterator end)
  9727. {
  9728. InputIterator itr = begin;
  9729. std::string s;
  9730. s.reserve(one_kilobyte);
  9731. while (end != itr)
  9732. {
  9733. s.clear();
  9734. s.append(pre);
  9735. s.append(type_to_string(*itr));
  9736. s.append(post);
  9737. output.append(s);
  9738. ++itr;
  9739. }
  9740. }
  9741. template <typename T,
  9742. typename Allocator,
  9743. template <typename,typename> class Sequence>
  9744. inline void bracketize(std::string& output,
  9745. const std::string& pre,
  9746. const std::string& post,
  9747. Sequence<T,Allocator>& sequence)
  9748. {
  9749. bracketize(output,pre,post,sequence.begin(),sequence.end());
  9750. }
  9751. template <typename T,
  9752. typename Comparator,
  9753. typename Allocator>
  9754. inline void bracketize(std::string& output,
  9755. const std::string& pre,
  9756. const std::string& post,
  9757. std::set<T,Comparator,Allocator>& set)
  9758. {
  9759. bracketize(output,pre,post,set.begin(),set.end());
  9760. }
  9761. template <typename T,
  9762. typename Comparator,
  9763. typename Allocator>
  9764. inline void bracketize(std::string& output,
  9765. const std::string& pre,
  9766. const std::string& post,
  9767. std::multiset<T,Comparator,Allocator>& multiset)
  9768. {
  9769. bracketize(output,pre,post,multiset.begin(),multiset.end());
  9770. }
  9771. template <typename InputIterator>
  9772. inline std::string bracketize(const std::string& pre,
  9773. const std::string& post,
  9774. const InputIterator begin,
  9775. const InputIterator end)
  9776. {
  9777. std::string output;
  9778. output.reserve(one_kilobyte);
  9779. bracketize(output,pre,post,begin,end);
  9780. return output;
  9781. }
  9782. template <typename T,
  9783. typename Allocator,
  9784. template <typename,typename> class Sequence>
  9785. inline std::string bracketize(const std::string& pre,
  9786. const std::string& post,
  9787. Sequence<T,Allocator>& sequence)
  9788. {
  9789. return bracketize(pre,post,sequence.begin(),sequence.end());
  9790. }
  9791. template <typename T,
  9792. typename Comparator,
  9793. typename Allocator>
  9794. inline std::string bracketize(const std::string& pre,
  9795. const std::string& post,
  9796. std::set<T,Comparator,Allocator>& set)
  9797. {
  9798. return bracketize(pre,post,set.begin(),set.end());
  9799. }
  9800. template <typename T,
  9801. typename Comparator,
  9802. typename Allocator>
  9803. inline std::string bracketize(const std::string& pre,
  9804. const std::string& post,
  9805. std::multiset<T,Comparator,Allocator>& multiset)
  9806. {
  9807. return bracketize(pre,post,multiset.begin(),multiset.end());
  9808. }
  9809. template <typename T>
  9810. struct interval_inserter
  9811. {
  9812. typedef T type;
  9813. interval_inserter(const std::size_t& interval, const T& t)
  9814. : count_(0),
  9815. interval_(interval),
  9816. t_(t)
  9817. {}
  9818. inline bool operator()(const type&)
  9819. {
  9820. if (++count_ == interval_)
  9821. {
  9822. count_ = 0;
  9823. return true;
  9824. }
  9825. else
  9826. return false;
  9827. }
  9828. inline T operator()()
  9829. {
  9830. return t_;
  9831. }
  9832. private:
  9833. std::size_t count_;
  9834. std::size_t interval_;
  9835. T t_;
  9836. };
  9837. template <typename Inserter,
  9838. typename InputIterator,
  9839. typename OutputIterator>
  9840. inline std::size_t inserter(Inserter ins,
  9841. const InputIterator begin, const InputIterator end,
  9842. OutputIterator out)
  9843. {
  9844. std::size_t size = 0;
  9845. InputIterator itr = begin;
  9846. while (end != itr)
  9847. {
  9848. (*out) = (*itr);
  9849. ++out;
  9850. if (ins(*itr++))
  9851. {
  9852. (*out) = ins();
  9853. ++out;
  9854. size += 2;
  9855. }
  9856. else
  9857. ++size;
  9858. }
  9859. return size;
  9860. }
  9861. template <typename Iterator, typename T>
  9862. inline void iota(Iterator begin, Iterator end, T value)
  9863. {
  9864. Iterator itr = begin;
  9865. while (end != itr)
  9866. {
  9867. (*itr) = value++;
  9868. ++itr;
  9869. }
  9870. }
  9871. template <typename T>
  9872. inline void iota(typename range::adapter<T>& r, T value)
  9873. {
  9874. iota(r.begin(),r.end(),value);
  9875. }
  9876. template <typename T,
  9877. typename Allocator,
  9878. template <typename,typename> class Sequence>
  9879. inline void iota(Sequence<T,Allocator>& sequence, std::size_t count, T value)
  9880. {
  9881. while (count)
  9882. {
  9883. sequence.push_back(value++);
  9884. --count;
  9885. }
  9886. }
  9887. template <typename T,
  9888. typename Comparator,
  9889. typename Allocator>
  9890. inline void iota(std::set<T,Comparator,Allocator>& set, std::size_t count, T value)
  9891. {
  9892. while (count)
  9893. {
  9894. set.insert(value++);
  9895. --count;
  9896. }
  9897. }
  9898. template <typename T,
  9899. typename Comparator,
  9900. typename Allocator>
  9901. inline void iota(std::multiset<T,Comparator,Allocator>& multiset, std::size_t count, T value)
  9902. {
  9903. while (count)
  9904. {
  9905. multiset.insert(value++);
  9906. --count;
  9907. }
  9908. }
  9909. template <typename OutputIterator, typename T>
  9910. inline void iota(std::size_t count, T value, OutputIterator out)
  9911. {
  9912. while (count)
  9913. {
  9914. (*out) = value++;
  9915. ++out;
  9916. --count;
  9917. }
  9918. }
  9919. template <typename T,
  9920. typename Allocator,
  9921. template <typename,typename> class Sequence>
  9922. inline void iota(Sequence<T,Allocator>& sequence, const T& value)
  9923. {
  9924. strtk::iota(sequence.begin(),sequence.end(),value);
  9925. }
  9926. template <typename T,
  9927. typename Comparator,
  9928. typename Allocator>
  9929. inline void iota(std::set<T,Comparator,Allocator>& set, const T& value)
  9930. {
  9931. strtk::iota(set.begin(),set.end(),value);
  9932. }
  9933. template <typename T,
  9934. typename Comparator,
  9935. typename Allocator>
  9936. inline void iota(std::multiset<T,Comparator,Allocator>& multiset, const T& value)
  9937. {
  9938. strtk::iota(multiset.begin(),multiset.end(),value);
  9939. }
  9940. template <typename InputIterator, typename OutputIterator>
  9941. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9942. const InputIterator begin, InputIterator end,
  9943. OutputIterator out)
  9944. {
  9945. // static assert: InputIterator must be of type std::string
  9946. InputIterator itr = begin;
  9947. while (end != itr)
  9948. {
  9949. const std::string& s = (*itr);
  9950. ++itr;
  9951. if (s.size() < r0)
  9952. continue;
  9953. (*out++) = s.substr(r0,std::min(r1,s.size()) - r0);
  9954. }
  9955. }
  9956. template <typename Allocator,
  9957. template <typename,typename> class Sequence,
  9958. typename OutputIterator>
  9959. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9960. const Sequence<std::string, Allocator>& sequence,
  9961. OutputIterator out)
  9962. {
  9963. cut(r0,r1,sequence.begin(),sequence.end(),out);
  9964. }
  9965. template <typename Iterator>
  9966. inline void cut_inplace(const std::size_t& r0, const std::size_t& r1,
  9967. const Iterator begin, const Iterator end)
  9968. {
  9969. // static assert: InputIterator must be of type std::string
  9970. Iterator itr = begin;
  9971. while (end != itr)
  9972. {
  9973. if ((*itr).size() >= r0)
  9974. {
  9975. (*itr) = (*itr).substr(r0,std::min(r1,(*itr).size()) - r0);
  9976. }
  9977. ++itr;
  9978. }
  9979. }
  9980. template <typename Allocator,
  9981. template <typename,typename> class Sequence>
  9982. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9983. const Sequence<std::string, Allocator>& sequence)
  9984. {
  9985. cut(r0,r1,sequence.begin(),sequence.end());
  9986. }
  9987. template <typename Comparator, typename Allocator>
  9988. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9989. const std::set<std::string, Comparator, Allocator>& set)
  9990. {
  9991. cut(r0,r1,set.begin(),set.end());
  9992. }
  9993. template <typename Comparator, typename Allocator>
  9994. inline void cut(const std::size_t& r0, const std::size_t& r1,
  9995. const std::multiset<std::string, Comparator, Allocator>& multiset)
  9996. {
  9997. cut(r0,r1,multiset.begin(),multiset.end());
  9998. }
  9999. class translation_table
  10000. {
  10001. public:
  10002. translation_table(const std::string& itable, const std::string& otable)
  10003. {
  10004. if (itable.size() != otable.size())
  10005. {
  10006. throw std::runtime_error("translation_table() - Input/Output table size mismatch.");
  10007. }
  10008. strtk::iota(table_, table_ + 256, static_cast<unsigned char>(0));
  10009. for (std::size_t i = 0; i < itable.size(); ++i)
  10010. {
  10011. table_[static_cast<unsigned int>(itable[i])] = static_cast<unsigned char>(otable[i]);
  10012. }
  10013. }
  10014. inline char operator()(const char c) const
  10015. {
  10016. return static_cast<char>(table_[static_cast<unsigned int>(c)]);
  10017. }
  10018. inline unsigned char operator()(const unsigned char c) const
  10019. {
  10020. return static_cast<unsigned char>(table_[static_cast<unsigned int>(c)]);
  10021. }
  10022. private:
  10023. unsigned char table_[256];
  10024. };
  10025. inline std::string translate(const translation_table& trans_table, const std::string& s)
  10026. {
  10027. std::string result = s;
  10028. std::transform(result.begin(),result.end(),result.begin(),trans_table);
  10029. return result;
  10030. }
  10031. inline void translate_inplace(const translation_table& trans_table, std::string& s)
  10032. {
  10033. std::transform(s.begin(),s.end(),s.begin(),trans_table);
  10034. }
  10035. #ifdef strtk_enable_random
  10036. inline void generate_random_data(unsigned char* data,
  10037. std::size_t length,
  10038. unsigned int pre_gen_cnt = 0,
  10039. unsigned int seed = magic_seed)
  10040. {
  10041. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  10042. boost::uniform_int<unsigned int> dist(std::numeric_limits<unsigned int>::min(),std::numeric_limits<unsigned int>::max());
  10043. boost::variate_generator<boost::mt19937&, boost::uniform_int<unsigned int> > rnd(rng,dist);
  10044. if (pre_gen_cnt > 0)
  10045. {
  10046. while (pre_gen_cnt--) rnd();
  10047. }
  10048. unsigned char* itr = data;
  10049. unsigned int* x = 0;
  10050. while (length >= sizeof(unsigned int))
  10051. {
  10052. x = reinterpret_cast<unsigned int*>(itr);
  10053. (*x) = rnd();
  10054. itr += sizeof(unsigned int);
  10055. length -= sizeof(unsigned int);
  10056. }
  10057. if (length > 0)
  10058. {
  10059. itr -= (sizeof(unsigned int) - length);
  10060. x = reinterpret_cast<unsigned int*>(itr);
  10061. (*x) = rnd();
  10062. }
  10063. }
  10064. namespace details
  10065. {
  10066. struct rand_int_type_tag {};
  10067. struct rand_real_type_tag {};
  10068. template <typename T> struct supported_random_type {};
  10069. #define strtk_register_rand_int_type_tag(T) \
  10070. template<> struct supported_random_type<T> { typedef rand_int_type_tag type; enum { value = true }; };
  10071. #define strtk_register_rand_real_type_tag(T) \
  10072. template<> struct supported_random_type<T> { typedef rand_real_type_tag type; enum { value = true }; };
  10073. strtk_register_rand_int_type_tag(char)
  10074. strtk_register_rand_int_type_tag(unsigned char)
  10075. strtk_register_rand_int_type_tag(short)
  10076. strtk_register_rand_int_type_tag(int)
  10077. strtk_register_rand_int_type_tag(long)
  10078. strtk_register_rand_int_type_tag(unsigned short)
  10079. strtk_register_rand_int_type_tag(unsigned int)
  10080. strtk_register_rand_int_type_tag(unsigned long)
  10081. strtk_register_rand_real_type_tag(float)
  10082. strtk_register_rand_real_type_tag(double)
  10083. strtk_register_rand_real_type_tag(long double)
  10084. #undef strtk_register_rand_int_type_tag
  10085. #undef strtk_register_rand_real_type_tag
  10086. template <typename T, typename OutputIterator, typename RandomNumberGenerator>
  10087. inline void generate_random_values_impl(const std::size_t& count,
  10088. const T& min,
  10089. const T& max,
  10090. OutputIterator out,
  10091. RandomNumberGenerator& rng,
  10092. rand_int_type_tag)
  10093. {
  10094. // Note: The implied range will be: [min,max]
  10095. using namespace boost;
  10096. variate_generator<RandomNumberGenerator&,uniform_int<T> > rnd(rng,uniform_int<T>(min,max));
  10097. for (std::size_t i = 0; i < count; ++i, *out++ = rnd()) ;
  10098. }
  10099. template <typename T, typename OutputIterator, typename RandomNumberGenerator>
  10100. inline void generate_random_values_impl(const std::size_t& count,
  10101. const T& min,
  10102. const T& max,
  10103. OutputIterator out,
  10104. RandomNumberGenerator& rng,
  10105. rand_real_type_tag)
  10106. {
  10107. // Note: The implied range will be: [min,max)
  10108. using namespace boost;
  10109. variate_generator<RandomNumberGenerator&, uniform_real<T> > rnd(rng,uniform_real<T>(min,max));
  10110. for (std::size_t i = 0; i < count; ++i, *out++ = rnd()) ;
  10111. }
  10112. } // namespace details
  10113. class uniform_real_rng
  10114. {
  10115. private:
  10116. typedef boost::mt19937 rng_type;
  10117. typedef boost::variate_generator<rng_type, boost::uniform_real<double> > variate_type;
  10118. public:
  10119. uniform_real_rng(const std::size_t& seed = magic_seed,
  10120. std::size_t pregen = 0)
  10121. : rng_(static_cast<rng_type::result_type>(seed)),
  10122. rnd_(rng_,boost::uniform_real<double>(0.0,1.0))
  10123. {
  10124. while (pregen--) rng_();
  10125. }
  10126. inline double operator()()
  10127. {
  10128. return rnd_();
  10129. }
  10130. private:
  10131. rng_type rng_;
  10132. variate_type rnd_;
  10133. };
  10134. template <typename T, typename OutputIterator>
  10135. inline void generate_random_values(const std::size_t& count,
  10136. const T& min,
  10137. const T& max,
  10138. OutputIterator out,
  10139. const std::size_t& seed = magic_seed,
  10140. const std::size_t& pregen = 0)
  10141. {
  10142. typename details::supported_random_type<T>::type type;
  10143. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  10144. for (std::size_t i = 0; i++ < pregen; rng()) ;
  10145. generate_random_values_impl(count,min,max,out,rng,type);
  10146. }
  10147. template <typename T,
  10148. typename Allocator,
  10149. template <typename,typename> class Sequence>
  10150. inline void generate_random_values(const std::size_t& count,
  10151. const T& min,
  10152. const T& max,
  10153. Sequence<T,Allocator>& sequence,
  10154. const std::size_t& seed = magic_seed,
  10155. const std::size_t& pregen = 0)
  10156. {
  10157. typename details::supported_random_type<T>::type type;
  10158. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  10159. for (std::size_t i = 0; i++ < pregen; rng()) ;
  10160. generate_random_values_impl(count,min,max,std::back_inserter(sequence),rng,type);
  10161. }
  10162. template <typename Iterator,
  10163. typename RandomNumberGenerator,
  10164. typename OutputIterator>
  10165. inline void random_permutation(const Iterator begin, const Iterator end,
  10166. RandomNumberGenerator& rng,
  10167. OutputIterator out)
  10168. {
  10169. const std::size_t size = std::distance(begin,end);
  10170. if ((rng. min() < 0.0) || (rng.max() > 1.0)) return;
  10171. std::deque<std::size_t> index;
  10172. for (std::size_t i = 0; i < size; index.push_back(i++)) ;
  10173. while (!index.empty())
  10174. {
  10175. std::size_t idx = static_cast<std::size_t>(index.size() * rng());
  10176. (*out) = *(begin + index[idx]);
  10177. index.erase(index.begin() + idx);
  10178. ++out;
  10179. }
  10180. }
  10181. template <typename Iterator,
  10182. typename OutputIterator>
  10183. inline void random_permutation(const Iterator begin, const Iterator end,
  10184. OutputIterator out,
  10185. const std::size_t& seed = magic_seed,
  10186. const std::size_t& pregen = 0)
  10187. {
  10188. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  10189. for (std::size_t i = 0; i++ < pregen; rng()) ;
  10190. boost::uniform_real<double> dist(0.0,1.0);
  10191. boost::variate_generator<boost::mt19937&, boost::uniform_real<double> > rnd(rng,dist);
  10192. random_permutation(begin,end,rnd,out);
  10193. }
  10194. template <typename T,
  10195. typename Allocator,
  10196. template <typename,typename> class Sequence,
  10197. typename OutputIterator>
  10198. inline void random_permutation(const Sequence<T,Allocator>& sequence,
  10199. OutputIterator out,
  10200. const std::size_t& seed = magic_seed,
  10201. const std::size_t& pregen = 0)
  10202. {
  10203. random_permutation(sequence.begin(),sequence.end(),out,seed,pregen);
  10204. }
  10205. template <typename Iterator,
  10206. typename RandomNumberGenerator,
  10207. typename OutputIterator>
  10208. inline bool random_combination(const Iterator begin, const Iterator end,
  10209. std::size_t set_size,
  10210. RandomNumberGenerator& rng,
  10211. OutputIterator out)
  10212. {
  10213. const std::size_t size = std::distance(begin,end);
  10214. if ((size < set_size) || (rng. min() < 0.0) || (rng.max() > 1.0)) return false;
  10215. std::deque<std::size_t> index;
  10216. for (std::size_t i = 0; i < size; index.push_back(i++)) ;
  10217. while (set_size)
  10218. {
  10219. std::size_t idx = static_cast<std::size_t>(index.size() * rng());
  10220. (*out) = *(begin + index[idx]);
  10221. index.erase(index.begin() + idx);
  10222. ++out;
  10223. --set_size;
  10224. }
  10225. return true;
  10226. }
  10227. template <typename Iterator,
  10228. typename OutputIterator>
  10229. inline void random_combination(const Iterator begin, const Iterator end,
  10230. const std::size_t& set_size,
  10231. OutputIterator out,
  10232. const std::size_t& seed = magic_seed,
  10233. const std::size_t& pregen = 0)
  10234. {
  10235. boost::mt19937 rng(static_cast<boost::mt19937::result_type>(seed));
  10236. for (std::size_t i = 0; i++ < pregen; rng()) ;
  10237. boost::uniform_real<double> dist(0.0,1.0);
  10238. boost::variate_generator<boost::mt19937&, boost::uniform_real<double> > rnd(rng,dist);
  10239. random_combination(begin,end,set_size,rnd,out);
  10240. }
  10241. template <typename T,
  10242. typename Allocator,
  10243. template <typename,typename> class Sequence,
  10244. typename OutputIterator>
  10245. inline void random_combination(const Sequence<T,Allocator>& sequence,
  10246. const std::size_t& set_size,
  10247. OutputIterator out,
  10248. const std::size_t& seed = magic_seed,
  10249. const std::size_t& pregen = 0)
  10250. {
  10251. random_combination(sequence.begin(),sequence.end(),set_size,out,seed,pregen);
  10252. }
  10253. template <typename Iterator,
  10254. typename OutputIterator,
  10255. typename RandomNumberGenerator>
  10256. inline std::size_t select_k_randomly(const Iterator begin, const Iterator end,
  10257. const std::size_t k,
  10258. OutputIterator out,
  10259. RandomNumberGenerator& rng)
  10260. {
  10261. typedef typename std::iterator_traits<Iterator>::value_type T;
  10262. std::vector<T> selection;
  10263. selection.resize(k);
  10264. Iterator itr = begin;
  10265. std::size_t index = 0;
  10266. while ((index < k) && (end != itr))
  10267. {
  10268. selection[index] = (*itr);
  10269. ++index;
  10270. ++itr;
  10271. }
  10272. if (0 == index)
  10273. return 0;
  10274. else if (index < k)
  10275. {
  10276. std::copy(selection.begin(),selection.begin() + index, out);
  10277. return index;
  10278. }
  10279. double n = k + 1;
  10280. while (end != itr)
  10281. {
  10282. if (rng() < (k / n))
  10283. {
  10284. selection[static_cast<std::size_t>(rng() * k)] = (*itr);
  10285. }
  10286. ++itr;
  10287. ++n;
  10288. }
  10289. std::copy(selection.begin(),selection.end(),out);
  10290. return k;
  10291. }
  10292. template <typename Iterator,
  10293. typename OutputIterator,
  10294. typename RandomNumberGenerator>
  10295. inline void select_1_randomly(const Iterator begin, const Iterator end,
  10296. OutputIterator out,
  10297. RandomNumberGenerator& rng)
  10298. {
  10299. typedef typename std::iterator_traits<Iterator>::value_type T;
  10300. T selection;
  10301. if (begin == end)
  10302. return;
  10303. Iterator itr = begin;
  10304. std::size_t n = 0;
  10305. while (end != itr)
  10306. {
  10307. if (rng() < (1.0 / ++n))
  10308. {
  10309. selection = (*itr);
  10310. }
  10311. ++itr;
  10312. }
  10313. (*out) = selection;
  10314. ++out;
  10315. }
  10316. #endif // strtk_enable_random
  10317. template <typename Iterator>
  10318. inline bool next_combination(const Iterator first, Iterator k, const Iterator last)
  10319. {
  10320. /* Credits: Thomas Draper */
  10321. if ((first == last) || (first == k) || (last == k))
  10322. return false;
  10323. Iterator itr1 = first;
  10324. Iterator itr2 = last;
  10325. ++itr1;
  10326. if (last == itr1)
  10327. return false;
  10328. itr1 = last;
  10329. --itr1;
  10330. itr1 = k;
  10331. --itr2;
  10332. while (first != itr1)
  10333. {
  10334. if (*--itr1 < (*itr2))
  10335. {
  10336. Iterator j = k;
  10337. while (!((*itr1) < (*j))) ++j;
  10338. std::iter_swap(itr1,j);
  10339. ++itr1;
  10340. ++j;
  10341. itr2 = k;
  10342. std::rotate(itr1,j,last);
  10343. while (last != j)
  10344. {
  10345. ++j;
  10346. ++itr2;
  10347. }
  10348. std::rotate(k,itr2,last);
  10349. return true;
  10350. }
  10351. }
  10352. std::rotate(first,k,last);
  10353. return false;
  10354. }
  10355. template <typename T,
  10356. typename Allocator,
  10357. template <typename,typename> class Sequence>
  10358. inline bool next_combination(Sequence<T,Allocator>& sequence, const std::size_t& size)
  10359. {
  10360. return next_combination(sequence.begin(), sequence.begin() + size, sequence.end());
  10361. }
  10362. template <typename Iterator, typename Function>
  10363. inline void for_each_permutation(Iterator begin, Iterator end, Function function)
  10364. {
  10365. do
  10366. {
  10367. function(begin,end);
  10368. }
  10369. while (std::next_permutation(begin,end));
  10370. }
  10371. template <typename Iterator, typename Function>
  10372. inline bool for_each_permutation_conditional(Iterator begin, Iterator end, Function function)
  10373. {
  10374. do
  10375. {
  10376. if (!function(begin,end))
  10377. return false;
  10378. }
  10379. while (std::next_permutation(begin,end));
  10380. return true;
  10381. }
  10382. namespace details
  10383. {
  10384. /*
  10385. Credits:
  10386. (C) Copyright Howard Hinnant 2005-2011.
  10387. Use, modification and distribution are subject to the Boost Software License,
  10388. Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  10389. http://www.boost.org/LICENSE_1_0.txt).
  10390. */
  10391. template <typename Iterator>
  10392. static inline void rotate_discontinuous(Iterator first1, Iterator last1,
  10393. typename std::iterator_traits<Iterator>::difference_type d1,
  10394. Iterator first2, Iterator last2,
  10395. typename std::iterator_traits<Iterator>::difference_type d2)
  10396. {
  10397. using std::swap;
  10398. if (d1 <= d2)
  10399. std::rotate(first2, std::swap_ranges(first1, last1, first2), last2);
  10400. else
  10401. {
  10402. Iterator i1 = last1;
  10403. while (first2 != last2)
  10404. {
  10405. swap(*--i1,*--last2);
  10406. }
  10407. std::rotate(first1, i1, last1);
  10408. }
  10409. }
  10410. template <typename Iterator, class Function>
  10411. inline void combine_discontinuous(Iterator first1, Iterator last1, typename std::iterator_traits<Iterator>::difference_type d1,
  10412. Iterator first2, Iterator last2, typename std::iterator_traits<Iterator>::difference_type d2,
  10413. Function& f,
  10414. typename std::iterator_traits<Iterator>::difference_type d = 0)
  10415. {
  10416. typedef typename std::iterator_traits<Iterator>::difference_type D;
  10417. using std::swap;
  10418. if ((0 == d1) || (0 == d2))
  10419. return f();
  10420. if (1 == d1)
  10421. {
  10422. Iterator i2 = first2;
  10423. while (i2 != last2)
  10424. {
  10425. f();
  10426. swap(*first1, *i2);
  10427. ++i2;
  10428. }
  10429. }
  10430. else
  10431. {
  10432. Iterator f1p = first1;
  10433. std::advance(f1p,1);
  10434. Iterator i2 = first2;
  10435. D d22 = d2;
  10436. while (i2 != last2)
  10437. {
  10438. combine_discontinuous(f1p, last1, d1 - 1, i2, last2, d22, f, d + 1);
  10439. swap(*first1, *i2);
  10440. ++i2;
  10441. --d22;
  10442. }
  10443. }
  10444. f();
  10445. if (0 != d)
  10446. {
  10447. Iterator f2p = first2;
  10448. std::advance(f2p,1);
  10449. rotate_discontinuous(first1, last1, d1, f2p, last2, d2 - 1);
  10450. }
  10451. else
  10452. rotate_discontinuous(first1, last1, d1, first2, last2, d2);
  10453. }
  10454. template <typename Iterator, class Function>
  10455. inline bool combine_discontinuous_conditional(Iterator first1, Iterator last1, typename std::iterator_traits<Iterator>::difference_type d1,
  10456. Iterator first2, Iterator last2, typename std::iterator_traits<Iterator>::difference_type d2,
  10457. Function& f,
  10458. typename std::iterator_traits<Iterator>::difference_type d = 0)
  10459. {
  10460. typedef typename std::iterator_traits<Iterator>::difference_type D;
  10461. using std::swap;
  10462. if (d1 == 0 || d2 == 0)
  10463. return f();
  10464. if (d1 == 1)
  10465. {
  10466. for (Iterator i2 = first2; i2 != last2; ++i2)
  10467. {
  10468. if (!f())
  10469. return false;
  10470. swap(*first1, *i2);
  10471. }
  10472. }
  10473. else
  10474. {
  10475. Iterator f1p = first1;
  10476. std::advance(f1p,1);
  10477. Iterator i2 = first2;
  10478. for (D d22 = d2; i2 != last2; ++i2, --d22)
  10479. {
  10480. if (!combine_discontinuous_conditional(f1p, last1, d1-1, i2, last2, d22, f, d + 1))
  10481. return false;
  10482. swap(*first1, *i2);
  10483. }
  10484. }
  10485. if (!f())
  10486. return false;
  10487. if (d != 0)
  10488. {
  10489. Iterator f2p = first2;
  10490. std::advance(f2p,1);
  10491. rotate_discontinuous(first1, last1, d1, f2p, last2, d2 - 1);
  10492. }
  10493. else
  10494. rotate_discontinuous(first1, last1, d1, first2, last2, d2);
  10495. return true;
  10496. }
  10497. template <class Function, typename Iterator>
  10498. class bound_range
  10499. {
  10500. public:
  10501. bound_range(Function f, Iterator first, Iterator last)
  10502. : f_(f),
  10503. first_(first),
  10504. last_(last)
  10505. {}
  10506. inline void operator()()
  10507. {
  10508. f_(first_,last_);
  10509. }
  10510. private:
  10511. inline bound_range& operator=(const bound_range&);
  10512. Function f_;
  10513. Iterator first_;
  10514. Iterator last_;
  10515. };
  10516. template <class Function, typename Iterator>
  10517. class bound_range_conditional
  10518. {
  10519. public:
  10520. bound_range_conditional(Function f, Iterator first, Iterator last)
  10521. : f_(f),
  10522. first_(first),
  10523. last_(last)
  10524. {}
  10525. inline bool operator()()
  10526. {
  10527. return f_(first_,last_);
  10528. }
  10529. private:
  10530. inline bound_range_conditional& operator=(const bound_range_conditional&);
  10531. Function f_;
  10532. Iterator first_;
  10533. Iterator last_;
  10534. };
  10535. }
  10536. template <typename Iterator, typename Function>
  10537. inline void for_each_combination(Iterator begin, Iterator end,
  10538. const std::size_t& size,
  10539. Function function)
  10540. {
  10541. if (static_cast<typename std::iterator_traits<Iterator>::difference_type>(size) > std::distance(begin,end))
  10542. return;
  10543. Iterator mid = begin + size;
  10544. details::bound_range<Function&,Iterator> func(function,begin,mid);
  10545. details::combine_discontinuous(begin, mid,
  10546. std::distance(begin,mid),
  10547. mid, end,
  10548. std::distance(mid,end),
  10549. func);
  10550. }
  10551. template <typename Iterator, typename Function>
  10552. inline void for_each_combination_conditional(Iterator begin, Iterator end,
  10553. const std::size_t& size,
  10554. Function function)
  10555. {
  10556. if (static_cast<typename std::iterator_traits<Iterator>::difference_type>(size) > std::distance(begin,end))
  10557. return;
  10558. Iterator mid = begin + size;
  10559. details::bound_range_conditional<Function&,Iterator> func(function,begin,mid);
  10560. details::combine_discontinuous_conditional(begin, mid,
  10561. std::distance(begin,mid),
  10562. mid, end,
  10563. std::distance(mid,end),
  10564. func);
  10565. }
  10566. inline unsigned long long int n_choose_k(const unsigned long long int& n, const unsigned long long int& k)
  10567. {
  10568. if (n < k) return 0;
  10569. if (0 == n) return 0;
  10570. if (0 == k) return 1;
  10571. if (n == k) return 1;
  10572. if (1 == k) return n;
  10573. typedef unsigned long long int value_type;
  10574. class n_choose_k_impl
  10575. {
  10576. public:
  10577. n_choose_k_impl(value_type* table, const value_type& dimension)
  10578. : table_(table),
  10579. dimension_(dimension / 2)
  10580. {}
  10581. inline value_type& lookup(const value_type& n, const value_type& k)
  10582. {
  10583. const std::size_t difference = static_cast<std::size_t>(n - k);
  10584. return table_[static_cast<std::size_t>((dimension_ * n) + std::min<value_type>(k,difference))];
  10585. }
  10586. inline value_type compute(const value_type& n, const value_type& k)
  10587. {
  10588. // n-Choose-k = (n-1)-Choose-(k-1) + (n-1)-Choose-k
  10589. if ((0 == k) || (k == n))
  10590. return 1;
  10591. value_type v1 = lookup(n - 1,k - 1);
  10592. if (0 == v1)
  10593. v1 = lookup(n - 1,k - 1) = compute(n - 1,k - 1);
  10594. value_type v2 = lookup(n - 1,k);
  10595. if (0 == v2)
  10596. v2 = lookup(n - 1,k) = compute(n - 1,k);
  10597. return v1 + v2;
  10598. }
  10599. value_type* table_;
  10600. const value_type dimension_;
  10601. private:
  10602. inline n_choose_k_impl& operator=(const n_choose_k_impl&)
  10603. {
  10604. return *this;
  10605. }
  10606. };
  10607. static const std::size_t static_table_dim = 100;
  10608. static const std::size_t static_table_size = static_cast<std::size_t>((static_table_dim * static_table_dim) / 2);
  10609. static value_type static_table[static_table_size];
  10610. static bool static_table_initialized = false;
  10611. if (!static_table_initialized && (n <= static_table_dim))
  10612. {
  10613. std::fill_n(static_table,static_table_size,0);
  10614. static_table_initialized = true;
  10615. }
  10616. const std::size_t table_size = static_cast<std::size_t>(n * (n / 2) + (n & 1));
  10617. unsigned long long int dimension = static_table_dim;
  10618. value_type* table = 0;
  10619. if (table_size <= static_table_size)
  10620. table = static_table;
  10621. else
  10622. {
  10623. dimension = n;
  10624. table = new value_type[table_size];
  10625. std::fill_n(table,table_size,0ULL);
  10626. }
  10627. value_type result = n_choose_k_impl(table,dimension).compute(n,k);
  10628. if (table != static_table)
  10629. delete [] table;
  10630. return result;
  10631. }
  10632. inline void initialize_n_choose_k()
  10633. {
  10634. const unsigned long long int max_n = 100ULL;
  10635. for (unsigned long long int n = 0; n < max_n; ++n)
  10636. {
  10637. for (unsigned long long int k = 0; k < max_n; ++k)
  10638. {
  10639. n_choose_k(n,k);
  10640. }
  10641. }
  10642. }
  10643. template <typename OutputIterator>
  10644. inline void nth_combination_sequence(unsigned long long int n,
  10645. const std::size_t& r,
  10646. const std::size_t& k,
  10647. OutputIterator out,
  10648. const bool complete_index = true)
  10649. {
  10650. //Compute the indicies for the n'th combination of r-choose-k
  10651. //n must be in the range [0,r-choose-k)
  10652. typedef unsigned long long int value_type;
  10653. std::vector<std::size_t> index_list(k,0);
  10654. value_type j = 0;
  10655. value_type x = 0;
  10656. ++n;
  10657. for (std::size_t i = 1; i <= (k - 1); ++i)
  10658. {
  10659. index_list[i - 1] = 0;
  10660. if (1 < i)
  10661. {
  10662. index_list[i - 1] = index_list[i - 2];
  10663. }
  10664. do
  10665. {
  10666. index_list[i - 1] += 1;
  10667. j = n_choose_k(r - index_list[i - 1], k - i);
  10668. x += j;
  10669. }
  10670. while (n > x);
  10671. x -= j;
  10672. }
  10673. index_list[k - 1] = index_list[k - 2] + static_cast<std::size_t>(n) - static_cast<std::size_t>(x);
  10674. for (std::size_t i = 0; i < index_list.size(); --index_list[i++]);
  10675. std::copy(index_list.begin(),index_list.end(),out);
  10676. if (complete_index)
  10677. {
  10678. std::vector<unsigned int> exist_table(r,0);
  10679. for (std::size_t i = 0; i < index_list.size(); ++i)
  10680. {
  10681. exist_table[index_list[i]] = 1;
  10682. }
  10683. for (std::size_t i = 0; i < exist_table.size(); ++i)
  10684. {
  10685. if (0 == exist_table[i])
  10686. {
  10687. (*out) = i;
  10688. ++out;
  10689. }
  10690. }
  10691. }
  10692. }
  10693. template <typename InputIterator, typename OutputIterator>
  10694. inline void nth_combination_sequence(const std::size_t& n,
  10695. const std::size_t& k,
  10696. const InputIterator begin,
  10697. const InputIterator end,
  10698. OutputIterator out,
  10699. const bool complete_index = true)
  10700. {
  10701. const std::size_t length = std::distance(begin,end);
  10702. std::vector<std::size_t> index_list;
  10703. nth_combination_sequence(n,length,k,std::back_inserter(index_list),complete_index);
  10704. for (std::size_t i = 0; i < index_list.size(); ++i)
  10705. {
  10706. (*out) = *(begin + index_list[i]);
  10707. ++out;
  10708. }
  10709. }
  10710. template <typename OutputIterator>
  10711. inline void nth_permutation_sequence(std::size_t n, const std::size_t k, OutputIterator out)
  10712. {
  10713. //Note: n in [0,k!)
  10714. std::vector<std::size_t> factorid (k,0);
  10715. std::vector<std::size_t> permutate(k,0);
  10716. factorid[0] = 1;
  10717. for (std::size_t i = 1; i < k; ++i)
  10718. {
  10719. factorid[i] = factorid[i - 1] * i;
  10720. }
  10721. for (std::size_t i = 0; i < k; ++i)
  10722. {
  10723. permutate[i] = n / factorid[k - i - 1];
  10724. n = n % factorid[k - i - 1];
  10725. }
  10726. for (std::size_t i = k - 1; i > 0; --i)
  10727. {
  10728. for (int j = static_cast<int>(i - 1); j >= 0; --j)
  10729. {
  10730. if (permutate[j] <= permutate[i])
  10731. {
  10732. ++permutate[i];
  10733. }
  10734. }
  10735. }
  10736. for (std::size_t i = 0; i < k; ++i)
  10737. {
  10738. *(out++) = permutate[i];
  10739. }
  10740. }
  10741. template <typename InputIterator, typename OutputIterator>
  10742. inline void nth_permutation_sequence(std::size_t n,
  10743. const InputIterator begin,
  10744. const InputIterator end,
  10745. OutputIterator out)
  10746. {
  10747. const std::size_t size = std::distance(begin,end);
  10748. std::vector<std::size_t> index_list(size,0);
  10749. nth_permutation_sequence(n,size,index_list.begin());
  10750. for (std::size_t i = 0; i < size; ++i)
  10751. {
  10752. *(out++) = (begin + index_list[i]);
  10753. }
  10754. }
  10755. inline std::string nth_permutation_sequence(const std::size_t& n, const std::string& s)
  10756. {
  10757. std::vector<std::size_t> index_list(s.size(),0);
  10758. nth_permutation_sequence(n,s.size(),index_list.begin());
  10759. std::string result;
  10760. result.reserve(s.size());
  10761. for (std::size_t i = 0; i < index_list.size(); ++i)
  10762. {
  10763. result += s[index_list[i]];
  10764. }
  10765. return result;
  10766. }
  10767. template <typename Iterator>
  10768. class combination_iterator : public std::iterator<std::forward_iterator_tag,
  10769. std::pair<Iterator,Iterator>,
  10770. void,
  10771. void>
  10772. {
  10773. public:
  10774. typedef Iterator iterator;
  10775. typedef const iterator const_iterator;
  10776. typedef std::pair<Iterator,Iterator> range_type;
  10777. explicit inline combination_iterator(const std::size_t& k,
  10778. iterator begin, iterator end,
  10779. const bool sorted = true)
  10780. : begin_(begin),
  10781. end_(end),
  10782. middle_(begin + k),
  10783. current_combination_(begin_,middle_)
  10784. {
  10785. if (!sorted)
  10786. {
  10787. std::sort(begin,end);
  10788. }
  10789. }
  10790. template <typename T,
  10791. typename Allocator,
  10792. template <typename,typename> class Sequence>
  10793. explicit inline combination_iterator(const std::size_t& k,
  10794. Sequence<T,Allocator>& seq,
  10795. const bool sorted = true)
  10796. : begin_(seq.begin()),
  10797. end_(seq.end()),
  10798. middle_(begin_ + k),
  10799. current_combination_(begin_,middle_)
  10800. {
  10801. if (!sorted)
  10802. {
  10803. std::sort(begin_,end_);
  10804. }
  10805. }
  10806. explicit inline combination_iterator(const std::size_t& k,
  10807. std::string& str,
  10808. const bool sorted = true)
  10809. : begin_(const_cast<char*>(str.data())),
  10810. end_(const_cast<char*>(str.data() + str.size())),
  10811. middle_(begin_ + k),
  10812. current_combination_(begin_,middle_)
  10813. {
  10814. if (!sorted)
  10815. {
  10816. std::sort(begin_,end_);
  10817. }
  10818. }
  10819. inline combination_iterator(iterator end)
  10820. : begin_(end),
  10821. end_(end),
  10822. middle_(end),
  10823. current_combination_(end,end)
  10824. {}
  10825. inline combination_iterator(const std::string& str)
  10826. : begin_(const_cast<char*>(str.data() + str.size())),
  10827. end_(begin_),
  10828. middle_(end_),
  10829. current_combination_(end_,end_)
  10830. {}
  10831. template <typename T,
  10832. typename Allocator,
  10833. template <typename,typename> class Sequence>
  10834. explicit inline combination_iterator(Sequence<T,Allocator>& seq)
  10835. : begin_(seq.end()),
  10836. end_(seq.end()),
  10837. middle_(end_),
  10838. current_combination_(end_,end_)
  10839. {}
  10840. inline combination_iterator& operator++()
  10841. {
  10842. if (begin_ != end_)
  10843. {
  10844. if (!next_combination(begin_,middle_,end_))
  10845. {
  10846. begin_ = middle_ = end_;
  10847. }
  10848. }
  10849. return (*this);
  10850. }
  10851. inline combination_iterator operator++(int)
  10852. {
  10853. combination_iterator tmp = *this;
  10854. this->operator++();
  10855. return tmp;
  10856. }
  10857. inline combination_iterator& operator+=(const int inc)
  10858. {
  10859. if (inc > 0)
  10860. {
  10861. for (int i = 0; i < inc; ++i, ++(*this)) ;
  10862. }
  10863. return (*this);
  10864. }
  10865. inline range_type operator*() const
  10866. {
  10867. return current_combination_;
  10868. }
  10869. inline bool operator==(const combination_iterator& itr) const
  10870. {
  10871. return (begin_ == itr.begin_ ) &&
  10872. (end_ == itr.end_ ) &&
  10873. (middle_ == itr.middle_);
  10874. }
  10875. inline bool operator!=(const combination_iterator& itr) const
  10876. {
  10877. return !operator==(itr);
  10878. }
  10879. protected:
  10880. iterator begin_;
  10881. iterator end_;
  10882. iterator middle_;
  10883. range_type current_combination_;
  10884. };
  10885. namespace fast
  10886. {
  10887. /*
  10888. Note: The following routines perform no sanity checks at all
  10889. upon the input data. Hence they should only be used with
  10890. data that is known to be completely 'valid'.
  10891. */
  10892. namespace details
  10893. {
  10894. template <typename Iterator, int N>
  10895. struct all_digits_check_impl
  10896. {
  10897. static inline bool process(Iterator)
  10898. {
  10899. throw std::runtime_error("all_digits_check_impl - unsupported value for N.");
  10900. }
  10901. };
  10902. template <typename Iterator>
  10903. struct all_digits_check_impl<Iterator,19>
  10904. {
  10905. static inline bool process(Iterator itr)
  10906. {
  10907. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10908. all_digits_check_impl<Iterator,18>::process(itr + 1);
  10909. }
  10910. };
  10911. template <typename Iterator>
  10912. struct all_digits_check_impl<Iterator,18>
  10913. {
  10914. static inline bool process(Iterator itr)
  10915. {
  10916. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10917. all_digits_check_impl<Iterator,17>::process(itr + 1);
  10918. }
  10919. };
  10920. template <typename Iterator>
  10921. struct all_digits_check_impl<Iterator,17>
  10922. {
  10923. static inline bool process(Iterator itr)
  10924. {
  10925. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  10926. all_digits_check_impl<Iterator,16>::process(itr + 1);
  10927. }
  10928. };
  10929. template <typename Iterator>
  10930. struct all_digits_check_impl<Iterator,16>
  10931. {
  10932. static inline bool process(Iterator itr)
  10933. {
  10934. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  10935. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  10936. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  10937. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  10938. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  10939. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  10940. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  10941. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  10942. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  10943. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  10944. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  10945. static_cast<unsigned char>(itr[11] - '0') < 10 &&
  10946. static_cast<unsigned char>(itr[12] - '0') < 10 &&
  10947. static_cast<unsigned char>(itr[13] - '0') < 10 &&
  10948. static_cast<unsigned char>(itr[14] - '0') < 10 &&
  10949. static_cast<unsigned char>(itr[15] - '0') < 10;
  10950. }
  10951. };
  10952. template <typename Iterator>
  10953. struct all_digits_check_impl<Iterator,15>
  10954. {
  10955. static inline bool process(Iterator itr)
  10956. {
  10957. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  10958. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  10959. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  10960. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  10961. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  10962. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  10963. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  10964. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  10965. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  10966. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  10967. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  10968. static_cast<unsigned char>(itr[11] - '0') < 10 &&
  10969. static_cast<unsigned char>(itr[12] - '0') < 10 &&
  10970. static_cast<unsigned char>(itr[13] - '0') < 10 &&
  10971. static_cast<unsigned char>(itr[14] - '0') < 10;
  10972. }
  10973. };
  10974. template <typename Iterator>
  10975. struct all_digits_check_impl<Iterator,14>
  10976. {
  10977. static inline bool process(Iterator itr)
  10978. {
  10979. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  10980. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  10981. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  10982. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  10983. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  10984. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  10985. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  10986. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  10987. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  10988. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  10989. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  10990. static_cast<unsigned char>(itr[11] - '0') < 10 &&
  10991. static_cast<unsigned char>(itr[12] - '0') < 10 &&
  10992. static_cast<unsigned char>(itr[13] - '0') < 10;
  10993. }
  10994. };
  10995. template <typename Iterator>
  10996. struct all_digits_check_impl<Iterator,13>
  10997. {
  10998. static inline bool process(Iterator itr)
  10999. {
  11000. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  11001. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  11002. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  11003. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  11004. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  11005. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  11006. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  11007. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  11008. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  11009. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  11010. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  11011. static_cast<unsigned char>(itr[11] - '0') < 10 &&
  11012. static_cast<unsigned char>(itr[12] - '0') < 10;
  11013. }
  11014. };
  11015. template <typename Iterator>
  11016. struct all_digits_check_impl<Iterator,12>
  11017. {
  11018. static inline bool process(Iterator itr)
  11019. {
  11020. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  11021. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  11022. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  11023. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  11024. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  11025. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  11026. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  11027. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  11028. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  11029. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  11030. static_cast<unsigned char>(itr[10] - '0') < 10 &&
  11031. static_cast<unsigned char>(itr[11] - '0') < 10;
  11032. }
  11033. };
  11034. template <typename Iterator>
  11035. struct all_digits_check_impl<Iterator,11>
  11036. {
  11037. static inline bool process(Iterator itr)
  11038. {
  11039. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  11040. static_cast<unsigned char>(itr[ 1] - '0') < 10 &&
  11041. static_cast<unsigned char>(itr[ 2] - '0') < 10 &&
  11042. static_cast<unsigned char>(itr[ 3] - '0') < 10 &&
  11043. static_cast<unsigned char>(itr[ 4] - '0') < 10 &&
  11044. static_cast<unsigned char>(itr[ 5] - '0') < 10 &&
  11045. static_cast<unsigned char>(itr[ 6] - '0') < 10 &&
  11046. static_cast<unsigned char>(itr[ 7] - '0') < 10 &&
  11047. static_cast<unsigned char>(itr[ 8] - '0') < 10 &&
  11048. static_cast<unsigned char>(itr[ 9] - '0') < 10 &&
  11049. static_cast<unsigned char>(itr[10] - '0') < 10;
  11050. }
  11051. };
  11052. template <typename Iterator>
  11053. struct all_digits_check_impl<Iterator,10>
  11054. {
  11055. static inline bool process(Iterator itr)
  11056. {
  11057. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11058. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11059. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11060. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  11061. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  11062. static_cast<unsigned char>(itr[5] - '0') < 10 &&
  11063. static_cast<unsigned char>(itr[6] - '0') < 10 &&
  11064. static_cast<unsigned char>(itr[7] - '0') < 10 &&
  11065. static_cast<unsigned char>(itr[8] - '0') < 10 &&
  11066. static_cast<unsigned char>(itr[9] - '0') < 10;
  11067. }
  11068. };
  11069. template <typename Iterator>
  11070. struct all_digits_check_impl<Iterator,9>
  11071. {
  11072. static inline bool process(Iterator itr)
  11073. {
  11074. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11075. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11076. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11077. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  11078. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  11079. static_cast<unsigned char>(itr[5] - '0') < 10 &&
  11080. static_cast<unsigned char>(itr[6] - '0') < 10 &&
  11081. static_cast<unsigned char>(itr[7] - '0') < 10 &&
  11082. static_cast<unsigned char>(itr[8] - '0') < 10;
  11083. }
  11084. };
  11085. template <typename Iterator>
  11086. struct all_digits_check_impl<Iterator,8>
  11087. {
  11088. static inline bool process(Iterator itr)
  11089. {
  11090. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11091. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11092. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11093. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  11094. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  11095. static_cast<unsigned char>(itr[5] - '0') < 10 &&
  11096. static_cast<unsigned char>(itr[6] - '0') < 10 &&
  11097. static_cast<unsigned char>(itr[7] - '0') < 10;
  11098. }
  11099. };
  11100. template <typename Iterator>
  11101. struct all_digits_check_impl<Iterator,7>
  11102. {
  11103. static inline bool process(Iterator itr)
  11104. {
  11105. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11106. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11107. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11108. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  11109. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  11110. static_cast<unsigned char>(itr[5] - '0') < 10 &&
  11111. static_cast<unsigned char>(itr[6] - '0') < 10;
  11112. }
  11113. };
  11114. template <typename Iterator>
  11115. struct all_digits_check_impl<Iterator,6>
  11116. {
  11117. static inline bool process(Iterator itr)
  11118. {
  11119. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11120. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11121. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11122. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  11123. static_cast<unsigned char>(itr[4] - '0') < 10 &&
  11124. static_cast<unsigned char>(itr[5] - '0') < 10;
  11125. }
  11126. };
  11127. template <typename Iterator>
  11128. struct all_digits_check_impl<Iterator,5>
  11129. {
  11130. static inline bool process(Iterator itr)
  11131. {
  11132. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11133. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11134. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11135. static_cast<unsigned char>(itr[3] - '0') < 10 &&
  11136. static_cast<unsigned char>(itr[4] - '0') < 10;
  11137. }
  11138. };
  11139. template <typename Iterator>
  11140. struct all_digits_check_impl<Iterator,4>
  11141. {
  11142. static inline bool process(Iterator itr)
  11143. {
  11144. return static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11145. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11146. static_cast<unsigned char>(itr[2] - '0') < 10 &&
  11147. static_cast<unsigned char>(itr[3] - '0') < 10;
  11148. }
  11149. };
  11150. template <typename Iterator>
  11151. struct all_digits_check_impl<Iterator,3>
  11152. {
  11153. static inline bool process(Iterator itr)
  11154. {
  11155. return
  11156. static_cast<unsigned char>(itr[0] - '0') < 10 &&
  11157. static_cast<unsigned char>(itr[1] - '0') < 10 &&
  11158. static_cast<unsigned char>(itr[2] - '0') < 10;
  11159. }
  11160. };
  11161. template <typename Iterator>
  11162. struct all_digits_check_impl<Iterator,2>
  11163. {
  11164. static inline bool process(Iterator itr)
  11165. {
  11166. return static_cast<unsigned char>(itr[ 0] - '0') < 10 &&
  11167. static_cast<unsigned char>(itr[ 1] - '0') < 10;
  11168. }
  11169. };
  11170. template <typename Iterator>
  11171. struct all_digits_check_impl<Iterator,1>
  11172. {
  11173. static inline bool process(Iterator itr)
  11174. {
  11175. return static_cast<unsigned char>(itr[ 0] - '0') < 10;
  11176. }
  11177. };
  11178. template <typename Iterator>
  11179. struct all_digits_check_impl<Iterator,0>
  11180. {
  11181. static inline bool process(Iterator)
  11182. {
  11183. return true;
  11184. }
  11185. };
  11186. template <typename T, typename Iterator, int N>
  11187. struct numeric_convert_impl
  11188. {
  11189. static inline void process(Iterator, T&)
  11190. { throw std::runtime_error("numeric_convert_impl::process( - unsupported value for N."); }
  11191. };
  11192. template <typename T, typename Iterator>
  11193. struct numeric_convert_impl<T,Iterator,19>
  11194. {
  11195. static inline void process(const Iterator itr, T& t)
  11196. {
  11197. strtk::fast::details::numeric_convert_impl<T,Iterator,18>::process(itr + 1,t);
  11198. t += static_cast<T>((itr[0] - '0') * 1000000000000000000LL);
  11199. }
  11200. };
  11201. template <typename T, typename Iterator>
  11202. struct numeric_convert_impl<T,Iterator,18>
  11203. {
  11204. static inline void process(const Iterator itr, T& t)
  11205. {
  11206. strtk::fast::details::numeric_convert_impl<T,Iterator,17>::process(itr + 1,t);
  11207. t += static_cast<T>((itr[0] - '0') * 100000000000000000LL);
  11208. }
  11209. };
  11210. template <typename T, typename Iterator>
  11211. struct numeric_convert_impl<T,Iterator,17>
  11212. {
  11213. static inline void process(const Iterator itr, T& t)
  11214. {
  11215. numeric_convert_impl<T,Iterator,16>::process(itr + 1,t);
  11216. t += static_cast<T>((itr[0] - '0') * 10000000000000000LL);
  11217. }
  11218. };
  11219. template <typename T, typename Iterator>
  11220. struct numeric_convert_impl<T,Iterator,16>
  11221. {
  11222. static inline void process(const Iterator itr, T& t)
  11223. {
  11224. T x = static_cast<T>(itr[ 0] - '0');
  11225. x = x * 10 + static_cast<T>(itr[ 1] - '0');
  11226. x = x * 10 + static_cast<T>(itr[ 2] - '0');
  11227. x = x * 10 + static_cast<T>(itr[ 3] - '0');
  11228. x = x * 10 + static_cast<T>(itr[ 4] - '0');
  11229. x = x * 10 + static_cast<T>(itr[ 5] - '0');
  11230. x = x * 10 + static_cast<T>(itr[ 6] - '0');
  11231. x = x * 10 + static_cast<T>(itr[ 7] - '0');
  11232. x = x * 10 + static_cast<T>(itr[ 8] - '0');
  11233. x = x * 10 + static_cast<T>(itr[ 9] - '0');
  11234. x = x * 10 + static_cast<T>(itr[10] - '0');
  11235. x = x * 10 + static_cast<T>(itr[11] - '0');
  11236. x = x * 10 + static_cast<T>(itr[12] - '0');
  11237. x = x * 10 + static_cast<T>(itr[13] - '0');
  11238. x = x * 10 + static_cast<T>(itr[14] - '0');
  11239. x = x * 10 + static_cast<T>(itr[15] - '0');
  11240. t = x;
  11241. }
  11242. };
  11243. template <typename T, typename Iterator>
  11244. struct numeric_convert_impl<T,Iterator,15>
  11245. {
  11246. static inline void process(const Iterator itr, T& t)
  11247. {
  11248. T x = static_cast<T>(itr[ 0] - '0');
  11249. x = x * 10 + static_cast<T>(itr[ 1] - '0');
  11250. x = x * 10 + static_cast<T>(itr[ 2] - '0');
  11251. x = x * 10 + static_cast<T>(itr[ 3] - '0');
  11252. x = x * 10 + static_cast<T>(itr[ 4] - '0');
  11253. x = x * 10 + static_cast<T>(itr[ 5] - '0');
  11254. x = x * 10 + static_cast<T>(itr[ 6] - '0');
  11255. x = x * 10 + static_cast<T>(itr[ 7] - '0');
  11256. x = x * 10 + static_cast<T>(itr[ 8] - '0');
  11257. x = x * 10 + static_cast<T>(itr[ 9] - '0');
  11258. x = x * 10 + static_cast<T>(itr[10] - '0');
  11259. x = x * 10 + static_cast<T>(itr[11] - '0');
  11260. x = x * 10 + static_cast<T>(itr[12] - '0');
  11261. x = x * 10 + static_cast<T>(itr[13] - '0');
  11262. x = x * 10 + static_cast<T>(itr[14] - '0');
  11263. t = x;
  11264. }
  11265. };
  11266. template <typename T, typename Iterator>
  11267. struct numeric_convert_impl<T,Iterator,14>
  11268. {
  11269. static inline void process(const Iterator itr, T& t)
  11270. {
  11271. T x = static_cast<T>(itr[ 0] - '0');
  11272. x = x * 10 + static_cast<T>(itr[ 1] - '0');
  11273. x = x * 10 + static_cast<T>(itr[ 2] - '0');
  11274. x = x * 10 + static_cast<T>(itr[ 3] - '0');
  11275. x = x * 10 + static_cast<T>(itr[ 4] - '0');
  11276. x = x * 10 + static_cast<T>(itr[ 5] - '0');
  11277. x = x * 10 + static_cast<T>(itr[ 6] - '0');
  11278. x = x * 10 + static_cast<T>(itr[ 7] - '0');
  11279. x = x * 10 + static_cast<T>(itr[ 8] - '0');
  11280. x = x * 10 + static_cast<T>(itr[ 9] - '0');
  11281. x = x * 10 + static_cast<T>(itr[10] - '0');
  11282. x = x * 10 + static_cast<T>(itr[11] - '0');
  11283. x = x * 10 + static_cast<T>(itr[12] - '0');
  11284. x = x * 10 + static_cast<T>(itr[13] - '0');
  11285. t = x;
  11286. }
  11287. };
  11288. template <typename T, typename Iterator>
  11289. struct numeric_convert_impl<T,Iterator,13>
  11290. {
  11291. static inline void process(const Iterator itr, T& t)
  11292. {
  11293. T x = static_cast<T>(itr[ 0] - '0');
  11294. x = x * 10 + static_cast<T>(itr[ 1] - '0');
  11295. x = x * 10 + static_cast<T>(itr[ 2] - '0');
  11296. x = x * 10 + static_cast<T>(itr[ 3] - '0');
  11297. x = x * 10 + static_cast<T>(itr[ 4] - '0');
  11298. x = x * 10 + static_cast<T>(itr[ 5] - '0');
  11299. x = x * 10 + static_cast<T>(itr[ 6] - '0');
  11300. x = x * 10 + static_cast<T>(itr[ 7] - '0');
  11301. x = x * 10 + static_cast<T>(itr[ 8] - '0');
  11302. x = x * 10 + static_cast<T>(itr[ 9] - '0');
  11303. x = x * 10 + static_cast<T>(itr[10] - '0');
  11304. x = x * 10 + static_cast<T>(itr[11] - '0');
  11305. x = x * 10 + static_cast<T>(itr[12] - '0');
  11306. t = x;
  11307. }
  11308. };
  11309. template <typename T, typename Iterator>
  11310. struct numeric_convert_impl<T,Iterator,12>
  11311. {
  11312. static inline void process(const Iterator itr, T& t)
  11313. {
  11314. T x = static_cast<T>(itr[ 0] - '0');
  11315. x = x * 10 + static_cast<T>(itr[ 1] - '0');
  11316. x = x * 10 + static_cast<T>(itr[ 2] - '0');
  11317. x = x * 10 + static_cast<T>(itr[ 3] - '0');
  11318. x = x * 10 + static_cast<T>(itr[ 4] - '0');
  11319. x = x * 10 + static_cast<T>(itr[ 5] - '0');
  11320. x = x * 10 + static_cast<T>(itr[ 6] - '0');
  11321. x = x * 10 + static_cast<T>(itr[ 7] - '0');
  11322. x = x * 10 + static_cast<T>(itr[ 8] - '0');
  11323. x = x * 10 + static_cast<T>(itr[ 9] - '0');
  11324. x = x * 10 + static_cast<T>(itr[10] - '0');
  11325. x = x * 10 + static_cast<T>(itr[11] - '0');
  11326. t = x;
  11327. }
  11328. };
  11329. template <typename T, typename Iterator>
  11330. struct numeric_convert_impl<T,Iterator,11>
  11331. {
  11332. static inline void process(const Iterator itr, T& t)
  11333. {
  11334. T x = static_cast<T>(itr[ 0] - '0');
  11335. x = x * 10 + static_cast<T>(itr[ 1] - '0');
  11336. x = x * 10 + static_cast<T>(itr[ 2] - '0');
  11337. x = x * 10 + static_cast<T>(itr[ 3] - '0');
  11338. x = x * 10 + static_cast<T>(itr[ 4] - '0');
  11339. x = x * 10 + static_cast<T>(itr[ 5] - '0');
  11340. x = x * 10 + static_cast<T>(itr[ 6] - '0');
  11341. x = x * 10 + static_cast<T>(itr[ 7] - '0');
  11342. x = x * 10 + static_cast<T>(itr[ 8] - '0');
  11343. x = x * 10 + static_cast<T>(itr[ 9] - '0');
  11344. x = x * 10 + static_cast<T>(itr[10] - '0');
  11345. t = x;
  11346. }
  11347. };
  11348. template <typename T, typename Iterator>
  11349. struct numeric_convert_impl<T,Iterator,10>
  11350. {
  11351. static inline void process(const Iterator itr, T& t)
  11352. {
  11353. T x = static_cast<T>(itr[0] - '0');
  11354. x = x * 10 + static_cast<T>(itr[1] - '0');
  11355. x = x * 10 + static_cast<T>(itr[2] - '0');
  11356. x = x * 10 + static_cast<T>(itr[3] - '0');
  11357. x = x * 10 + static_cast<T>(itr[4] - '0');
  11358. x = x * 10 + static_cast<T>(itr[5] - '0');
  11359. x = x * 10 + static_cast<T>(itr[6] - '0');
  11360. x = x * 10 + static_cast<T>(itr[7] - '0');
  11361. x = x * 10 + static_cast<T>(itr[8] - '0');
  11362. x = x * 10 + static_cast<T>(itr[9] - '0');
  11363. t = x;
  11364. }
  11365. };
  11366. template <typename T, typename Iterator>
  11367. struct numeric_convert_impl<T,Iterator,9>
  11368. {
  11369. static inline void process(const Iterator itr, T& t)
  11370. {
  11371. T x = static_cast<T>(itr[0] - '0');
  11372. x = x * 10 + static_cast<T>(itr[1] - '0');
  11373. x = x * 10 + static_cast<T>(itr[2] - '0');
  11374. x = x * 10 + static_cast<T>(itr[3] - '0');
  11375. x = x * 10 + static_cast<T>(itr[4] - '0');
  11376. x = x * 10 + static_cast<T>(itr[5] - '0');
  11377. x = x * 10 + static_cast<T>(itr[6] - '0');
  11378. x = x * 10 + static_cast<T>(itr[7] - '0');
  11379. x = x * 10 + static_cast<T>(itr[8] - '0');
  11380. t = x;
  11381. }
  11382. };
  11383. template <typename T, typename Iterator>
  11384. struct numeric_convert_impl<T,Iterator,8>
  11385. {
  11386. static inline void process(const Iterator itr, T& t)
  11387. {
  11388. T x = static_cast<T>(itr[0] - '0');
  11389. x = x * 10 + static_cast<T>(itr[1] - '0');
  11390. x = x * 10 + static_cast<T>(itr[2] - '0');
  11391. x = x * 10 + static_cast<T>(itr[3] - '0');
  11392. x = x * 10 + static_cast<T>(itr[4] - '0');
  11393. x = x * 10 + static_cast<T>(itr[5] - '0');
  11394. x = x * 10 + static_cast<T>(itr[6] - '0');
  11395. x = x * 10 + static_cast<T>(itr[7] - '0');
  11396. t = x;
  11397. }
  11398. };
  11399. template <typename T, typename Iterator>
  11400. struct numeric_convert_impl<T,Iterator,7>
  11401. {
  11402. static inline void process(const Iterator itr, T& t)
  11403. {
  11404. T x = static_cast<T>(itr[0] - '0');
  11405. x = x * 10 + static_cast<T>(itr[1] - '0');
  11406. x = x * 10 + static_cast<T>(itr[2] - '0');
  11407. x = x * 10 + static_cast<T>(itr[3] - '0');
  11408. x = x * 10 + static_cast<T>(itr[4] - '0');
  11409. x = x * 10 + static_cast<T>(itr[5] - '0');
  11410. x = x * 10 + static_cast<T>(itr[6] - '0');
  11411. t = x;
  11412. }
  11413. };
  11414. template <typename T, typename Iterator>
  11415. struct numeric_convert_impl<T,Iterator,6>
  11416. {
  11417. static inline void process(const Iterator itr, T& t)
  11418. {
  11419. T x = static_cast<T>(itr[0] - '0');
  11420. x = x * 10 + static_cast<T>(itr[1] - '0');
  11421. x = x * 10 + static_cast<T>(itr[2] - '0');
  11422. x = x * 10 + static_cast<T>(itr[3] - '0');
  11423. x = x * 10 + static_cast<T>(itr[4] - '0');
  11424. x = x * 10 + static_cast<T>(itr[5] - '0');
  11425. t = x;
  11426. }
  11427. };
  11428. template <typename T, typename Iterator>
  11429. struct numeric_convert_impl<T,Iterator,5>
  11430. {
  11431. static inline void process(const Iterator itr, T& t)
  11432. {
  11433. T x = static_cast<T>(itr[0] - '0');
  11434. x = x * 10 + static_cast<T>(itr[1] - '0');
  11435. x = x * 10 + static_cast<T>(itr[2] - '0');
  11436. x = x * 10 + static_cast<T>(itr[3] - '0');
  11437. x = x * 10 + static_cast<T>(itr[4] - '0');
  11438. t = x;
  11439. }
  11440. };
  11441. template <typename T, typename Iterator>
  11442. struct numeric_convert_impl<T,Iterator,4>
  11443. {
  11444. static inline void process(const Iterator itr, T& t)
  11445. {
  11446. T x = static_cast<T>(itr[0] - '0');
  11447. x = x * 10 + static_cast<T>(itr[1] - '0');
  11448. x = x * 10 + static_cast<T>(itr[2] - '0');
  11449. x = x * 10 + static_cast<T>(itr[3] - '0');
  11450. t = x;
  11451. }
  11452. };
  11453. template <typename T, typename Iterator>
  11454. struct numeric_convert_impl<T,Iterator,3>
  11455. {
  11456. static inline void process(const Iterator itr, T& t)
  11457. {
  11458. T x = static_cast<T>(itr[0] - '0');
  11459. x = x * 10 + static_cast<T>(itr[1] - '0');
  11460. x = x * 10 + static_cast<T>(itr[2] - '0');
  11461. t = x;
  11462. }
  11463. };
  11464. template <typename T, typename Iterator>
  11465. struct numeric_convert_impl<T,Iterator,2>
  11466. {
  11467. static inline void process(const Iterator itr, T& t)
  11468. {
  11469. t = static_cast<T>(itr[0] - '0') * 10 +
  11470. static_cast<T>(itr[1] - '0');
  11471. }
  11472. };
  11473. template <typename T, typename Iterator>
  11474. struct numeric_convert_impl<T,Iterator,1>
  11475. {
  11476. static inline void process(const Iterator itr, T& t)
  11477. {
  11478. t = static_cast<T>(itr[0] - '0');
  11479. }
  11480. };
  11481. template <typename T, typename Iterator>
  11482. struct numeric_convert_impl<T,Iterator,0>
  11483. {
  11484. static inline void process(const Iterator, T& t)
  11485. {
  11486. t = 0;
  11487. }
  11488. };
  11489. template <typename T, typename NoneSignedTag>
  11490. inline bool negate(T&, NoneSignedTag)
  11491. {
  11492. return false;
  11493. }
  11494. template <typename T>
  11495. inline bool negate(T& t, strtk::details::signed_type_tag)
  11496. {
  11497. t = -t;
  11498. return true;
  11499. }
  11500. } // namespace details
  11501. template <std::size_t N, typename Iterator>
  11502. inline bool all_digits_check(Iterator itr)
  11503. {
  11504. typedef typename strtk::details::is_valid_iterator<Iterator>::type itr_type;
  11505. strtk::details::convert_type_assert<itr_type>();
  11506. return details::all_digits_check_impl<Iterator,N>::process(itr);
  11507. }
  11508. template <std::size_t N>
  11509. inline bool all_digits_check(const std::string& s)
  11510. {
  11511. return all_digits_check<N,const char*>(s.data());
  11512. }
  11513. template <typename Iterator>
  11514. inline bool all_digits_check(const std::size_t& n, Iterator itr)
  11515. {
  11516. switch (n)
  11517. {
  11518. case 0 : return details::all_digits_check_impl<Iterator, 0>::process(itr);
  11519. case 1 : return details::all_digits_check_impl<Iterator, 1>::process(itr);
  11520. case 2 : return details::all_digits_check_impl<Iterator, 2>::process(itr);
  11521. case 3 : return details::all_digits_check_impl<Iterator, 3>::process(itr);
  11522. case 4 : return details::all_digits_check_impl<Iterator, 4>::process(itr);
  11523. case 5 : return details::all_digits_check_impl<Iterator, 5>::process(itr);
  11524. case 6 : return details::all_digits_check_impl<Iterator, 6>::process(itr);
  11525. case 7 : return details::all_digits_check_impl<Iterator, 7>::process(itr);
  11526. case 8 : return details::all_digits_check_impl<Iterator, 8>::process(itr);
  11527. case 9 : return details::all_digits_check_impl<Iterator, 9>::process(itr);
  11528. case 10 : return details::all_digits_check_impl<Iterator,10>::process(itr);
  11529. case 11 : return details::all_digits_check_impl<Iterator,11>::process(itr);
  11530. case 12 : return details::all_digits_check_impl<Iterator,12>::process(itr);
  11531. case 13 : return details::all_digits_check_impl<Iterator,13>::process(itr);
  11532. case 14 : return details::all_digits_check_impl<Iterator,14>::process(itr);
  11533. case 15 : return details::all_digits_check_impl<Iterator,15>::process(itr);
  11534. case 16 : return details::all_digits_check_impl<Iterator,16>::process(itr);
  11535. case 17 : return details::all_digits_check_impl<Iterator,17>::process(itr);
  11536. case 18 : return details::all_digits_check_impl<Iterator,18>::process(itr);
  11537. case 19 : return details::all_digits_check_impl<Iterator,19>::process(itr);
  11538. default : return false;
  11539. }
  11540. }
  11541. template <typename Iterator>
  11542. inline bool all_digits_check(Iterator begin, Iterator end)
  11543. {
  11544. return all_digits_check(std::distance(begin,end),begin);
  11545. }
  11546. inline bool all_digits_check(const std::string& s)
  11547. {
  11548. return all_digits_check(s.size(),s.data());
  11549. }
  11550. template <std::size_t N, typename Iterator>
  11551. inline bool signed_all_digits_check(Iterator itr)
  11552. {
  11553. if (('-' == (*itr)) || ('+' == (*itr)))
  11554. return all_digits_check<Iterator,N - 1>((itr + 1));
  11555. else
  11556. return all_digits_check<Iterator,N>(itr);
  11557. }
  11558. template <typename Iterator>
  11559. inline bool signed_all_digits_check(const std::size_t& n, Iterator itr)
  11560. {
  11561. if (('-' == (*itr)) || ('+' == (*itr)))
  11562. return all_digits_check(n - 1,(itr + 1));
  11563. else
  11564. return all_digits_check(n,itr);
  11565. }
  11566. template <std::size_t N>
  11567. inline bool signed_all_digits_check(const std::string& s)
  11568. {
  11569. return signed_all_digits_check<N,const char*>(s.data());
  11570. }
  11571. template <typename Iterator>
  11572. inline bool signed_all_digits_check(Iterator begin, Iterator end)
  11573. {
  11574. return signed_all_digits_check(std::distance(begin,end),begin);
  11575. }
  11576. inline bool signed_all_digits_check(const std::string& s)
  11577. {
  11578. return signed_all_digits_check(s.size(),s.data());
  11579. }
  11580. template <std::size_t N, typename T, typename Iterator>
  11581. inline void numeric_convert(Iterator itr, T& t, const bool digit_check = false)
  11582. {
  11583. typedef typename strtk::details::is_valid_iterator<Iterator>::type itr_type;
  11584. strtk::details::convert_type_assert<itr_type>();
  11585. if (digit_check)
  11586. {
  11587. if (!all_digits_check<N,Iterator>(itr))
  11588. {
  11589. t = 0;
  11590. return;
  11591. }
  11592. }
  11593. details::numeric_convert_impl<T,Iterator,N>::process(itr,t);
  11594. }
  11595. template <std::size_t N, typename T>
  11596. inline void numeric_convert(const std::string& s, T& t, const bool digit_check = false)
  11597. {
  11598. numeric_convert<N,T,const char*>(s.data(),t,digit_check);
  11599. }
  11600. template <typename T, typename Iterator>
  11601. inline bool numeric_convert(const std::size_t n,
  11602. const Iterator itr, T& t,
  11603. const bool digit_check = false)
  11604. {
  11605. if (digit_check)
  11606. {
  11607. if (!all_digits_check(n,itr))
  11608. {
  11609. return false;
  11610. }
  11611. }
  11612. switch (n)
  11613. {
  11614. case 0 : details::numeric_convert_impl<T,Iterator, 0>::process(itr,t); return true;
  11615. case 1 : details::numeric_convert_impl<T,Iterator, 1>::process(itr,t); return true;
  11616. case 2 : details::numeric_convert_impl<T,Iterator, 2>::process(itr,t); return true;
  11617. case 3 : details::numeric_convert_impl<T,Iterator, 3>::process(itr,t); return true;
  11618. case 4 : details::numeric_convert_impl<T,Iterator, 4>::process(itr,t); return true;
  11619. case 5 : details::numeric_convert_impl<T,Iterator, 5>::process(itr,t); return true;
  11620. case 6 : details::numeric_convert_impl<T,Iterator, 6>::process(itr,t); return true;
  11621. case 7 : details::numeric_convert_impl<T,Iterator, 7>::process(itr,t); return true;
  11622. case 8 : details::numeric_convert_impl<T,Iterator, 8>::process(itr,t); return true;
  11623. case 9 : details::numeric_convert_impl<T,Iterator, 9>::process(itr,t); return true;
  11624. case 10 : details::numeric_convert_impl<T,Iterator,10>::process(itr,t); return true;
  11625. case 11 : details::numeric_convert_impl<T,Iterator,11>::process(itr,t); return true;
  11626. case 12 : details::numeric_convert_impl<T,Iterator,12>::process(itr,t); return true;
  11627. case 13 : details::numeric_convert_impl<T,Iterator,13>::process(itr,t); return true;
  11628. case 14 : details::numeric_convert_impl<T,Iterator,14>::process(itr,t); return true;
  11629. case 15 : details::numeric_convert_impl<T,Iterator,15>::process(itr,t); return true;
  11630. case 16 : details::numeric_convert_impl<T,Iterator,16>::process(itr,t); return true;
  11631. case 17 : details::numeric_convert_impl<T,Iterator,17>::process(itr,t); return true;
  11632. case 18 : details::numeric_convert_impl<T,Iterator,18>::process(itr,t); return true;
  11633. case 19 : details::numeric_convert_impl<T,Iterator,19>::process(itr,t); return true;
  11634. default : return false;
  11635. }
  11636. }
  11637. template <typename T>
  11638. inline bool numeric_convert(const std::string& s, T& t, const bool digit_check = false)
  11639. {
  11640. return numeric_convert(s.size(),s.data(),t,digit_check);
  11641. }
  11642. template <std::size_t N, typename T, typename Iterator>
  11643. inline bool signed_numeric_convert(Iterator itr, T& t, const bool digit_check = false)
  11644. {
  11645. if ('-' == (*itr))
  11646. {
  11647. numeric_convert<N - 1,T,Iterator>((itr + 1),t,digit_check);
  11648. typename strtk::details::supported_conversion_to_type<T>::type type;
  11649. details::negate(t,type);
  11650. }
  11651. else if ('+' == (*itr))
  11652. {
  11653. return numeric_convert<N - 1,T,Iterator>((itr + 1),t,digit_check);
  11654. }
  11655. else
  11656. return numeric_convert<N,T,Iterator>(itr,t,digit_check);
  11657. }
  11658. template <typename T, typename Iterator>
  11659. inline bool signed_numeric_convert(Iterator itr,
  11660. const Iterator end,
  11661. T& t,
  11662. const bool digit_check = false)
  11663. {
  11664. const bool negative = ('-' == (*itr));
  11665. if (negative || ('+' == (*itr)))
  11666. {
  11667. if (end == (++itr))
  11668. return false;
  11669. }
  11670. while ((end != itr) && ('0' == (*itr))) ++itr;
  11671. if (numeric_convert(std::distance(itr,end),itr,t,digit_check))
  11672. {
  11673. t = negative ? -t : t;
  11674. return true;
  11675. }
  11676. else
  11677. return false;
  11678. }
  11679. template <std::size_t N, typename T>
  11680. inline bool signed_numeric_convert(const std::string& s,
  11681. T& t,
  11682. const bool digit_check = false)
  11683. {
  11684. return signed_numeric_convert<N,T,const char*>(s.data(),t,digit_check);
  11685. }
  11686. template <typename T>
  11687. inline bool signed_numeric_convert(const std::string& s,
  11688. T& t,
  11689. const bool digit_check = false)
  11690. {
  11691. return signed_numeric_convert<T,const char*>(s.data(),s.data() + s.size(),t,digit_check);
  11692. }
  11693. } // namespace fast
  11694. namespace binary
  11695. {
  11696. namespace details
  11697. {
  11698. namespace details_endian
  11699. {
  11700. #if (defined(__LITTLE_ENDIAN__)) || \
  11701. (defined(WIN32)) || \
  11702. (defined(_WIN32)) || \
  11703. (defined(__WIN32__)) || \
  11704. (defined(__MINGW32_VERSION)) || \
  11705. (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
  11706. static const bool __le_result = true;
  11707. static const bool __be_result = false;
  11708. #else
  11709. static const bool __le_result = false;
  11710. static const bool __be_result = true;
  11711. #endif
  11712. }
  11713. static inline bool is_little_endian()
  11714. {
  11715. //Is the current architecture/platform little-endian?
  11716. return details_endian::__le_result;
  11717. }
  11718. static inline bool is_big_endian()
  11719. {
  11720. return details_endian::__be_result;
  11721. }
  11722. static inline unsigned short convert(const unsigned short v)
  11723. {
  11724. //static_assert(2 == sizeof(v),"");
  11725. return ((v >> 8) & 0x00FF) | ((v << 8) & 0xFFFF);
  11726. }
  11727. static inline unsigned int convert(const unsigned int v)
  11728. {
  11729. //static_assert(4 == sizeof(v),"");
  11730. return ((v >> 24) & 0x000000FF) | ((v << 24) & 0x0000FF00) |
  11731. ((v << 8) & 0x00FF0000) | ((v >> 8) & 0xFF000000);
  11732. }
  11733. static inline unsigned long long int convert(const unsigned long long int v)
  11734. {
  11735. //static_assert(8 == sizeof(v),"");
  11736. return ((v >> 56) & 0x00000000000000FFLL) | ((v << 56) & 0xFF00000000000000LL) |
  11737. ((v >> 40) & 0x000000000000FF00LL) | ((v << 40) & 0x00FF000000000000LL) |
  11738. ((v >> 24) & 0x0000000000FF0000LL) | ((v << 24) & 0x0000FF0000000000LL) |
  11739. ((v >> 8) & 0x00000000FF000000LL) | ((v << 8) & 0x000000FF00000000LL) ;
  11740. }
  11741. static inline short convert(const short v)
  11742. {
  11743. return static_cast<short>(convert(static_cast<unsigned short>(v)));
  11744. }
  11745. static inline int convert(const int v)
  11746. {
  11747. return static_cast<int>(convert(static_cast<unsigned int>(v)));
  11748. }
  11749. static inline long long int convert(const long long int v)
  11750. {
  11751. return static_cast<long long>(convert(static_cast<unsigned long long int>(v)));
  11752. }
  11753. static inline unsigned short convert_to_be(const unsigned short v)
  11754. {
  11755. return (is_little_endian()) ? convert(v) : v;
  11756. }
  11757. static inline unsigned int convert_to_be(const unsigned int v)
  11758. {
  11759. return (is_little_endian()) ? convert(v) : v;
  11760. }
  11761. static inline unsigned long long int convert_to_be(const unsigned long long int v)
  11762. {
  11763. return (is_little_endian()) ? convert(v) : v;
  11764. }
  11765. static inline short convert_to_be(const short v)
  11766. {
  11767. return (is_little_endian()) ? convert(v) : v;
  11768. }
  11769. static inline int convert_to_be(const int v)
  11770. {
  11771. return (is_little_endian()) ? convert(v) : v;
  11772. }
  11773. static inline long long int convert_to_be(const long long int v)
  11774. {
  11775. return (is_little_endian()) ? convert(v) : v;
  11776. }
  11777. static inline unsigned short convert_to_le(const unsigned short v)
  11778. {
  11779. return (is_big_endian()) ? convert(v) : v;
  11780. }
  11781. static inline unsigned int convert_to_le(const unsigned int v)
  11782. {
  11783. return (is_big_endian()) ? convert(v) : v;
  11784. }
  11785. static inline unsigned long long int convert_to_le(const unsigned long long int v)
  11786. {
  11787. return (is_big_endian()) ? convert(v) : v;
  11788. }
  11789. static inline short convert_to_le(const short v)
  11790. {
  11791. return (is_big_endian()) ? convert(v) : v;
  11792. }
  11793. static inline int convert_to_le(const int v)
  11794. {
  11795. return (is_big_endian()) ? convert(v) : v;
  11796. }
  11797. static inline unsigned long long int convert_to_le(const long long int v)
  11798. {
  11799. return (is_big_endian()) ? convert(v) : v;
  11800. }
  11801. class marker
  11802. {
  11803. private:
  11804. typedef std::pair<std::size_t,char*> mark_type;
  11805. public:
  11806. inline bool reset(std::size_t& v1, char*& v2)
  11807. {
  11808. if (stack_.empty())
  11809. return false;
  11810. v1 = stack_.top().first;
  11811. v2 = stack_.top().second;
  11812. stack_.pop();
  11813. return true;
  11814. }
  11815. inline void mark(const std::size_t& v1,char* v2)
  11816. {
  11817. stack_.push(std::make_pair(v1,v2));
  11818. }
  11819. private:
  11820. std::stack<mark_type> stack_;
  11821. };
  11822. }
  11823. class reader
  11824. {
  11825. public:
  11826. // should be sourced from cstdint
  11827. typedef unsigned int uint32_t;
  11828. typedef unsigned short uint16_t;
  11829. typedef unsigned char uint8_t;
  11830. typedef unsigned long long int uint64_t;
  11831. template <typename T>
  11832. reader(T* buffer,
  11833. const std::size_t& buffer_length)
  11834. : original_buffer_(reinterpret_cast<char*>(buffer)),
  11835. buffer_(reinterpret_cast<char*>(buffer)),
  11836. buffer_length_(buffer_length * sizeof(T)),
  11837. amount_read_sofar_(0)
  11838. {}
  11839. inline bool operator!() const
  11840. {
  11841. return (0 == buffer_length_) ||
  11842. (0 == original_buffer_) ||
  11843. (0 == buffer_);
  11844. }
  11845. inline void reset(const bool clear_buffer = false)
  11846. {
  11847. amount_read_sofar_ = 0;
  11848. buffer_ = original_buffer_;
  11849. if (clear_buffer)
  11850. clear();
  11851. }
  11852. inline std::size_t position() const
  11853. {
  11854. return amount_read_sofar_;
  11855. }
  11856. inline const char* position_ptr() const
  11857. {
  11858. return buffer_ ;
  11859. }
  11860. inline std::size_t amount_read()
  11861. {
  11862. return amount_read_sofar_;
  11863. }
  11864. inline bool rewind(const std::size_t& n_bytes)
  11865. {
  11866. if (n_bytes <= amount_read_sofar_)
  11867. {
  11868. amount_read_sofar_ -= n_bytes;
  11869. buffer_ -= n_bytes;
  11870. return true;
  11871. }
  11872. else
  11873. return false;
  11874. }
  11875. inline bool seek(const int& n_bytes)
  11876. {
  11877. if (n_bytes < 0)
  11878. return rewind(-n_bytes);
  11879. else if (n_bytes > 0)
  11880. {
  11881. if ((amount_read_sofar_ + n_bytes) <= buffer_length_)
  11882. {
  11883. amount_read_sofar_ += n_bytes;
  11884. buffer_ += n_bytes;
  11885. return true;
  11886. }
  11887. else
  11888. return false;
  11889. }
  11890. else
  11891. return true;
  11892. }
  11893. inline void clear()
  11894. {
  11895. reset();
  11896. std::memset(buffer_,0x00,buffer_length_);
  11897. }
  11898. template <typename T>
  11899. inline bool operator()(T*& data, uint32_t& length, const bool read_length = true)
  11900. {
  11901. if (read_length && !operator()(length))
  11902. return false;
  11903. const std::size_t raw_size = length * sizeof(T);
  11904. if (!buffer_capacity_ok(raw_size))
  11905. return false;
  11906. if (read_length)
  11907. {
  11908. data = new T[length];
  11909. }
  11910. std::copy(buffer_, buffer_ + raw_size, reinterpret_cast<char*>(data));
  11911. buffer_ += raw_size;
  11912. amount_read_sofar_ += raw_size;
  11913. return true;
  11914. }
  11915. template <typename T>
  11916. inline bool operator()(T*& data, uint64_t& length, const bool read_length = true)
  11917. {
  11918. uint32_t l = 0;
  11919. if (read_length)
  11920. l = static_cast<uint32_t>(length);
  11921. if (!operator()(data,l,read_length))
  11922. return false;
  11923. if (read_length)
  11924. length = l;
  11925. return true;
  11926. }
  11927. inline bool operator()(std::string& output)
  11928. {
  11929. uint32_t length = 0;
  11930. if (!operator()(length))
  11931. return false;
  11932. if (!buffer_capacity_ok(length))
  11933. return false;
  11934. output.resize(length);
  11935. std::copy(buffer_,
  11936. buffer_ + length,
  11937. const_cast<char*>(output.data()));
  11938. buffer_ += length;
  11939. amount_read_sofar_ += length;
  11940. return true;
  11941. }
  11942. template <typename T1, typename T2>
  11943. inline bool operator()(std::pair<T1,T2>& p)
  11944. {
  11945. if (!operator()(p.first))
  11946. return false;
  11947. if (!operator()(p.second))
  11948. return false;
  11949. return true;
  11950. }
  11951. template <typename T,
  11952. typename Allocator,
  11953. template <typename,typename> class Sequence>
  11954. inline bool operator()(Sequence<T,Allocator>& seq)
  11955. {
  11956. uint32_t size = 0;
  11957. if (!read_pod(size))
  11958. return false;
  11959. const std::size_t raw_size = size * sizeof(T);
  11960. if (!buffer_capacity_ok(raw_size))
  11961. return false;
  11962. T t = T();
  11963. for (std::size_t i = 0; i < size; ++i)
  11964. {
  11965. if (operator()(t))
  11966. seq.push_back(t);
  11967. else
  11968. return false;
  11969. }
  11970. return true;
  11971. }
  11972. template <typename T, typename Allocator>
  11973. inline bool operator()(std::vector<T,Allocator>& vec)
  11974. {
  11975. uint32_t size = 0;
  11976. if (!read_pod(size))
  11977. return false;
  11978. const std::size_t raw_size = size * sizeof(T);
  11979. if (!buffer_capacity_ok(raw_size))
  11980. return false;
  11981. vec.resize(size);
  11982. return selector<T>::type::batch_vector_read(*this,size,vec,false);
  11983. }
  11984. template <typename T,
  11985. typename Comparator,
  11986. typename Allocator>
  11987. inline bool operator()(std::set<T,Comparator,Allocator>& set)
  11988. {
  11989. uint32_t size = 0;
  11990. if (!read_pod(size))
  11991. return false;
  11992. const std::size_t raw_size = size * sizeof(T);
  11993. if (!buffer_capacity_ok(raw_size))
  11994. return false;
  11995. T t;
  11996. for (std::size_t i = 0; i < size; ++i)
  11997. {
  11998. if (!operator()(t))
  11999. return false;
  12000. set.insert(t);
  12001. }
  12002. return true;
  12003. }
  12004. template <typename T,
  12005. typename Allocator,
  12006. typename Comparator>
  12007. inline bool operator()(std::multiset<T,Allocator,Comparator>& multiset)
  12008. {
  12009. uint32_t size = 0;
  12010. if (!read_pod(size))
  12011. return false;
  12012. const std::size_t raw_size = size * sizeof(T);
  12013. if (!buffer_capacity_ok(raw_size))
  12014. return false;
  12015. T t;
  12016. for (std::size_t i = 0; i < size; ++i)
  12017. {
  12018. if (!operator()(t))
  12019. return false;
  12020. multiset.insert(t);
  12021. }
  12022. return true;
  12023. }
  12024. inline bool operator()(std::ifstream& stream, const std::size_t& length)
  12025. {
  12026. if (length > buffer_length_) return false;
  12027. stream.read(original_buffer_,static_cast<std::streamsize>(length));
  12028. return true;
  12029. }
  12030. inline bool operator()(std::ifstream& stream)
  12031. {
  12032. if (0 == amount_read_sofar_) return false;
  12033. stream.read(original_buffer_,static_cast<std::streamsize>(amount_read_sofar_));
  12034. return true;
  12035. }
  12036. template <typename T>
  12037. inline bool operator()(T& output)
  12038. {
  12039. return selector<T>::type::run(*this,output);
  12040. }
  12041. template <typename T>
  12042. inline bool operator()(const T& output)
  12043. {
  12044. return selector<T>::type::run(*this,const_cast<T&>(output));
  12045. }
  12046. template <typename T>
  12047. inline bool be_to_native(T& output)
  12048. {
  12049. //From big-endian to native
  12050. if (details::is_little_endian())
  12051. {
  12052. if (!operator()<T>(output)) return false;
  12053. output = details::convert(output);
  12054. return true;
  12055. }
  12056. else
  12057. return operator()(output);
  12058. }
  12059. template <typename T>
  12060. inline bool le_to_native(T& output)
  12061. {
  12062. //From little-endian to native
  12063. if (details::is_little_endian())
  12064. return operator()(output);
  12065. else
  12066. {
  12067. if (!operator()<T>(output)) return false;
  12068. output = details::convert(output);
  12069. return true;
  12070. }
  12071. }
  12072. template <typename T, std::size_t N>
  12073. inline bool operator()(T (&output)[N])
  12074. {
  12075. const std::size_t raw_size = N * sizeof(T);
  12076. if (buffer_capacity_ok(raw_size))
  12077. {
  12078. std::copy(buffer_,
  12079. buffer_ + raw_size,
  12080. reinterpret_cast<char*>(output));
  12081. buffer_ += raw_size;
  12082. amount_read_sofar_ += raw_size;
  12083. return true;
  12084. }
  12085. else
  12086. return false;
  12087. }
  12088. template <typename T>
  12089. inline bool operator()(T& output, const std::size_t& size)
  12090. {
  12091. if (buffer_capacity_ok(size))
  12092. {
  12093. bool result = strtk::string_to_type_converter<char*,T>(buffer_,buffer_ + size,output);
  12094. buffer_ += size;
  12095. amount_read_sofar_ += size;
  12096. return result;
  12097. }
  12098. else
  12099. return false;
  12100. }
  12101. inline void mark()
  12102. {
  12103. marker_.mark(amount_read_sofar_,buffer_);
  12104. }
  12105. inline bool reset_to_mark()
  12106. {
  12107. return marker_.reset(amount_read_sofar_,buffer_);
  12108. }
  12109. private:
  12110. reader();
  12111. reader(const reader& s);
  12112. reader& operator=(const reader& s);
  12113. inline bool buffer_capacity_ok(const std::size_t& required_read_qty)
  12114. {
  12115. return ((required_read_qty + amount_read_sofar_) <= buffer_length_);
  12116. }
  12117. template <typename Type>
  12118. struct selector
  12119. {
  12120. private:
  12121. template <typename T, typename IsPOD>
  12122. struct selector_impl
  12123. {
  12124. template <typename Reader>
  12125. static inline bool run(Reader& r, T& t)
  12126. {
  12127. return t(r);
  12128. }
  12129. template <typename Reader,
  12130. typename Allocator>
  12131. static inline bool batch_vector_read(Reader& r,
  12132. const std::size_t& size,
  12133. std::vector<T,Allocator>& v,
  12134. const bool)
  12135. {
  12136. T t;
  12137. for (std::size_t i = 0; i < size; ++i)
  12138. {
  12139. if (r.operator()(t))
  12140. v[i] = t;
  12141. else
  12142. return false;
  12143. }
  12144. return true;
  12145. }
  12146. };
  12147. template <typename T>
  12148. struct selector_impl<T,strtk::details::yes_t>
  12149. {
  12150. template <typename Reader>
  12151. static inline bool run(Reader& r,
  12152. T& t,
  12153. const bool perform_buffer_capacity_check = true)
  12154. {
  12155. return r.read_pod(t,perform_buffer_capacity_check);
  12156. }
  12157. template <typename Reader,
  12158. typename Allocator>
  12159. static inline bool batch_vector_read(Reader& r,
  12160. const std::size_t& size,
  12161. std::vector<T,Allocator>& v,
  12162. const bool)
  12163. {
  12164. const std::size_t raw_size = sizeof(T) * size;
  12165. char* ptr = const_cast<char*>(reinterpret_cast<const char*>(&v[0]));
  12166. std::copy(r.buffer_, r.buffer_ + raw_size, ptr);
  12167. r.buffer_ += raw_size;
  12168. r.amount_read_sofar_ += raw_size;
  12169. return true;
  12170. }
  12171. };
  12172. public:
  12173. typedef selector_impl<Type,typename strtk::details::is_pod<Type>::result_t> type;
  12174. };
  12175. template <typename T>
  12176. inline bool read_pod(T& data, const bool perform_buffer_capacity_check = true)
  12177. {
  12178. static const std::size_t data_length = sizeof(T);
  12179. if (perform_buffer_capacity_check)
  12180. {
  12181. if (!buffer_capacity_ok(data_length))
  12182. return false;
  12183. }
  12184. data = (*reinterpret_cast<T*>(buffer_));
  12185. buffer_ += data_length;
  12186. amount_read_sofar_ += data_length;
  12187. return true;
  12188. }
  12189. char* const original_buffer_;
  12190. char* buffer_;
  12191. std::size_t buffer_length_;
  12192. std::size_t amount_read_sofar_;
  12193. details::marker marker_;
  12194. };
  12195. class writer
  12196. {
  12197. public:
  12198. // should be sourced from cstdint
  12199. typedef unsigned int uint32_t;
  12200. typedef unsigned short uint16_t;
  12201. typedef unsigned char uint8_t;
  12202. typedef unsigned long long int uint64_t;
  12203. template <typename T>
  12204. writer(T* buffer, const std::size_t& buffer_length)
  12205. : original_buffer_(reinterpret_cast<char*>(buffer)),
  12206. buffer_(reinterpret_cast<char*>(buffer)),
  12207. buffer_length_(buffer_length * sizeof(T)),
  12208. amount_written_sofar_(0)
  12209. {}
  12210. inline bool operator!() const
  12211. {
  12212. return (0 == buffer_length_) ||
  12213. (0 == original_buffer_) ||
  12214. (0 == buffer_);
  12215. }
  12216. inline void reset(const bool clear_buffer = false)
  12217. {
  12218. amount_written_sofar_ = 0;
  12219. buffer_ = original_buffer_;
  12220. if (clear_buffer)
  12221. clear();
  12222. }
  12223. inline std::size_t position() const
  12224. {
  12225. return amount_written_sofar_;
  12226. }
  12227. inline const char* position_ptr() const
  12228. {
  12229. return buffer_ ;
  12230. }
  12231. inline std::size_t amount_written() const
  12232. {
  12233. return amount_written_sofar_;
  12234. }
  12235. inline void clear()
  12236. {
  12237. reset();
  12238. std::memset(buffer_,0x00,buffer_length_);
  12239. }
  12240. template <typename T, std::size_t N>
  12241. inline bool operator()(const T (&data)[N], const bool write_length = false)
  12242. {
  12243. if (write_length && !operator()(N))
  12244. return false;
  12245. const std::size_t raw_size = N * sizeof(T);
  12246. if (!buffer_capacity_ok(raw_size))
  12247. return false;
  12248. const char* ptr = reinterpret_cast<const char*>(data);
  12249. std::copy(ptr, ptr + raw_size, buffer_);
  12250. buffer_ += raw_size;
  12251. amount_written_sofar_ += raw_size;
  12252. return true;
  12253. }
  12254. template <typename T>
  12255. inline bool operator()(const T* data, const uint32_t& length, const bool write_length = true)
  12256. {
  12257. if (write_length && !operator()(length))
  12258. return false;
  12259. const std::size_t raw_size = length * sizeof(T);
  12260. if (!buffer_capacity_ok(raw_size))
  12261. return false;
  12262. const char* ptr = reinterpret_cast<const char*>(data);
  12263. std::copy(ptr, ptr + raw_size, buffer_);
  12264. buffer_ += raw_size;
  12265. amount_written_sofar_ += raw_size;
  12266. return true;
  12267. }
  12268. template <typename T>
  12269. inline bool operator()(const T* data, const uint64_t& length, const bool write_length = true)
  12270. {
  12271. return operator()(data,static_cast<uint32_t>(length),write_length);
  12272. }
  12273. template <typename T>
  12274. inline bool operator()(const T* data, const uint16_t& length, const bool write_length = true)
  12275. {
  12276. return operator()(data,static_cast<uint32_t>(length),write_length);
  12277. }
  12278. template <typename T>
  12279. inline bool operator()(const T* data, const uint8_t& length, const bool write_length = true)
  12280. {
  12281. return operator()(data,static_cast<uint32_t>(length),write_length);
  12282. }
  12283. template <typename T1, typename T2>
  12284. inline bool operator()(const std::pair<T1,T2>& p)
  12285. {
  12286. if (!operator()(p.first))
  12287. return false;
  12288. if (!operator()(p.second))
  12289. return false;
  12290. return true;
  12291. }
  12292. inline bool operator()(const std::string& input)
  12293. {
  12294. return operator()<const char>(input.data(),static_cast<uint32_t>(input.size()));
  12295. }
  12296. template <typename T,
  12297. typename Allocator,
  12298. template <typename,typename> class Sequence>
  12299. inline bool operator()(const Sequence<T,Allocator>& seq)
  12300. {
  12301. const uint32_t size = static_cast<uint32_t>(seq.size());
  12302. if (!operator()(size))
  12303. return false;
  12304. typename Sequence<T,Allocator>::const_iterator itr = seq.begin();
  12305. typename Sequence<T,Allocator>::const_iterator end = seq.end();
  12306. while (end != itr)
  12307. {
  12308. if (!operator()(*itr))
  12309. return false;
  12310. ++itr;
  12311. }
  12312. return true;
  12313. }
  12314. template <typename T,
  12315. typename Allocator>
  12316. inline bool operator()(const std::vector<T,Allocator>& vec)
  12317. {
  12318. const uint32_t size = static_cast<uint32_t>(vec.size());
  12319. const std::size_t raw_size = (size * sizeof(T));
  12320. if (!buffer_capacity_ok(raw_size + sizeof(size)))
  12321. return false;
  12322. if (!operator()(size))
  12323. return false;
  12324. return selector<T>::type::batch_vector_writer(*this,raw_size,vec);
  12325. }
  12326. template <typename T,
  12327. typename Comparator,
  12328. typename Allocator>
  12329. inline bool operator()(const std::set<T,Comparator,Allocator>& set)
  12330. {
  12331. const uint32_t size = static_cast<uint32_t>(set.size());
  12332. if (!operator()(size))
  12333. return false;
  12334. const std::size_t raw_size = size * sizeof(T);
  12335. if (!buffer_capacity_ok(raw_size))
  12336. return false;
  12337. typename std::set<T,Comparator,Allocator>::const_iterator itr = set.begin();
  12338. typename std::set<T,Comparator,Allocator>::const_iterator end = set.end();
  12339. while (end != itr)
  12340. {
  12341. if (!operator()(*itr))
  12342. return false;
  12343. ++itr;
  12344. }
  12345. return true;
  12346. }
  12347. template <typename T,
  12348. typename Allocator,
  12349. typename Comparator>
  12350. inline bool operator()(const std::multiset<T,Allocator,Comparator>& multiset)
  12351. {
  12352. const uint32_t size = static_cast<uint32_t>(multiset.size());
  12353. if (!operator()(size))
  12354. return false;
  12355. const std::size_t raw_size = size * sizeof(T);
  12356. if (!buffer_capacity_ok(raw_size))
  12357. return false;
  12358. typename std::multiset<T,Allocator,Comparator>::const_iterator itr = multiset.begin();
  12359. typename std::multiset<T,Allocator,Comparator>::const_iterator end = multiset.end();
  12360. while (end != itr)
  12361. {
  12362. if (!operator()(*itr))
  12363. return false;
  12364. ++itr;
  12365. }
  12366. return true;
  12367. }
  12368. inline std::size_t operator()(std::ofstream& stream)
  12369. {
  12370. stream.write(original_buffer_,static_cast<std::streamsize>(amount_written_sofar_));
  12371. return amount_written_sofar_;
  12372. }
  12373. template <typename T>
  12374. inline bool operator()(const T& input)
  12375. {
  12376. return selector<T>::type::run(*this,input);
  12377. }
  12378. template <typename T>
  12379. inline bool native_to_be(const T& input)
  12380. {
  12381. //From native to big-endian
  12382. if (details::is_little_endian())
  12383. {
  12384. return operator()<T>(details::convert(input));
  12385. }
  12386. else
  12387. return operator()<T>(input);
  12388. }
  12389. template <typename T>
  12390. inline bool native_to_le(const T& input)
  12391. {
  12392. //From native to little-endian
  12393. if (details::is_little_endian())
  12394. return operator()<T>(input);
  12395. else
  12396. return operator()<T>(details::convert(input));
  12397. }
  12398. enum padding_mode
  12399. {
  12400. right_padding = 0,
  12401. left_padding = 1
  12402. };
  12403. template <typename T>
  12404. inline bool operator()(const T& input,
  12405. const std::size_t& size,
  12406. const padding_mode pmode,
  12407. const char padding = ' ')
  12408. {
  12409. if (amount_written_sofar_ + size <= buffer_length_)
  12410. {
  12411. std::string s;
  12412. s.reserve(size);
  12413. if (!strtk::type_to_string<T>(input,s))
  12414. return false;
  12415. else if (s.size() > size)
  12416. return false;
  12417. else if (s.size() < size)
  12418. {
  12419. if (right_padding == pmode)
  12420. s.resize(size - s.size(),padding);
  12421. else
  12422. s = std::string(size - s.size(),padding) + s;
  12423. }
  12424. return operator()<const char>(s.data(),static_cast<uint32_t>(size),false);
  12425. }
  12426. else
  12427. return false;
  12428. }
  12429. inline void mark()
  12430. {
  12431. marker_.mark(amount_written_sofar_,buffer_);
  12432. }
  12433. inline bool reset_to_mark()
  12434. {
  12435. return marker_.reset(amount_written_sofar_,buffer_);
  12436. }
  12437. private:
  12438. writer();
  12439. writer(const writer& s);
  12440. writer& operator=(const writer& s);
  12441. inline bool buffer_capacity_ok(const std::size_t& required_write_qty)
  12442. {
  12443. return ((required_write_qty + amount_written_sofar_) <= buffer_length_);
  12444. }
  12445. template <typename Type>
  12446. struct selector
  12447. {
  12448. private:
  12449. template <typename T, typename IsPOD>
  12450. struct selector_impl
  12451. {
  12452. template <typename Writer>
  12453. static inline bool run(Writer& w, const T& t)
  12454. {
  12455. return t(w);
  12456. }
  12457. template <typename Writer,
  12458. typename Allocator>
  12459. static inline bool batch_vector_writer(Writer& w,
  12460. const std::size_t&,
  12461. const std::vector<T,Allocator>& v)
  12462. {
  12463. for (std::size_t i = 0; i < v.size(); ++i)
  12464. {
  12465. if (w.operator()(v[i]))
  12466. continue;
  12467. else
  12468. return false;
  12469. }
  12470. return true;
  12471. }
  12472. };
  12473. template <typename T>
  12474. struct selector_impl<T,strtk::details::yes_t>
  12475. {
  12476. template <typename Writer>
  12477. static inline bool run(Writer& w, const T& t)
  12478. {
  12479. return w.write_pod(t);
  12480. }
  12481. template <typename Writer,
  12482. typename Allocator>
  12483. static inline bool batch_vector_writer(Writer& w,
  12484. const std::size_t& raw_size,
  12485. const std::vector<T,Allocator>& v)
  12486. {
  12487. const char* ptr = reinterpret_cast<const char*>(&v[0]);
  12488. std::copy(ptr, ptr + raw_size, w.buffer_);
  12489. w.buffer_ += raw_size;
  12490. w.amount_written_sofar_ += raw_size;
  12491. return true;
  12492. }
  12493. };
  12494. public:
  12495. typedef selector_impl<Type,typename strtk::details::is_pod<Type>::result_t> type;
  12496. };
  12497. template <typename T>
  12498. inline bool write_pod(const T& data, const bool perform_buffer_capacity_check = true)
  12499. {
  12500. static const std::size_t data_length = sizeof(T);
  12501. if (perform_buffer_capacity_check)
  12502. {
  12503. if ((data_length + amount_written_sofar_) > buffer_length_)
  12504. {
  12505. return false;
  12506. }
  12507. }
  12508. *(reinterpret_cast<T*>(buffer_)) = data;
  12509. buffer_ += data_length;
  12510. amount_written_sofar_ += data_length;
  12511. return true;
  12512. }
  12513. char* const original_buffer_;
  12514. char* buffer_;
  12515. std::size_t buffer_length_;
  12516. std::size_t amount_written_sofar_;
  12517. details::marker marker_;
  12518. };
  12519. #define strtk_binary_reader_begin() \
  12520. bool operator()(strtk::binary::reader& reader)\
  12521. { return true \
  12522. #define strtk_binary_reader(T) \
  12523. && reader(T) \
  12524. #define strtk_binary_reader_end() \
  12525. ;} \
  12526. #define strtk_binary_writer_begin() \
  12527. bool operator()(strtk::binary::writer& writer) const\
  12528. { return true \
  12529. #define strtk_binary_writer(T) \
  12530. && writer(T) \
  12531. #define strtk_binary_writer_end() \
  12532. ;} \
  12533. namespace details
  12534. {
  12535. template <typename size_type>
  12536. class short_string_impl
  12537. {
  12538. public:
  12539. short_string_impl()
  12540. : s(0)
  12541. {}
  12542. short_string_impl(std::string& str)
  12543. : s(&str)
  12544. {}
  12545. inline void clear()
  12546. {
  12547. s = 0;
  12548. }
  12549. inline short_string_impl<size_type>& set(std::string& str)
  12550. {
  12551. s = &str;
  12552. return *this;
  12553. }
  12554. inline bool operator()(reader& r)
  12555. {
  12556. if (0 == s)
  12557. return false;
  12558. size_type size = 0;
  12559. if (!r(size))
  12560. return false;
  12561. s->resize(size);
  12562. char* ptr = const_cast<char*>(s->data());
  12563. strtk::binary::reader::uint32_t length = size;
  12564. if (!r(ptr,length,false))
  12565. return false;
  12566. return true;
  12567. }
  12568. inline bool operator()(writer& w) const
  12569. {
  12570. if (0 == s)
  12571. return false;
  12572. if (s->size() > std::numeric_limits<size_type>::max())
  12573. return false;
  12574. const size_type size = static_cast<size_type>(s->size());
  12575. if (!w(size))
  12576. return false;
  12577. if (!w(s->data(),size, false))
  12578. return false;
  12579. return true;
  12580. }
  12581. private:
  12582. short_string_impl& operator=(const short_string_impl&);
  12583. mutable std::string* s;
  12584. };
  12585. }
  12586. typedef details::short_string_impl<reader::uint16_t> short_string;
  12587. typedef details::short_string_impl<reader::uint8_t> pascal_string;
  12588. } // namespace binary
  12589. class ignore_token
  12590. {
  12591. public:
  12592. template <typename InputIterator>
  12593. inline ignore_token& operator=(const std::pair<InputIterator,InputIterator>&)
  12594. {
  12595. return (*this);
  12596. }
  12597. inline ignore_token& operator=(const std::string&)
  12598. {
  12599. return (*this);
  12600. }
  12601. };
  12602. template <typename T>
  12603. class hex_to_number_sink
  12604. {
  12605. // static_assert for T either int or unsigned int and alike (could use a concept)
  12606. private:
  12607. struct hex_value_check
  12608. {
  12609. inline bool operator()(const unsigned char c) const
  12610. {
  12611. return (('0' <= c) && (c <= '9')) ||
  12612. (('A' <= c) && (c <= 'F')) ||
  12613. (('a' <= c) && (c <= 'f'));
  12614. }
  12615. inline bool operator()(const char c) const
  12616. {
  12617. return (*this)(static_cast<unsigned char>(c));
  12618. }
  12619. };
  12620. public:
  12621. hex_to_number_sink(T& t)
  12622. : valid_(false),
  12623. t_(&t)
  12624. {}
  12625. hex_to_number_sink(const hex_to_number_sink& hns)
  12626. : valid_(hns.valid),
  12627. t_(hns.t_)
  12628. {}
  12629. inline hex_to_number_sink& operator=(const hex_to_number_sink& hns)
  12630. {
  12631. valid_ = hns.valid_;
  12632. t_ = hns.t_;
  12633. return (*this);
  12634. }
  12635. template <typename InputIterator>
  12636. inline hex_to_number_sink& operator=(const std::pair<InputIterator,InputIterator>& s)
  12637. {
  12638. std::size_t offset = 0;
  12639. const std::size_t size = std::distance(s.first,s.second);
  12640. if ((size > 2) && ((*s.first) == '0') && (((*(s.first + 1)) == 'x') || ((*(s.first + 1)) == 'X')))
  12641. offset = 2;
  12642. if ((size - offset) > (2 * sizeof(T)))
  12643. return (*this);
  12644. const std::size_t buffer_size = 2 * sizeof(T);
  12645. const std::size_t buffer_offset = ((size - offset) % 2);
  12646. char buffer[buffer_size] = { '0' };
  12647. if (!range_only_contains(hex_value_check(),s.first + offset,s.first + size))
  12648. {
  12649. valid_ = false;
  12650. return (*this);
  12651. }
  12652. std::copy(s.first + offset, s.first + size, buffer + buffer_offset);
  12653. (*t_) = 0;
  12654. valid_= convert_hex_to_bin(buffer,
  12655. buffer + (size - offset) + buffer_offset,
  12656. reinterpret_cast<char*>(t_));
  12657. reverse_bytes();
  12658. return (*this);
  12659. }
  12660. inline hex_to_number_sink& operator=(const std::string& s)
  12661. {
  12662. return this->operator =(std::make_pair(s.data(),s.data() + s.size()));
  12663. }
  12664. inline bool valid() const
  12665. {
  12666. return valid_;
  12667. }
  12668. private:
  12669. inline void reverse_bytes()
  12670. {
  12671. unsigned char* itr1 = reinterpret_cast<unsigned char*>(t_);
  12672. unsigned char* itr2 = itr1 + (sizeof(T) - 1);
  12673. while (itr1 < itr2)
  12674. {
  12675. std::swap(*itr1,*itr2);
  12676. ++itr1;
  12677. --itr2;
  12678. }
  12679. }
  12680. private:
  12681. bool valid_;
  12682. T* t_;
  12683. };
  12684. template <typename T>
  12685. class base64_to_number_sink
  12686. {
  12687. // static_assert for T either int or unsigned int and alike (could use a concept)
  12688. private:
  12689. struct base64_value_check
  12690. {
  12691. inline bool operator()(const unsigned char c) const
  12692. {
  12693. return (('0' <= c) && (c <= '9')) ||
  12694. (('A' <= c) && (c <= 'Z')) ||
  12695. (('a' <= c) && (c <= 'z')) ||
  12696. ('+' == c) ||
  12697. ('/' == c) ||
  12698. ('=' == c);
  12699. }
  12700. inline bool operator()(const char c) const
  12701. {
  12702. return (*this)(static_cast<unsigned char>(c));
  12703. }
  12704. };
  12705. public:
  12706. base64_to_number_sink(T& t)
  12707. : valid_(false),
  12708. t_(&t)
  12709. {}
  12710. base64_to_number_sink(const base64_to_number_sink& bns)
  12711. : valid_(bns.valid),
  12712. t_(bns.t_)
  12713. {}
  12714. inline base64_to_number_sink& operator=(const base64_to_number_sink& bns)
  12715. {
  12716. valid_ = bns.valid_;
  12717. t_ = bns.t_;
  12718. return (*this);
  12719. }
  12720. inline base64_to_number_sink& operator=(const std::string& s)
  12721. {
  12722. if (!range_only_contains(base64_value_check(),s.data(),s.data() + s.size()))
  12723. {
  12724. valid_ = false;
  12725. return (*this);
  12726. }
  12727. (*t_) = T(0);
  12728. convert_base64_to_bin(s.data(),
  12729. s.data() + s.size(),
  12730. reinterpret_cast<char*>(t_));
  12731. reverse_bytes();
  12732. return (*this);
  12733. }
  12734. template <typename InputIterator>
  12735. inline base64_to_number_sink& operator=(const std::pair<InputIterator,InputIterator>& s)
  12736. {
  12737. if (!range_only_contains(base64_value_check(),s.first,s.second))
  12738. {
  12739. valid_ = false;
  12740. return (*this);
  12741. }
  12742. (*t_) = T(0);
  12743. convert_base64_to_bin(s.first, s.second,reinterpret_cast<char*>(t_));
  12744. reverse_bytes();
  12745. return (*this);
  12746. }
  12747. inline bool valid() const
  12748. {
  12749. return valid_;
  12750. }
  12751. private:
  12752. inline void reverse_bytes()
  12753. {
  12754. unsigned char* itr1 = reinterpret_cast<unsigned char*>(t_);
  12755. unsigned char* itr2 = itr1 + (sizeof(T) - 1);
  12756. while (itr1 < itr2)
  12757. {
  12758. std::swap(*itr1,*itr2);
  12759. ++itr1;
  12760. --itr2;
  12761. }
  12762. }
  12763. private:
  12764. bool valid_;
  12765. T* t_;
  12766. };
  12767. class hex_to_string_sink
  12768. {
  12769. public:
  12770. hex_to_string_sink(std::string& s)
  12771. : valid_(false),
  12772. s_(s)
  12773. {}
  12774. hex_to_string_sink(const hex_to_string_sink& hss)
  12775. : valid_(hss.valid_),
  12776. s_(hss.s_)
  12777. {}
  12778. inline hex_to_string_sink& operator=(const hex_to_string_sink& hss)
  12779. {
  12780. valid_ = hss.valid_;
  12781. s_ = hss.s_;
  12782. return (*this);
  12783. }
  12784. template <typename InputIterator>
  12785. inline hex_to_string_sink& operator=(const std::pair<InputIterator,InputIterator>& s)
  12786. {
  12787. const std::size_t size = std::distance(s.first,s.second);
  12788. std::size_t offset = 0;
  12789. if ((size > 2) && ((*s.first) == '0') && (((*(s.first + 1)) == 'x') || ((*(s.first + 1)) == 'X')))
  12790. offset = 2;
  12791. if ((size - offset) < 2)
  12792. {
  12793. valid_ = false;
  12794. return (*this);
  12795. }
  12796. s_.resize((size - offset) / 2);
  12797. valid_ = convert_hex_to_bin(s.first + offset,
  12798. s.second,
  12799. const_cast<char*>(s_.data()));
  12800. return (*this);
  12801. }
  12802. inline hex_to_string_sink& operator=(const std::string& s)
  12803. {
  12804. return this->operator=(std::make_pair<char*>(const_cast<char*>(s.data()),
  12805. const_cast<char*>(s.data() + s.size())));
  12806. }
  12807. inline bool valid() const
  12808. {
  12809. return valid_;
  12810. }
  12811. private:
  12812. bool valid_;
  12813. std::string& s_;
  12814. };
  12815. template <typename T>
  12816. class truncated_int
  12817. {
  12818. public:
  12819. truncated_int()
  12820. : t_(0),
  12821. fractional_size_(std::numeric_limits<std::size_t>::max())
  12822. {}
  12823. truncated_int& fractional_size(const std::size_t& size)
  12824. {
  12825. fractional_size_ = size;
  12826. return *this;
  12827. }
  12828. truncated_int& fractional_unknown_size()
  12829. {
  12830. fractional_size_ = std::numeric_limits<std::size_t>::max();
  12831. return *this;
  12832. }
  12833. truncated_int& operator()(T& t)
  12834. {
  12835. t_ = &t;
  12836. return *this;
  12837. }
  12838. template <typename InputIterator>
  12839. inline bool operator()(InputIterator begin, InputIterator end)
  12840. {
  12841. if (0 == t_)
  12842. return false;
  12843. const std::size_t size = std::distance(begin,end);
  12844. if (std::numeric_limits<std::size_t>::max() != fractional_size_)
  12845. {
  12846. if (size < (fractional_size_ + 1))
  12847. return false;
  12848. else
  12849. return strtk::string_to_type_converter(begin, begin + (size - (fractional_size_ + 1)),(*t_));
  12850. }
  12851. typedef typename std::iterator_traits<InputIterator>::value_type value_type;
  12852. const value_type fullstop = value_type('.');
  12853. InputIterator new_end = std::find(begin,end,fullstop);
  12854. return strtk::string_to_type_converter(begin,new_end,(*t_));
  12855. }
  12856. private:
  12857. T* t_;
  12858. std::size_t fractional_size_;
  12859. };
  12860. namespace details
  12861. {
  12862. template <typename T>
  12863. inline T pow10(T d, const int exponent);
  12864. }
  12865. template <typename T>
  12866. class decimal_sink
  12867. {
  12868. public:
  12869. decimal_sink(const std::size_t& int_size, const std::size_t& frac_size)
  12870. : t_ (0),
  12871. int_size_ (int_size ),
  12872. frac_size_(frac_size)
  12873. {}
  12874. decimal_sink(T& t, const std::size_t& int_size, const std::size_t& frac_size)
  12875. : t_ (&t),
  12876. int_size_ (int_size ),
  12877. frac_size_(frac_size)
  12878. {}
  12879. inline decimal_sink& int_size(const std::size_t& size)
  12880. {
  12881. int_size_ = size;
  12882. return *this;
  12883. }
  12884. inline decimal_sink& frac_size(const std::size_t& size)
  12885. {
  12886. frac_size_ = size;
  12887. return *this;
  12888. }
  12889. inline decimal_sink& operator()(T& t)
  12890. {
  12891. t_ = &t;
  12892. return *this;
  12893. }
  12894. template <typename InputIterator>
  12895. inline bool operator()(InputIterator itr, InputIterator end)
  12896. {
  12897. if (0 == t_)
  12898. return false;
  12899. typedef typename strtk::details::real_type<T>::type real_t;
  12900. bool negative = ('-' == (*itr));
  12901. if (negative || '+' == (*itr))
  12902. {
  12903. if (end == ++itr)
  12904. return false;
  12905. }
  12906. while ((end != itr) && ('0' == (*itr))) ++itr;
  12907. std::size_t length = std::distance(itr,end);
  12908. InputIterator end_n = itr + std::min(length,int_size_);
  12909. real_t d = real_t(0);
  12910. unsigned int digit = 0;
  12911. while (end_n != itr)
  12912. {
  12913. if ((digit = (*itr - '0')) < 10)
  12914. {
  12915. d = d * real_t(10) + static_cast<T>(digit);
  12916. ++itr;
  12917. }
  12918. else if ('.' == *itr)
  12919. break;
  12920. else
  12921. return false;
  12922. }
  12923. ++itr;
  12924. length = std::min<std::size_t>(frac_size_,std::distance(itr,end));
  12925. end_n = itr + length;
  12926. real_t f = real_t(0);
  12927. while (end_n != itr)
  12928. {
  12929. if ((digit = (*itr - '0')) < 10)
  12930. {
  12931. f = f * real_t(10) + static_cast<T>(digit);
  12932. ++itr;
  12933. }
  12934. else
  12935. return false;
  12936. }
  12937. if (length)
  12938. {
  12939. d += strtk::details::pow10(f,-length);
  12940. }
  12941. (*t_) = static_cast<T>((negative) ? -d : d);
  12942. return true;
  12943. }
  12944. private:
  12945. T* t_;
  12946. std::size_t int_size_;
  12947. std::size_t frac_size_;
  12948. };
  12949. namespace details
  12950. {
  12951. template <typename InputIterator,
  12952. typename T,
  12953. typename Allocator,
  12954. template <typename,typename> class Sequence>
  12955. inline std::size_t parse_stl_container_proxy(const InputIterator begin,
  12956. const InputIterator end,
  12957. const std::string& delimiters,
  12958. Sequence<T,Allocator>& sequence,
  12959. const split_options::type& split_option = split_options::compress_delimiters)
  12960. {
  12961. return parse(begin,end,delimiters,sequence,split_option);
  12962. }
  12963. template <typename InputIterator,
  12964. typename T,
  12965. typename Comparator,
  12966. typename Allocator>
  12967. inline std::size_t parse_stl_container_proxy(const InputIterator begin,
  12968. const InputIterator end,
  12969. const std::string& delimiters,
  12970. std::set<T,Comparator,Allocator>& set,
  12971. const split_options::type& split_option = split_options::compress_delimiters)
  12972. {
  12973. return parse(begin,end,delimiters,set,split_option);
  12974. }
  12975. template <typename InputIterator,
  12976. typename T,
  12977. typename Comparator,
  12978. typename Allocator>
  12979. inline std::size_t parse_stl_container_proxy(const InputIterator begin,
  12980. const InputIterator end,
  12981. const std::string& delimiters,
  12982. std::multiset<T,Comparator,Allocator>& multiset,
  12983. const split_options::type& split_option = split_options::compress_delimiters)
  12984. {
  12985. return parse(begin,end,delimiters,multiset,split_option);
  12986. }
  12987. template <typename InputIterator,
  12988. typename T,
  12989. typename Container>
  12990. inline std::size_t parse_stl_container_proxy(const InputIterator begin,
  12991. const InputIterator end,
  12992. const std::string& delimiters,
  12993. std::queue<T,Container>& queue,
  12994. const split_options::type& split_option = split_options::compress_delimiters)
  12995. {
  12996. return parse(begin,end,delimiters,queue,split_option);
  12997. }
  12998. template <typename InputIterator,
  12999. typename T,
  13000. typename Container>
  13001. inline std::size_t parse_stl_container_proxy(const InputIterator begin,
  13002. const InputIterator end,
  13003. const std::string& delimiters,
  13004. std::stack<T,Container>& stack,
  13005. const split_options::type& split_option = split_options::compress_delimiters)
  13006. {
  13007. return parse(begin,end,delimiters,stack,split_option);
  13008. }
  13009. template <typename InputIterator,
  13010. typename T,
  13011. typename Container,
  13012. typename Comparator>
  13013. inline std::size_t parse_stl_container_proxy(const InputIterator begin,
  13014. const InputIterator end,
  13015. const std::string& delimiters,
  13016. std::priority_queue<T,Container,Comparator>& priority_queue,
  13017. const split_options::type& split_option = split_options::compress_delimiters)
  13018. {
  13019. return parse(begin,end,delimiters,priority_queue,split_option);
  13020. }
  13021. template <typename InputIterator,
  13022. typename T,
  13023. typename Allocator,
  13024. template <typename,typename> class Sequence>
  13025. inline std::size_t parse_n_stl_container_proxy(const InputIterator begin,
  13026. const InputIterator end,
  13027. const std::string& delimiters,
  13028. const std::size_t& n,
  13029. Sequence<T,Allocator>& sequence,
  13030. const split_options::type& split_option = split_options::compress_delimiters)
  13031. {
  13032. return parse_n(begin,end,delimiters,n,sequence,split_option);
  13033. }
  13034. template <typename InputIterator,
  13035. typename T,
  13036. typename Comparator,
  13037. typename Allocator>
  13038. inline std::size_t parse_n_stl_container_proxy(const InputIterator begin,
  13039. const InputIterator end,
  13040. const std::string& delimiters,
  13041. const std::size_t& n,
  13042. std::set<T,Comparator,Allocator>& set,
  13043. const split_options::type& split_option = split_options::compress_delimiters)
  13044. {
  13045. return parse_n(begin,end,delimiters,n,set,split_option);
  13046. }
  13047. template <typename InputIterator,
  13048. typename T,
  13049. typename Comparator,
  13050. typename Allocator>
  13051. inline std::size_t parse_n_stl_container_proxy(const InputIterator begin,
  13052. const InputIterator end,
  13053. const std::string& delimiters,
  13054. const std::size_t& n,
  13055. std::multiset<T,Comparator,Allocator>& multiset,
  13056. const split_options::type& split_option = split_options::compress_delimiters)
  13057. {
  13058. return parse_n(begin,end,delimiters,n,multiset,split_option);
  13059. }
  13060. template <typename InputIterator,
  13061. typename T,
  13062. typename Container>
  13063. inline std::size_t parse_n_stl_container_proxy(const InputIterator begin,
  13064. const InputIterator end,
  13065. const std::string& delimiters,
  13066. const std::size_t& n,
  13067. std::queue<T,Container>& queue,
  13068. const split_options::type& split_option = split_options::compress_delimiters)
  13069. {
  13070. return parse_n(begin,end,delimiters,n,queue,split_option);
  13071. }
  13072. template <typename InputIterator,
  13073. typename T,
  13074. typename Container>
  13075. inline std::size_t parse_n_stl_container_proxy(const InputIterator begin,
  13076. const InputIterator end,
  13077. const std::string& delimiters,
  13078. const std::size_t& n,
  13079. std::stack<T,Container>& stack,
  13080. const split_options::type& split_option = split_options::compress_delimiters)
  13081. {
  13082. return parse_n(begin,end,delimiters,n,stack,split_option);
  13083. }
  13084. template <typename InputIterator,
  13085. typename T,
  13086. typename Container,
  13087. typename Comparator>
  13088. inline std::size_t parse_n_stl_container_proxy(const InputIterator begin,
  13089. const InputIterator end,
  13090. const std::string& delimiters,
  13091. const std::size_t& n,
  13092. std::priority_queue<T,Container,Comparator>& priority_queue,
  13093. const split_options::type& split_option = split_options::compress_delimiters)
  13094. {
  13095. return parse_n(begin,end,delimiters,n,priority_queue,split_option);
  13096. }
  13097. } // namespace details
  13098. template <typename Container>
  13099. class sink_type
  13100. {
  13101. public:
  13102. typedef typename Container::value_type value_type;
  13103. inline sink_type(const std::string& delimiters,
  13104. const split_options::type& split_option = split_options::compress_delimiters)
  13105. : delimiters_(delimiters),
  13106. split_option_(split_option),
  13107. container_(0),
  13108. element_count_(std::numeric_limits<std::size_t>::max())
  13109. {}
  13110. inline sink_type(Container& container,
  13111. const std::string& delimiters,
  13112. const split_options::type& split_option = split_options::compress_delimiters)
  13113. : delimiters_(delimiters),
  13114. split_option_(split_option),
  13115. container_(&container)
  13116. {}
  13117. inline sink_type& count(const std::size_t& element_count = std::numeric_limits<std::size_t>::max())
  13118. {
  13119. element_count_ = element_count;
  13120. return (*this);
  13121. }
  13122. inline sink_type& operator()(Container& container,
  13123. const std::string& delimiters = "",
  13124. const split_options::type& split_option = split_options::compress_delimiters)
  13125. {
  13126. container_ = (&container);
  13127. if (!delimiters.empty())
  13128. delimiters_ = delimiters;
  13129. split_option_ = split_option;
  13130. return (*this);
  13131. }
  13132. template <typename InputIterator>
  13133. inline bool parse(InputIterator begin, InputIterator end)
  13134. {
  13135. if (container_)
  13136. {
  13137. if (std::numeric_limits<std::size_t>::max() == element_count_)
  13138. return (details::parse_stl_container_proxy
  13139. (begin,end,delimiters_,(*container_),split_option_) > 0);
  13140. else
  13141. return (details::parse_n_stl_container_proxy
  13142. (begin,end,delimiters_,element_count_,(*container_),split_option_) == element_count_);
  13143. }
  13144. else
  13145. return false;
  13146. }
  13147. sink_type<Container>& reference()
  13148. {
  13149. return *this;
  13150. }
  13151. private:
  13152. std::string delimiters_;
  13153. split_options::type split_option_;
  13154. Container* container_;
  13155. std::size_t element_count_;
  13156. };
  13157. template <typename T> struct vector_sink { typedef sink_type<std::vector<T> > type; };
  13158. template <typename T> struct deque_sink { typedef sink_type<std::deque<T> > type; };
  13159. template <typename T> struct list_sink { typedef sink_type<std::list<T> > type; };
  13160. template <typename T> struct set_sink { typedef sink_type<std::set<T> > type; };
  13161. template <typename T> struct multiset_sink { typedef sink_type<std::multiset<T> > type; };
  13162. template <typename T> struct queue_sink { typedef sink_type<std::queue<T> > type; };
  13163. template <typename T> struct stack_sink { typedef sink_type<std::stack<T> > type; };
  13164. template <typename T> struct priority_queue_sink { typedef sink_type<std::priority_queue<T> > type; };
  13165. namespace text
  13166. {
  13167. inline std::string center(const std::size_t& width,
  13168. const std::string::value_type& pad,
  13169. const std::string& str)
  13170. {
  13171. if (str.size() >= width) return str;
  13172. const std::size_t pad_count = width - str.size();
  13173. const std::size_t pad_count_2 = (pad_count >> 1) + (pad_count & 1);
  13174. return std::string(pad_count >> 1,pad) + str + std::string(pad_count_2,pad);
  13175. }
  13176. inline std::string right_align(const std::size_t& width,
  13177. const std::string::value_type& pad,
  13178. const std::string& str)
  13179. {
  13180. if (str.size() >= width) return str;
  13181. return std::string(width - str.size(),pad) + str;
  13182. }
  13183. inline std::string left_align(const std::size_t& width,
  13184. const std::string::value_type& pad,
  13185. const std::string& str)
  13186. {
  13187. if (str.size() >= width) return str;
  13188. return str + std::string(width - str.size(),pad);
  13189. }
  13190. template <typename T>
  13191. inline std::string center(const std::size_t& width,
  13192. const std::string::value_type& pad,
  13193. const T& t)
  13194. {
  13195. return center(width,pad,type_to_string(t));
  13196. }
  13197. template <typename T>
  13198. inline std::string right_align(const std::size_t& width,
  13199. const std::string::value_type& pad,
  13200. const T& t)
  13201. {
  13202. return right_align(width,pad,type_to_string(t));
  13203. }
  13204. template <typename T>
  13205. inline std::string left_align(const std::size_t& width,
  13206. const std::string::value_type& pad,
  13207. const T& t)
  13208. {
  13209. return left_align(width,pad,type_to_string(t));
  13210. }
  13211. template <typename T>
  13212. inline std::string center(const std::size_t& width, const T& t)
  13213. {
  13214. return center(width,' ',type_to_string(t));
  13215. }
  13216. template <typename T>
  13217. inline std::string right_align(const std::size_t& width, const T& t)
  13218. {
  13219. return right_align(width,' ',type_to_string(t));
  13220. }
  13221. template <typename T>
  13222. inline std::string left_align(const std::size_t& width, const T& t)
  13223. {
  13224. return left_align(width,' ',type_to_string(t));
  13225. }
  13226. inline std::string remaining_string(const std::size_t& index,
  13227. const std::string& str)
  13228. {
  13229. return (index < str.size()) ? str.substr(index,str.size() - index) : str;
  13230. }
  13231. inline void remaining_string(const std::size_t& index,
  13232. const std::string& str,
  13233. std::string& result)
  13234. {
  13235. result = (index < str.size()) ? str.substr(index,str.size() - index) : str;
  13236. }
  13237. inline bool is_letter(const char c)
  13238. {
  13239. return (('A' <= c) && ( c <= 'Z')) || (('a' <= c) && ( c <= 'z'));
  13240. }
  13241. inline bool is_lowercase_letter(const char c)
  13242. {
  13243. return (('a' <= c) && ( c <= 'z'));
  13244. }
  13245. inline bool is_uppercase_letter(const char c)
  13246. {
  13247. return (('A' <= c) && ( c <= 'Z'));
  13248. }
  13249. inline bool is_digit(const char c)
  13250. {
  13251. return (('0' <= c) && ( c <= '9'));
  13252. }
  13253. inline bool is_hex_digit(const char c)
  13254. {
  13255. return (('0' <= c) && (c <= '9')) ||
  13256. (('A' <= c) && (c <= 'F')) ||
  13257. (('a' <= c) && (c <= 'f'));
  13258. }
  13259. inline bool is_letter_or_digit(const char c)
  13260. {
  13261. return (is_letter(c) || is_digit(c));
  13262. }
  13263. inline bool is_all_letters(const std::string& s)
  13264. {
  13265. for (std::size_t i = 0; i < s.size(); ++i)
  13266. {
  13267. if (!is_letter(s[i]))
  13268. return false;
  13269. }
  13270. return true;
  13271. }
  13272. inline bool is_all_digits(const std::string& s)
  13273. {
  13274. for (std::size_t i = 0; i < s.size(); ++i)
  13275. {
  13276. if (!is_digit(s[i]))
  13277. return false;
  13278. }
  13279. return true;
  13280. }
  13281. inline void swap_inplace(std::string& s, const std::size_t& i0, const std::size_t& i1)
  13282. {
  13283. if (i0 >= s.size()) return;
  13284. if (i1 >= s.size()) return;
  13285. std::swap(s[i0],s[i1]);
  13286. }
  13287. inline std::string swap(const std::string& s, const std::size_t& i0, const std::size_t& i1)
  13288. {
  13289. std::string result = s;
  13290. swap_inplace(result,i0,i1);
  13291. return result;
  13292. }
  13293. inline void remove_inplace(std::string& s, const std::size_t& index)
  13294. {
  13295. if (index >= s.size())
  13296. return;
  13297. std::memcpy(const_cast<char*>(s.data() + index), const_cast<char*>(s.data() + (index + 1)), s.size() - index);
  13298. s.resize(s.size() - 1);
  13299. }
  13300. inline std::string remove(const std::string& s, const std::size_t& index)
  13301. {
  13302. std::string result = s;
  13303. remove_inplace(result,index);
  13304. return result;
  13305. }
  13306. inline void insert_inplace(std::string& s, const std::size_t& index, const char c)
  13307. {
  13308. s.resize(s.size() + 1);
  13309. std::memcpy(const_cast<char*>(s.data() + index + 1), const_cast<char*>(s.data() + (index)), s.size() - index);
  13310. s[index] = c;
  13311. }
  13312. inline std::string insert(const std::string& s, const std::size_t& index, const char c)
  13313. {
  13314. std::string result = s;
  13315. insert_inplace(result,index,c);
  13316. return result;
  13317. }
  13318. } // namespace text
  13319. namespace find_mode
  13320. {
  13321. enum type
  13322. {
  13323. exactly_n,
  13324. atleast_n
  13325. };
  13326. }
  13327. namespace find_type
  13328. {
  13329. enum type
  13330. {
  13331. digits,
  13332. letters,
  13333. lowercase_letters,
  13334. uppercase_letters,
  13335. letters_digits
  13336. };
  13337. }
  13338. namespace details
  13339. {
  13340. template <typename Iterator>
  13341. struct range_type
  13342. {
  13343. typedef typename std::pair<Iterator,Iterator> type;
  13344. };
  13345. template <typename Iterator, typename Predicate>
  13346. inline typename range_type<Iterator>::type find_exactly_n_consecutive_values(const std::size_t n,
  13347. Predicate p,
  13348. Iterator itr,
  13349. const Iterator end,
  13350. const bool stateful_predicate = false)
  13351. {
  13352. if (static_cast<unsigned int>(std::distance(itr,end)) < n)
  13353. return typename range_type<Iterator>::type(end,end);
  13354. std::size_t count = n;
  13355. while (end != itr)
  13356. {
  13357. if (p(*itr))
  13358. {
  13359. if (0 != --count)
  13360. ++itr;
  13361. else
  13362. {
  13363. std::advance(itr,1 - n);
  13364. return typename range_type<Iterator>::type(itr,itr + n);
  13365. }
  13366. }
  13367. else
  13368. {
  13369. ++itr;
  13370. while ((end != itr) && !p(*itr))
  13371. ++itr;
  13372. if (!stateful_predicate)
  13373. count = n;
  13374. else
  13375. {
  13376. --count;
  13377. ++itr;
  13378. }
  13379. }
  13380. }
  13381. return typename range_type<Iterator>::type(end,end);
  13382. }
  13383. template <typename Iterator, typename Predicate>
  13384. inline typename range_type<Iterator>::type find_atleast_n_consecutive_values(const std::size_t n,
  13385. Predicate p,
  13386. Iterator itr,
  13387. const Iterator end)
  13388. {
  13389. if (static_cast<unsigned int>(std::distance(itr,end)) < n)
  13390. return typename range_type<Iterator>::type(end,end);
  13391. std::size_t count = 0;
  13392. while (end != itr)
  13393. {
  13394. if (p(*itr))
  13395. {
  13396. ++count;
  13397. ++itr;
  13398. }
  13399. else
  13400. {
  13401. if (count >= n)
  13402. {
  13403. std::advance(itr,-static_cast<int>(count));
  13404. return typename range_type<Iterator>::type(itr,itr + count);
  13405. }
  13406. while ((end != itr) && !p(*itr))
  13407. ++itr;
  13408. count = 0;
  13409. }
  13410. }
  13411. if (count >= n)
  13412. {
  13413. std::advance(itr,-static_cast<int>(count));
  13414. return typename range_type<Iterator>::type(itr,itr + count);
  13415. }
  13416. else
  13417. return typename range_type<Iterator>::type(end,end);
  13418. }
  13419. template <typename Iterator, typename Predicate>
  13420. inline typename range_type<Iterator>::type find_exactly_n_consecutive_values(const std::size_t n,
  13421. Predicate p,
  13422. typename details::range_type<Iterator>::type range,
  13423. const bool stateful_predicate = false)
  13424. {
  13425. return find_exactly_n_consecutive_values(n,p,range.first,range.second,stateful_predicate);
  13426. }
  13427. template <typename Iterator, typename Predicate>
  13428. inline typename range_type<Iterator>::type find_atleast_n_consecutive_values(const std::size_t n,
  13429. Predicate p,
  13430. typename details::range_type<Iterator>::type range)
  13431. {
  13432. return find_atleast_n_consecutive_values(n,p,range.first,range.second);
  13433. }
  13434. template <typename Iterator, typename Predicate>
  13435. inline typename range_type<Iterator>::type find_n_consecutive_values(const std::size_t n,
  13436. find_mode::type mode,
  13437. Predicate p,
  13438. Iterator itr,
  13439. const Iterator end)
  13440. {
  13441. switch (mode)
  13442. {
  13443. case find_mode::exactly_n : return find_exactly_n_consecutive_values(n,p,itr,end);
  13444. case find_mode::atleast_n : return find_atleast_n_consecutive_values(n,p,itr,end);
  13445. default : return typename range_type<Iterator>::type(end,end);
  13446. }
  13447. }
  13448. template <typename Iterator,typename Predicate>
  13449. inline bool match_exactly_n_consecutive_values(const std::size_t n,
  13450. Predicate p,
  13451. Iterator itr,
  13452. const Iterator end)
  13453. {
  13454. if (static_cast<unsigned int>(std::distance(itr,end)) < n)
  13455. return false;
  13456. std::size_t count = n;
  13457. while (end != itr)
  13458. {
  13459. if (p(*itr))
  13460. {
  13461. if (0 == --count)
  13462. return true;
  13463. else
  13464. ++itr;
  13465. }
  13466. else
  13467. return false;
  13468. }
  13469. return false;
  13470. }
  13471. template <typename Iterator,typename Predicate>
  13472. inline bool match_atleast_n_consecutive_values(const std::size_t n,
  13473. Predicate p,
  13474. Iterator itr,
  13475. const Iterator end)
  13476. {
  13477. if (static_cast<unsigned int>(std::distance(itr,end)) < n)
  13478. return false;
  13479. std::size_t count = 0;
  13480. while (end != itr)
  13481. {
  13482. if (p(*itr))
  13483. {
  13484. ++count;
  13485. ++itr;
  13486. }
  13487. else if (count >= n)
  13488. return true;
  13489. else
  13490. return false;
  13491. }
  13492. return false;
  13493. }
  13494. template <typename Iterator,typename Predicate>
  13495. inline bool match_n_consecutive_values(const std::size_t n,
  13496. find_mode::type mode,
  13497. Predicate p,
  13498. Iterator itr,
  13499. const Iterator end)
  13500. {
  13501. switch (mode)
  13502. {
  13503. case find_mode::exactly_n : return match_exactly_n_consecutive_values(n,p,itr,end);
  13504. case find_mode::atleast_n : return match_atleast_n_consecutive_values(n,p,itr,end);
  13505. default : return false;
  13506. }
  13507. }
  13508. }
  13509. template <typename Iterator>
  13510. inline typename details::range_type<Iterator>::type find_n_consecutive(const std::size_t n,
  13511. find_type::type type,
  13512. find_mode::type mode,
  13513. typename details::range_type<Iterator>::type range)
  13514. {
  13515. switch (type)
  13516. {
  13517. case find_type::digits : return details::find_n_consecutive_values<Iterator>(n,
  13518. mode,
  13519. strtk::text::is_digit,
  13520. range.first,range.second);
  13521. case find_type::letters : return details::find_n_consecutive_values<Iterator>(n,
  13522. mode,
  13523. strtk::text::is_letter,
  13524. range.first,range.second);
  13525. case find_type::lowercase_letters : return details::find_n_consecutive_values<Iterator>(n,
  13526. mode,
  13527. strtk::text::is_lowercase_letter,
  13528. range.first,range.second);
  13529. case find_type::uppercase_letters : return details::find_n_consecutive_values<Iterator>(n,
  13530. mode,
  13531. strtk::text::is_uppercase_letter,
  13532. range.first,range.second);
  13533. case find_type::letters_digits : return details::find_n_consecutive_values<Iterator>(n,
  13534. mode,
  13535. strtk::text::is_letter_or_digit,
  13536. range.first,range.second);
  13537. default : return typename details::range_type<Iterator>::type(range.second,range.second);
  13538. }
  13539. }
  13540. template <typename Iterator>
  13541. inline bool match_n_consecutive(const std::size_t n,
  13542. find_type::type type,
  13543. find_mode::type mode,
  13544. typename details::range_type<Iterator>::type range)
  13545. {
  13546. switch (type)
  13547. {
  13548. case find_type::digits : return details::match_n_consecutive_values<Iterator>(n,
  13549. mode,
  13550. strtk::text::is_digit,
  13551. range.first,range.second);
  13552. case find_type::letters : return details::match_n_consecutive_values<Iterator>(n,
  13553. mode,
  13554. strtk::text::is_letter,
  13555. range.first,range.second);
  13556. case find_type::lowercase_letters : return details::match_n_consecutive_values<Iterator>(n,
  13557. mode,
  13558. strtk::text::is_lowercase_letter,
  13559. range.first,range.second);
  13560. case find_type::uppercase_letters : return details::match_n_consecutive_values<Iterator>(n,
  13561. mode,
  13562. strtk::text::is_uppercase_letter,
  13563. range.first,range.second);
  13564. case find_type::letters_digits : return details::match_n_consecutive_values<Iterator>(n,
  13565. mode,
  13566. strtk::text::is_letter_or_digit,
  13567. range.first,range.second);
  13568. default : return false;
  13569. }
  13570. }
  13571. template <typename Predicate,
  13572. typename OutputIterator>
  13573. inline std::size_t split_on_consecutive(const std::size_t n,
  13574. Predicate p,
  13575. char* begin,
  13576. char* end,
  13577. OutputIterator out,
  13578. const bool stateful_predicate = false)
  13579. {
  13580. if (0 == n) return 0;
  13581. typedef char* iterator_type;
  13582. typedef details::range_type<iterator_type>::type range_type;
  13583. range_type itr_range(begin,end);
  13584. std::size_t match_count = 0;
  13585. while (end != itr_range.first)
  13586. {
  13587. range_type found_itr =
  13588. details::find_exactly_n_consecutive_values<iterator_type,Predicate>(n,
  13589. p,
  13590. itr_range,
  13591. stateful_predicate);
  13592. if ((end == found_itr.first) && (found_itr.first == found_itr.second))
  13593. {
  13594. break;
  13595. }
  13596. else
  13597. {
  13598. (*out) = found_itr;
  13599. ++out;
  13600. ++match_count;
  13601. itr_range.first = found_itr.second;
  13602. }
  13603. }
  13604. return match_count;
  13605. }
  13606. template <typename Predicate,
  13607. typename OutputIterator>
  13608. inline std::size_t split_on_consecutive(const std::size_t n,
  13609. const std::size_t m,
  13610. Predicate p,
  13611. char* begin,
  13612. char* end,
  13613. OutputIterator out)
  13614. {
  13615. if (0 == n) return 0;
  13616. typedef char* iterator_type;
  13617. typedef details::range_type<iterator_type>::type range_type;
  13618. range_type itr_range(begin,end);
  13619. std::size_t match_count = 0;
  13620. while ((end != itr_range.first) && (match_count <= n))
  13621. {
  13622. range_type found_itr = details::find_exactly_n_consecutive_values(m,p,itr_range);
  13623. if ((end == found_itr.first) && (found_itr.first == found_itr.second))
  13624. {
  13625. break;
  13626. }
  13627. else
  13628. {
  13629. (*out) = found_itr;
  13630. ++out;
  13631. ++match_count;
  13632. itr_range.first = found_itr.second;
  13633. }
  13634. }
  13635. return match_count;
  13636. }
  13637. template <typename InputIterator, typename OutputIterator>
  13638. inline std::size_t split_on_consecutive(const std::size_t& n,
  13639. const find_type::type type,
  13640. const find_mode::type mode,
  13641. char* begin,
  13642. char* end,
  13643. OutputIterator out)
  13644. {
  13645. if (0 == n) return 0;
  13646. typedef char* iterator_type;
  13647. typedef details::range_type<iterator_type>::type range_type;
  13648. range_type itr_range(begin,end);
  13649. std::size_t match_count = 0;
  13650. while (end != itr_range.first)
  13651. {
  13652. range_type found_itr = find_n_consecutive<iterator_type>(n,type,mode,itr_range);
  13653. if ((end == found_itr.first) && (found_itr.first == found_itr.second))
  13654. {
  13655. break;
  13656. }
  13657. else
  13658. {
  13659. (*out) = found_itr;
  13660. ++out;
  13661. ++match_count;
  13662. itr_range.first = found_itr.second;
  13663. }
  13664. }
  13665. return match_count;
  13666. }
  13667. template <typename InputIterator, typename OutputIterator>
  13668. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13669. const std::size_t& m,
  13670. const find_type::type type,
  13671. const find_mode::type mode,
  13672. char* begin,
  13673. char* end,
  13674. OutputIterator out)
  13675. {
  13676. if (0 == n) return 0;
  13677. typedef char* iterator_type;
  13678. typedef details::range_type<iterator_type>::type range_type;
  13679. range_type itr_range(begin,end);
  13680. std::size_t match_count = 0;
  13681. while ((end != itr_range.first) && (match_count <= n))
  13682. {
  13683. range_type found_itr = find_n_consecutive<iterator_type>(m,type,mode,itr_range);
  13684. if ((end == found_itr.first) && (found_itr.first == found_itr.second))
  13685. {
  13686. break;
  13687. }
  13688. else
  13689. {
  13690. (*out) = found_itr;
  13691. ++out;
  13692. ++match_count;
  13693. itr_range.first = found_itr.second;
  13694. }
  13695. }
  13696. return match_count;
  13697. }
  13698. template <typename OutputIterator>
  13699. inline std::size_t split_on_consecutive(const std::size_t& n,
  13700. const find_type::type type,
  13701. const find_mode::type mode,
  13702. const char* begin,
  13703. const char* end,
  13704. OutputIterator out)
  13705. {
  13706. return split_on_consecutive<char*,OutputIterator>(n,
  13707. type,
  13708. mode,
  13709. const_cast<char*>(begin),
  13710. const_cast<char*>(end),
  13711. out);
  13712. }
  13713. template <typename OutputIterator>
  13714. inline std::size_t split_on_consecutive(const std::size_t& n,
  13715. const find_type::type type,
  13716. const find_mode::type mode,
  13717. const unsigned char* begin,
  13718. const unsigned char* end,
  13719. OutputIterator out)
  13720. {
  13721. return split_on_consecutive<OutputIterator>(n,
  13722. type,
  13723. mode,
  13724. reinterpret_cast<const char*>(begin),
  13725. reinterpret_cast<const char*>(end),
  13726. out);
  13727. }
  13728. template <typename OutputIterator>
  13729. inline std::size_t split_on_consecutive(const std::size_t& n,
  13730. const find_type::type type,
  13731. const find_mode::type mode,
  13732. const std::string& str,
  13733. OutputIterator out)
  13734. {
  13735. return split_on_consecutive<OutputIterator>(n,
  13736. type,
  13737. mode,
  13738. str.data(),
  13739. str.data() + str.size(),
  13740. out);
  13741. }
  13742. template <typename OutputIterator>
  13743. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13744. const std::size_t& m,
  13745. const find_type::type type,
  13746. const find_mode::type mode,
  13747. const char* begin,
  13748. const char* end,
  13749. OutputIterator out)
  13750. {
  13751. return split_on_consecutive_n<char*,OutputIterator>(n,
  13752. m,
  13753. type,
  13754. mode,
  13755. const_cast<char*>(begin),
  13756. const_cast<char*>(end),
  13757. out);
  13758. }
  13759. template <typename OutputIterator>
  13760. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13761. const std::size_t& m,
  13762. const find_type::type type,
  13763. const find_mode::type mode,
  13764. const unsigned char* begin,
  13765. const unsigned char* end,
  13766. OutputIterator out)
  13767. {
  13768. return split_on_consecutive_n<OutputIterator>(n,
  13769. m,
  13770. type,
  13771. mode,
  13772. reinterpret_cast<const char*>(begin),
  13773. reinterpret_cast<const char*>(end),
  13774. out);
  13775. }
  13776. template <typename OutputIterator>
  13777. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13778. const std::size_t& m,
  13779. const find_type::type type,
  13780. const find_mode::type mode,
  13781. const std::string& str,
  13782. OutputIterator out)
  13783. {
  13784. return split_on_consecutive_n<OutputIterator>(n,
  13785. m,
  13786. type,
  13787. mode,
  13788. str.data(),
  13789. str.data() + str.size(),
  13790. out);
  13791. }
  13792. template <typename Predicate, typename OutputIterator>
  13793. inline std::size_t split_on_consecutive(const std::size_t& n,
  13794. Predicate p,
  13795. const char* begin,
  13796. const char* end,
  13797. OutputIterator out,
  13798. const bool stateful_predicate = false)
  13799. {
  13800. return split_on_consecutive<Predicate,
  13801. OutputIterator>(n,
  13802. p,
  13803. const_cast<char*>(begin),
  13804. const_cast<char*>(end),
  13805. out,
  13806. stateful_predicate);
  13807. }
  13808. template <typename Predicate, typename OutputIterator>
  13809. inline std::size_t split_on_consecutive(const std::size_t& n,
  13810. Predicate p,
  13811. const unsigned char* begin,
  13812. const unsigned char* end,
  13813. OutputIterator out,
  13814. const bool stateful_predicate = false)
  13815. {
  13816. return split_on_consecutive<Predicate,
  13817. OutputIterator>(n,
  13818. p,
  13819. reinterpret_cast<const char*>(begin),
  13820. reinterpret_cast<const char*>(end),
  13821. out,
  13822. stateful_predicate);
  13823. }
  13824. template <typename Predicate, typename OutputIterator>
  13825. inline std::size_t split_on_consecutive(const std::size_t& n,
  13826. Predicate p,
  13827. const std::string& str,
  13828. OutputIterator out,
  13829. const bool stateful_predicate = false)
  13830. {
  13831. return split_on_consecutive<Predicate,
  13832. OutputIterator>(n,
  13833. p,
  13834. str.data(),
  13835. str.data() + str.size(),
  13836. out,
  13837. stateful_predicate);
  13838. }
  13839. template <typename Predicate, typename OutputIterator>
  13840. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13841. const std::size_t& m,
  13842. Predicate p,
  13843. const char* begin,
  13844. const char* end,
  13845. OutputIterator out)
  13846. {
  13847. return split_on_consecutive_n<Predicate,
  13848. char*,
  13849. OutputIterator>(n,
  13850. m,
  13851. p,
  13852. const_cast<char*>(begin),
  13853. const_cast<char*>(end),
  13854. out);
  13855. }
  13856. template <typename Predicate, typename OutputIterator>
  13857. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13858. const std::size_t& m,
  13859. Predicate p,
  13860. const unsigned char* begin,
  13861. const unsigned char* end,
  13862. OutputIterator out)
  13863. {
  13864. return split_on_consecutive_n<Predicate,
  13865. OutputIterator>(n,
  13866. m,
  13867. p,
  13868. reinterpret_cast<const char*>(begin),
  13869. reinterpret_cast<const char*>(end),
  13870. out);
  13871. }
  13872. template <typename Predicate, typename OutputIterator>
  13873. inline std::size_t split_on_consecutive_n(const std::size_t& n,
  13874. const std::size_t& m,
  13875. Predicate p,
  13876. const std::string& str,
  13877. OutputIterator out)
  13878. {
  13879. return split_on_consecutive_n<Predicate,
  13880. OutputIterator>(n,
  13881. m,
  13882. p,
  13883. str.data(),
  13884. str.data() + str.size(),
  13885. out);
  13886. }
  13887. // Required for broken versions of GCC pre 4.5
  13888. namespace util { class value; }
  13889. namespace details
  13890. {
  13891. class expect_impl
  13892. {
  13893. public:
  13894. expect_impl(const std::string& s)
  13895. : s_(s)
  13896. {}
  13897. template <typename InputIterator>
  13898. inline bool operator()(InputIterator begin, InputIterator end)
  13899. {
  13900. if (static_cast<std::size_t>(std::distance(begin,end)) != s_.size())
  13901. return false;
  13902. else
  13903. return std::equal(s_.data(),s_.data() + s_.size(),begin);
  13904. }
  13905. inline expect_impl& ref()
  13906. {
  13907. return (*this);
  13908. }
  13909. inline void set_value(const std::string& s)
  13910. {
  13911. s_ = s;
  13912. }
  13913. private:
  13914. std::string s_;
  13915. };
  13916. class iexpect_impl
  13917. {
  13918. public:
  13919. iexpect_impl(const std::string& s)
  13920. : s_(s)
  13921. {}
  13922. template <typename InputIterator>
  13923. inline bool operator()(InputIterator begin, InputIterator end)
  13924. {
  13925. if (static_cast<std::size_t>(std::distance(begin,end)) != s_.size())
  13926. return false;
  13927. else
  13928. return std::equal(s_.data(),s_.data() + s_.size(),begin,imatch_char);
  13929. }
  13930. inline iexpect_impl& ref()
  13931. {
  13932. return (*this);
  13933. }
  13934. inline void set_value(const std::string& s)
  13935. {
  13936. s_ = s;
  13937. }
  13938. private:
  13939. std::string s_;
  13940. };
  13941. class like_impl
  13942. {
  13943. public:
  13944. like_impl(const std::string& s)
  13945. : s_(s)
  13946. {}
  13947. template <typename InputIterator>
  13948. inline bool operator()(InputIterator begin, InputIterator end)
  13949. {
  13950. typedef typename std::iterator_traits<InputIterator>::value_type value_type;
  13951. static const value_type zero_or_more = value_type('*');
  13952. static const value_type zero_or_one = value_type('?');
  13953. return strtk::match(s_.data(),s_.data() + s_.size(),begin,end,zero_or_more,zero_or_one);
  13954. }
  13955. inline like_impl& ref()
  13956. {
  13957. return (*this);
  13958. }
  13959. inline void set_pattern(const std::string& s)
  13960. {
  13961. s_ = s;
  13962. }
  13963. private:
  13964. std::string s_;
  13965. };
  13966. template <typename T>
  13967. class inrange_impl
  13968. {
  13969. public:
  13970. inrange_impl(T& t, const T& low, const T& hi)
  13971. : t_(&t),
  13972. low_(low),
  13973. hi_(hi)
  13974. {}
  13975. template <typename InputIterator>
  13976. inline bool operator()(InputIterator begin, InputIterator end)
  13977. {
  13978. T temp;
  13979. if (!strtk::string_to_type_converter(begin,end,temp))
  13980. return false;
  13981. else if (temp < low_)
  13982. return false;
  13983. else if (temp > hi_)
  13984. return false;
  13985. (*t_) = temp;
  13986. return true;
  13987. }
  13988. inline inrange_impl<T>& ref()
  13989. {
  13990. return (*this);
  13991. }
  13992. inline void set_low_hi(const T& low, const T& hi)
  13993. {
  13994. low_ = low;
  13995. hi_ = hi;
  13996. }
  13997. private:
  13998. T* t_;
  13999. T low_;
  14000. T hi_;
  14001. };
  14002. namespace trim_details
  14003. {
  14004. template <typename Type>
  14005. struct convert_impl
  14006. {
  14007. template <typename InputIterator>
  14008. static bool execute(InputIterator begin, InputIterator end,
  14009. const std::string& rem_chars,
  14010. std::size_t mode,
  14011. Type& t)
  14012. {
  14013. std::string s;
  14014. if (!strtk::string_to_type_converter(begin,end,s))
  14015. return false;
  14016. switch (mode)
  14017. {
  14018. case 0 : remove_leading_trailing(rem_chars,s); break;
  14019. case 1 : remove_leading (rem_chars,s); break;
  14020. case 2 : remove_trailing (rem_chars,s); break;
  14021. default : return false;
  14022. }
  14023. return strtk::string_to_type_converter(s,t);
  14024. }
  14025. };
  14026. template <>
  14027. struct convert_impl <std::string>
  14028. {
  14029. template <typename InputIterator>
  14030. static bool execute(InputIterator begin, InputIterator end,
  14031. const std::string& rem_chars,
  14032. std::size_t mode,
  14033. std::string& t)
  14034. {
  14035. if (!strtk::string_to_type_converter(begin,end,t))
  14036. return false;
  14037. switch (mode)
  14038. {
  14039. case 0 : remove_leading_trailing(rem_chars,t); break;
  14040. case 1 : remove_leading (rem_chars,t); break;
  14041. case 2 : remove_trailing (rem_chars,t); break;
  14042. default : return false;
  14043. }
  14044. return true;
  14045. }
  14046. };
  14047. }
  14048. template <typename T>
  14049. class trim_impl
  14050. {
  14051. public:
  14052. trim_impl(const std::size_t mode,
  14053. T& t,
  14054. const std::string& rem_chars = " ")
  14055. : mode_(mode),
  14056. t_(&t),
  14057. rem_chars_(rem_chars)
  14058. {}
  14059. template <typename InputIterator>
  14060. inline bool operator()(InputIterator begin, InputIterator end)
  14061. {
  14062. return trim_details::convert_impl<T>::execute(begin,end,rem_chars_,mode_,(*t_));
  14063. }
  14064. inline trim_impl<T>& ref()
  14065. {
  14066. return (*this);
  14067. }
  14068. private:
  14069. std::size_t mode_;
  14070. T* t_;
  14071. std::string rem_chars_;
  14072. };
  14073. class conv_to_lcase_impl
  14074. {
  14075. public:
  14076. conv_to_lcase_impl(std::string& s)
  14077. : s_(&s)
  14078. {}
  14079. template <typename InputIterator>
  14080. inline bool operator()(InputIterator begin, InputIterator end)
  14081. {
  14082. std::string& s = (*s_);
  14083. s.assign(begin,end);
  14084. convert_to_lowercase(s);
  14085. return true;
  14086. }
  14087. inline conv_to_lcase_impl& ref()
  14088. {
  14089. return (*this);
  14090. }
  14091. private:
  14092. std::string* s_;
  14093. };
  14094. class conv_to_ucase_impl
  14095. {
  14096. public:
  14097. conv_to_ucase_impl(std::string& s)
  14098. : s_(&s)
  14099. {}
  14100. template <typename InputIterator>
  14101. inline bool operator()(InputIterator begin, InputIterator end)
  14102. {
  14103. std::string& s = (*s_);
  14104. s.assign(begin,end);
  14105. convert_to_uppercase(s);
  14106. return true;
  14107. }
  14108. inline conv_to_ucase_impl& ref()
  14109. {
  14110. return (*this);
  14111. }
  14112. private:
  14113. std::string* s_;
  14114. };
  14115. class fill_array_impl
  14116. {
  14117. public:
  14118. fill_array_impl(unsigned char* data, const std::size_t& size)
  14119. : data_(data),
  14120. size_(size)
  14121. {}
  14122. template <typename InputIterator>
  14123. inline bool operator()(InputIterator begin, InputIterator end)
  14124. {
  14125. const std::size_t range_size = static_cast<std::size_t>(std::distance(begin,end));
  14126. if (range_size != size_)
  14127. return false;
  14128. std::memcpy(data_,begin,range_size);
  14129. return true;
  14130. }
  14131. inline fill_array_impl& ref()
  14132. {
  14133. return (*this);
  14134. }
  14135. inline fill_array_impl& set(unsigned char* data, const std::size_t& size)
  14136. {
  14137. data_ = data;
  14138. size_ = size;
  14139. return (*this);
  14140. }
  14141. inline fill_array_impl& set(char* data, const std::size_t& size)
  14142. {
  14143. data_ = reinterpret_cast<unsigned char*>(data);
  14144. size_ = size;
  14145. return (*this);
  14146. }
  14147. inline fill_array_impl& set_data(unsigned char* data)
  14148. {
  14149. data_ = data;
  14150. return (*this);
  14151. }
  14152. inline fill_array_impl& set_data(char* data)
  14153. {
  14154. data_ = reinterpret_cast<unsigned char*>(data);
  14155. return (*this);
  14156. }
  14157. inline fill_array_impl& set_size(const std::size_t& size)
  14158. {
  14159. size_ = size;
  14160. return (*this);
  14161. }
  14162. private:
  14163. unsigned char* data_;
  14164. std::size_t size_;
  14165. };
  14166. }
  14167. inline details::expect_impl expect(const std::string& s)
  14168. {
  14169. return details::expect_impl(s);
  14170. }
  14171. inline details::iexpect_impl iexpect(const std::string& s)
  14172. {
  14173. return details::iexpect_impl(s);
  14174. }
  14175. inline details::like_impl like(const std::string& s)
  14176. {
  14177. return details::like_impl(s);
  14178. }
  14179. template <typename T, typename T0, typename T1>
  14180. inline details::inrange_impl<T> inrange(T& t, const T0& low, const T1& hi)
  14181. {
  14182. return details::inrange_impl<T>(t,T(low),T(hi));
  14183. }
  14184. template <typename T>
  14185. inline details::trim_impl<T> trim(const std::string& rem_chars, T& t)
  14186. {
  14187. return details::trim_impl<T>(0,t,rem_chars);
  14188. }
  14189. template <typename T>
  14190. inline details::trim_impl<T> trim_leading(const std::string& rem_chars, T& t)
  14191. {
  14192. return details::trim_impl<T>(1,t,rem_chars);
  14193. }
  14194. template <typename T>
  14195. inline details::trim_impl<T> trim_trailing(const std::string& rem_chars, T& t)
  14196. {
  14197. return details::trim_impl<T>(2,t,rem_chars);
  14198. }
  14199. inline details::conv_to_lcase_impl as_lcase(std::string& s)
  14200. {
  14201. return details::conv_to_lcase_impl(s);
  14202. }
  14203. inline details::conv_to_ucase_impl as_ucase(std::string& s)
  14204. {
  14205. return details::conv_to_ucase_impl(s);
  14206. }
  14207. inline details::fill_array_impl fill_array(unsigned char* data, const std::size_t& size)
  14208. {
  14209. return details::fill_array_impl(data,size);
  14210. }
  14211. inline details::fill_array_impl fill_array(char* data, const std::size_t& size)
  14212. {
  14213. return details::fill_array_impl(reinterpret_cast<unsigned char*>(data),size);
  14214. }
  14215. template <std::size_t N>
  14216. inline details::fill_array_impl fill_array(unsigned char (&data)[N])
  14217. {
  14218. return details::fill_array_impl(data,N);
  14219. }
  14220. template <std::size_t N>
  14221. inline details::fill_array_impl fill_array(char (&data)[N])
  14222. {
  14223. return details::fill_array_impl(reinterpret_cast<unsigned char*>(data),N);
  14224. }
  14225. inline details::fill_array_impl fill_array(std::string& data, const std::size_t& size)
  14226. {
  14227. return fill_array(const_cast<char*>(data.data()),size);
  14228. }
  14229. inline details::fill_array_impl fill_array(std::string& data)
  14230. {
  14231. return fill_array(const_cast<char*>(data.data()),data.size());
  14232. }
  14233. namespace details
  14234. {
  14235. static const unsigned char digit_table[] =
  14236. {
  14237. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xFF - 0x07
  14238. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x08 - 0x0F
  14239. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x10 - 0x17
  14240. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x18 - 0x1F
  14241. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x20 - 0x27
  14242. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x28 - 0x2F
  14243. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 0x30 - 0x37
  14244. 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x38 - 0x3F
  14245. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x40 - 0x47
  14246. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x48 - 0x4F
  14247. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x50 - 0x57
  14248. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x58 - 0x5F
  14249. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x60 - 0x67
  14250. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x68 - 0x6F
  14251. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x70 - 0x77
  14252. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x78 - 0x7F
  14253. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x80 - 0x87
  14254. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x88 - 0x8F
  14255. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x90 - 0x97
  14256. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x98 - 0x9F
  14257. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA0 - 0xA7
  14258. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA8 - 0xAF
  14259. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB0 - 0xB7
  14260. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB8 - 0xBF
  14261. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC0 - 0xC7
  14262. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC8 - 0xCF
  14263. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD0 - 0xD7
  14264. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD8 - 0xDF
  14265. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE0 - 0xE7
  14266. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE8 - 0xEF
  14267. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xF0 - 0xF7
  14268. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 0xF8 - 0xFF
  14269. };
  14270. static const std::size_t digit_table_size = sizeof(digit_table) / sizeof(unsigned char);
  14271. template <typename T>
  14272. static inline bool is_invalid_digit(const T& t)
  14273. {
  14274. static const unsigned int invalid_digit = 0xFF;
  14275. return (static_cast<T>(invalid_digit) == t);
  14276. }
  14277. template <typename T>
  14278. static inline bool is_valid_digit(const T& t)
  14279. {
  14280. static const unsigned int invalid_digit = 0xFF;
  14281. return (static_cast<T>(invalid_digit) != t);
  14282. }
  14283. static const unsigned char digitr[] =
  14284. {
  14285. "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  14286. };
  14287. static const unsigned char rev_3digit_lut[] =
  14288. {
  14289. "000001002003004005006007008009010011012013014015016017018019020021022023024"
  14290. "025026027028029030031032033034035036037038039040041042043044045046047048049"
  14291. "050051052053054055056057058059060061062063064065066067068069070071072073074"
  14292. "075076077078079080081082083084085086087088089090091092093094095096097098099"
  14293. "100101102103104105106107108109110111112113114115116117118119120121122123124"
  14294. "125126127128129130131132133134135136137138139140141142143144145146147148149"
  14295. "150151152153154155156157158159160161162163164165166167168169170171172173174"
  14296. "175176177178179180181182183184185186187188189190191192193194195196197198199"
  14297. "200201202203204205206207208209210211212213214215216217218219220221222223224"
  14298. "225226227228229230231232233234235236237238239240241242243244245246247248249"
  14299. "250251252253254255256257258259260261262263264265266267268269270271272273274"
  14300. "275276277278279280281282283284285286287288289290291292293294295296297298299"
  14301. "300301302303304305306307308309310311312313314315316317318319320321322323324"
  14302. "325326327328329330331332333334335336337338339340341342343344345346347348349"
  14303. "350351352353354355356357358359360361362363364365366367368369370371372373374"
  14304. "375376377378379380381382383384385386387388389390391392393394395396397398399"
  14305. "400401402403404405406407408409410411412413414415416417418419420421422423424"
  14306. "425426427428429430431432433434435436437438439440441442443444445446447448449"
  14307. "450451452453454455456457458459460461462463464465466467468469470471472473474"
  14308. "475476477478479480481482483484485486487488489490491492493494495496497498499"
  14309. "500501502503504505506507508509510511512513514515516517518519520521522523524"
  14310. "525526527528529530531532533534535536537538539540541542543544545546547548549"
  14311. "550551552553554555556557558559560561562563564565566567568569570571572573574"
  14312. "575576577578579580581582583584585586587588589590591592593594595596597598599"
  14313. "600601602603604605606607608609610611612613614615616617618619620621622623624"
  14314. "625626627628629630631632633634635636637638639640641642643644645646647648649"
  14315. "650651652653654655656657658659660661662663664665666667668669670671672673674"
  14316. "675676677678679680681682683684685686687688689690691692693694695696697698699"
  14317. "700701702703704705706707708709710711712713714715716717718719720721722723724"
  14318. "725726727728729730731732733734735736737738739740741742743744745746747748749"
  14319. "750751752753754755756757758759760761762763764765766767768769770771772773774"
  14320. "775776777778779780781782783784785786787788789790791792793794795796797798799"
  14321. "800801802803804805806807808809810811812813814815816817818819820821822823824"
  14322. "825826827828829830831832833834835836837838839840841842843844845846847848849"
  14323. "850851852853854855856857858859860861862863864865866867868869870871872873874"
  14324. "875876877878879880881882883884885886887888889890891892893894895896897898899"
  14325. "900901902903904905906907908909910911912913914915916917918919920921922923924"
  14326. "925926927928929930931932933934935936937938939940941942943944945946947948949"
  14327. "950951952953954955956957958959960961962963964965966967968969970971972973974"
  14328. "975976977978979980981982983984985986987988989990991992993994995996997998999"
  14329. "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  14330. };
  14331. static const unsigned char rev_2digit_lut[] =
  14332. {
  14333. "0001020304050607080910111213141516171819"
  14334. "2021222324252627282930313233343536373839"
  14335. "4041424344454647484950515253545556575859"
  14336. "6061626364656667686970717273747576777879"
  14337. "8081828384858687888990919293949596979899"
  14338. "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  14339. };
  14340. template <typename T>
  14341. inline T pow10(T d, const int exponent)
  14342. {
  14343. static const double fract10[] =
  14344. {
  14345. 0.0,
  14346. 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,
  14347. 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,
  14348. 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,
  14349. 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,
  14350. 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,
  14351. 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,
  14352. 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,
  14353. 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,
  14354. 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,
  14355. 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,
  14356. 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,
  14357. 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,
  14358. 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,
  14359. 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,
  14360. 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,
  14361. 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,
  14362. 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,
  14363. 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,
  14364. 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,
  14365. 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,
  14366. 1.0E+201, 1.0E+202, 1.0E+203, 1.0E+204, 1.0E+205, 1.0E+206, 1.0E+207, 1.0E+208, 1.0E+209, 1.0E+210,
  14367. 1.0E+211, 1.0E+212, 1.0E+213, 1.0E+214, 1.0E+215, 1.0E+216, 1.0E+217, 1.0E+218, 1.0E+219, 1.0E+220,
  14368. 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,
  14369. 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,
  14370. 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,
  14371. 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,
  14372. 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,
  14373. 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,
  14374. 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,
  14375. 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,
  14376. 1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308
  14377. };
  14378. static const int fract10_size = static_cast<int>(sizeof(fract10) / sizeof(double));
  14379. const int e = std::abs(exponent);
  14380. if (exponent >= std::numeric_limits<T>::min_exponent10)
  14381. {
  14382. if (e < fract10_size)
  14383. {
  14384. if (exponent > 0)
  14385. return T(d * fract10[e]);
  14386. else
  14387. return T(d / fract10[e]);
  14388. }
  14389. else
  14390. return T(d * std::pow(10.0, 10.0 * exponent));
  14391. }
  14392. else
  14393. {
  14394. d /= fract10[ -std::numeric_limits<T>::min_exponent10];
  14395. return T(d / fract10[-exponent + std::numeric_limits<T>::min_exponent10]);
  14396. }
  14397. }
  14398. #define strtk_register_pod_type(T) \
  14399. template<> struct is_pod<T>{ typedef yes_t result_t; enum {result = true }; }; \
  14400. template<> struct is_pod<const T>{ typedef yes_t result_t; enum {result = true }; }; \
  14401. template<> struct is_pod<volatile T>{ typedef yes_t result_t; enum {result = true }; }; \
  14402. template<> struct is_pod<const volatile T>{ typedef yes_t result_t; enum {result = true }; };\
  14403. strtk_register_pod_type(bool)
  14404. strtk_register_pod_type(signed char)
  14405. strtk_register_pod_type(char)
  14406. strtk_register_pod_type(short)
  14407. strtk_register_pod_type(int)
  14408. strtk_register_pod_type(long int)
  14409. strtk_register_pod_type(long long int)
  14410. strtk_register_pod_type(unsigned char)
  14411. strtk_register_pod_type(unsigned short)
  14412. strtk_register_pod_type(unsigned int)
  14413. strtk_register_pod_type(unsigned long int)
  14414. strtk_register_pod_type(unsigned long long int)
  14415. strtk_register_pod_type(float)
  14416. strtk_register_pod_type(double)
  14417. strtk_register_pod_type(long double)
  14418. #undef strtk_register_pod_type
  14419. template <typename>
  14420. struct numeric {};
  14421. template<>
  14422. struct numeric<short>
  14423. {
  14424. static const unsigned int length = 5;
  14425. static const unsigned int size = 16;
  14426. static const unsigned int bound_length = 5;
  14427. static const short m10 = 3276;
  14428. static const short ldpos = 7;
  14429. static const short ldneg = 8;
  14430. };
  14431. template<>
  14432. struct numeric<unsigned short>
  14433. {
  14434. static const unsigned int length = 5;
  14435. static const unsigned int size = 16;
  14436. static const unsigned int bound_length = 5;
  14437. static const unsigned short m10 = 6553;
  14438. static const unsigned short ldpos = 5;
  14439. };
  14440. template<>
  14441. struct numeric<int>
  14442. {
  14443. static const unsigned int length = 10;
  14444. static const unsigned int size = 16;
  14445. static const unsigned int bound_length = 10;
  14446. static const int m10 = 214748364;
  14447. static const int ldpos = 7;
  14448. static const int ldneg = 8;
  14449. };
  14450. template<>
  14451. struct numeric<unsigned int>
  14452. {
  14453. static const unsigned int length = 10;
  14454. static const unsigned int size = 16;
  14455. static const unsigned int bound_length = 10;
  14456. static const unsigned int m10 = 429496729;
  14457. static const unsigned int ldpos = 5;
  14458. };
  14459. template<>
  14460. struct numeric<long>
  14461. {
  14462. static const unsigned int length = 10;
  14463. static const unsigned int size = 16;
  14464. static const unsigned int bound_length = 10;
  14465. static const long m10 = 214748364;
  14466. static const long ldpos = 7;
  14467. static const long ldneg = 8;
  14468. };
  14469. template<>
  14470. struct numeric<unsigned long>
  14471. {
  14472. static const unsigned int length = 10;
  14473. static const unsigned int size = 16;
  14474. static const unsigned int bound_length = 10;
  14475. static const unsigned long m10 = 429496729;
  14476. static const unsigned long ldpos = 5;
  14477. };
  14478. template<>
  14479. struct numeric<long long>
  14480. {
  14481. static const unsigned int length = 19;
  14482. static const unsigned int size = 24;
  14483. static const unsigned int bound_length = 19;
  14484. static const unsigned long long m10 = 922337203685477580;
  14485. static const unsigned long long ldpos = 7;
  14486. static const unsigned long long ldneg = 8;
  14487. };
  14488. template<>
  14489. struct numeric<unsigned long long int>
  14490. {
  14491. static const unsigned int length = 20;
  14492. static const unsigned int size = 24;
  14493. static const unsigned int bound_length = 19;
  14494. static const unsigned long long m10 = 1844674407370955161;
  14495. static const unsigned long long ldpos = 5;
  14496. };
  14497. template<> struct numeric<float> { enum { min_exp = -37, max_exp = +38, precision = 10}; };
  14498. template<> struct numeric<double> { enum { min_exp = -307, max_exp = +308, precision = 15}; };
  14499. template <typename ld, std::size_t size> struct ldt {};
  14500. template <> struct ldt <long double, sizeof(double)> { enum { i = -308, a = +308, p = 15}; }; // 64-bit
  14501. template <> struct ldt <long double, 10> { enum { i = -4931, a = +4931, p = 18}; }; // 80-bit
  14502. template <> struct ldt <long double, 12> { enum { i = -4931, a = +4931, p = 22}; }; // 96-bit
  14503. template <> struct ldt <long double, 2 * sizeof(double)> { enum { i = -4931, a = +4931, p = 34}; }; //128-bit
  14504. template<>
  14505. struct numeric<long double>
  14506. {
  14507. typedef ldt<long double, sizeof(long double)> ld;
  14508. enum { min_exp = ld::i, max_exp = ld::a, precision = ld::p};
  14509. };
  14510. #define strtk_register_unsigned_type_tag(T) \
  14511. template<> struct supported_conversion_to_type<T> { typedef unsigned_type_tag type; }; \
  14512. template<> struct supported_conversion_from_type<T> { typedef unsigned_type_tag type; };\
  14513. #define strtk_register_signed_type_tag(T) \
  14514. template<> struct supported_conversion_to_type<T>{ typedef signed_type_tag type; }; \
  14515. template<> struct supported_conversion_from_type<T> { typedef signed_type_tag type; }; \
  14516. #define strtk_register_real_type_tag(T) \
  14517. template<> struct supported_conversion_to_type<T>{ typedef real_type_tag type; };
  14518. #define strtk_register_byte_type_tag(T) \
  14519. template<> struct supported_conversion_to_type<T>{ typedef byte_type_tag type; }; \
  14520. template<> struct supported_conversion_from_type<T> { typedef byte_type_tag type; };\
  14521. #define strtk_register_hex_number_type_tag(T) \
  14522. template<> struct supported_conversion_to_type<T >{ typedef hex_number_type_tag type; };
  14523. template<> struct supported_conversion_to_type<hex_to_string_sink>{ typedef hex_string_type_tag type; };
  14524. #define strtk_register_base64_type_tag(T) \
  14525. template<> struct supported_conversion_to_type<T >{ typedef base64_type_tag type; };
  14526. #define strtk_register_supported_iterator_type(T) \
  14527. template<> struct supported_iterator_type<T> { enum { value = true }; };
  14528. template<> struct supported_conversion_to_type<bool> { typedef bool_type_tag type; };
  14529. template<> struct supported_iterator_type<bool> { enum { value = true }; };
  14530. template<> struct supported_conversion_to_type<std::string> { typedef stdstring_type_tag type; };
  14531. template<> struct supported_iterator_type<std::string> { enum { value = true }; };
  14532. template<> struct supported_conversion_to_type<strtk::util::value> { typedef value_type_tag type; };
  14533. template<> struct supported_conversion_from_type<strtk::util::value> { typedef value_type_tag type; };
  14534. template<> struct supported_iterator_type<strtk::util::value> { enum { value = true }; };
  14535. template<> struct supported_conversion_to_type<strtk::details::expect_impl> { typedef expect_type_tag type; };
  14536. template<> struct supported_iterator_type<strtk::details::expect_impl> { enum { value = true }; };
  14537. template<> struct supported_conversion_to_type<strtk::details::iexpect_impl> { typedef expect_type_tag type; };
  14538. template<> struct supported_iterator_type<strtk::details::iexpect_impl> { enum { value = true }; };
  14539. template<> struct supported_conversion_to_type<strtk::details::like_impl> { typedef like_type_tag type; };
  14540. template<> struct supported_iterator_type<strtk::details::like_impl> { enum { value = true }; };
  14541. template<> struct supported_conversion_to_type<strtk::details::fill_array_impl> { typedef fillchararray_type_tag type; };
  14542. template<> struct supported_iterator_type<strtk::details::fill_array_impl> { enum { value = true }; };
  14543. template<> struct supported_conversion_to_type<strtk::details::conv_to_lcase_impl> { typedef lcase_type_tag type; };
  14544. template<> struct supported_iterator_type<strtk::details::conv_to_lcase_impl> { enum { value = true }; };
  14545. template<> struct supported_conversion_to_type<strtk::details::conv_to_ucase_impl> { typedef ucase_type_tag type; };
  14546. template<> struct supported_iterator_type<strtk::details::conv_to_ucase_impl> { enum { value = true }; };
  14547. #define strtk_register_truncint_type_tag(T) \
  14548. template<> struct supported_conversion_to_type<strtk::truncated_int<T> > { typedef truncint_type_tag type; };\
  14549. template<> struct supported_iterator_type<strtk::truncated_int<T> > { enum { value = true }; };
  14550. #define strtk_register_decsink_type_tag(T) \
  14551. template<> struct supported_conversion_to_type<strtk::decimal_sink<T> > { typedef decsink_type_tag type; };\
  14552. template<> struct supported_iterator_type<strtk::decimal_sink<T> > { enum { value = true }; };
  14553. #define strtk_register_inrange_type_tag(T) \
  14554. template<> struct supported_conversion_to_type<strtk::details::inrange_impl<T> > { typedef inrange_type_tag type; };\
  14555. template<> struct supported_iterator_type<strtk::details::inrange_impl<T> > { enum { value = true }; };
  14556. #define strtk_register_trim_type_tag(T) \
  14557. template<> struct supported_conversion_to_type<strtk::details::trim_impl<T> > { typedef trim_type_tag type; };\
  14558. template<> struct supported_iterator_type<strtk::details::trim_impl<T> > { enum { value = true }; };
  14559. #define strtk_register_stdstring_range_type_tag(T) \
  14560. template<> struct supported_conversion_to_type< std::pair<T,T> >{ typedef stdstring_range_type_tag type; };
  14561. #define strtk_register_sink_type_tag(T) \
  14562. template<> struct supported_conversion_to_type<sink_type<std::vector<T> > > { typedef sink_type_tag type; }; \
  14563. template<> struct supported_conversion_to_type<sink_type<std::deque<T> > > { typedef sink_type_tag type; }; \
  14564. template<> struct supported_conversion_to_type<sink_type<std::list<T> > > { typedef sink_type_tag type; }; \
  14565. template<> struct supported_conversion_to_type<sink_type<std::set<T> > > { typedef sink_type_tag type; }; \
  14566. template<> struct supported_conversion_to_type<sink_type<std::multiset<T> > > { typedef sink_type_tag type; }; \
  14567. template<> struct supported_conversion_to_type<sink_type<std::queue<T> > > { typedef sink_type_tag type; }; \
  14568. template<> struct supported_conversion_to_type<sink_type<std::stack<T> > > { typedef sink_type_tag type; }; \
  14569. template<> struct supported_conversion_to_type<sink_type<std::priority_queue<T> > > { typedef sink_type_tag type; }; \
  14570. template<> struct supported_conversion_from_type<sink_type<std::vector<T> > > { typedef sink_type_tag type; }; \
  14571. template<> struct supported_conversion_from_type<sink_type<std::deque<T> > > { typedef sink_type_tag type; }; \
  14572. template<> struct supported_conversion_from_type<sink_type<std::list<T> > > { typedef sink_type_tag type; }; \
  14573. template<> struct supported_conversion_from_type<sink_type<std::set<T> > > { typedef sink_type_tag type; }; \
  14574. template<> struct supported_conversion_from_type<sink_type<std::multiset<T> > > { typedef sink_type_tag type; }; \
  14575. template<> struct supported_conversion_from_type<sink_type<std::queue<T> > > { typedef sink_type_tag type; }; \
  14576. template<> struct supported_conversion_from_type<sink_type<std::stack<T> > > { typedef sink_type_tag type; }; \
  14577. template<> struct supported_conversion_from_type<sink_type<std::priority_queue<T> > > { typedef sink_type_tag type; };\
  14578. #define strtk_register_stl_container_to_string_conv_type_tag(T) \
  14579. template<> struct supported_conversion_from_type<std::vector<T> > { typedef stl_seq_type_tag type; }; \
  14580. template<> struct supported_conversion_from_type<std::deque<T> > { typedef stl_seq_type_tag type; }; \
  14581. template<> struct supported_conversion_from_type<std::list<T> > { typedef stl_seq_type_tag type; }; \
  14582. template<> struct supported_conversion_from_type<std::set<T> > { typedef stl_seq_type_tag type; }; \
  14583. template<> struct supported_conversion_from_type<std::multiset<T> > { typedef stl_seq_type_tag type; }; \
  14584. template<> struct supported_conversion_from_type<std::queue<T> > { typedef stl_seq_type_tag type; }; \
  14585. template<> struct supported_conversion_from_type<std::stack<T> > { typedef stl_seq_type_tag type; }; \
  14586. template<> struct supported_conversion_from_type<std::priority_queue<T> > { typedef stl_seq_type_tag type; };\
  14587. template<> struct supported_conversion_to_type<ignore_token>{ typedef ignore_token_type_tag type; };
  14588. #define strtk_register_sequence_iterator_type(sequence) \
  14589. strtk_register_supported_iterator_type(sequence<char>::iterator) \
  14590. strtk_register_supported_iterator_type(sequence<char>::const_iterator) \
  14591. strtk_register_supported_iterator_type(sequence<unsigned char>::iterator) \
  14592. strtk_register_supported_iterator_type(sequence<unsigned char>::const_iterator)\
  14593. strtk_register_unsigned_type_tag(unsigned short)
  14594. strtk_register_unsigned_type_tag(unsigned int)
  14595. strtk_register_unsigned_type_tag(unsigned long)
  14596. strtk_register_unsigned_type_tag(unsigned long long int)
  14597. strtk_register_signed_type_tag(short)
  14598. strtk_register_signed_type_tag(int)
  14599. strtk_register_signed_type_tag(long)
  14600. strtk_register_signed_type_tag(long long)
  14601. strtk_register_real_type_tag(float)
  14602. strtk_register_real_type_tag(double)
  14603. strtk_register_real_type_tag(long double)
  14604. strtk_register_byte_type_tag(unsigned char)
  14605. strtk_register_byte_type_tag(signed char)
  14606. strtk_register_byte_type_tag(char)
  14607. strtk_register_hex_number_type_tag(hex_to_number_sink<short>)
  14608. strtk_register_hex_number_type_tag(hex_to_number_sink<int>)
  14609. strtk_register_hex_number_type_tag(hex_to_number_sink<long>)
  14610. strtk_register_hex_number_type_tag(hex_to_number_sink<long long>)
  14611. strtk_register_hex_number_type_tag(hex_to_number_sink<unsigned short>)
  14612. strtk_register_hex_number_type_tag(hex_to_number_sink<unsigned int>)
  14613. strtk_register_hex_number_type_tag(hex_to_number_sink<unsigned long>)
  14614. strtk_register_hex_number_type_tag(hex_to_number_sink<unsigned long long int>)
  14615. strtk_register_base64_type_tag(base64_to_number_sink<short>)
  14616. strtk_register_base64_type_tag(base64_to_number_sink<int>)
  14617. strtk_register_base64_type_tag(base64_to_number_sink<long>)
  14618. strtk_register_base64_type_tag(base64_to_number_sink<long long>)
  14619. strtk_register_base64_type_tag(base64_to_number_sink<unsigned short>)
  14620. strtk_register_base64_type_tag(base64_to_number_sink<unsigned int>)
  14621. strtk_register_base64_type_tag(base64_to_number_sink<unsigned long>)
  14622. strtk_register_base64_type_tag(base64_to_number_sink<unsigned long long int>)
  14623. strtk_register_stdstring_range_type_tag(std::string::iterator)
  14624. strtk_register_stdstring_range_type_tag(std::string::const_iterator)
  14625. strtk_register_stdstring_range_type_tag(char*)
  14626. strtk_register_stdstring_range_type_tag(signed char*)
  14627. strtk_register_stdstring_range_type_tag(unsigned char*)
  14628. strtk_register_stdstring_range_type_tag(const char*)
  14629. strtk_register_stdstring_range_type_tag(const unsigned char*)
  14630. strtk_register_supported_iterator_type(char*)
  14631. strtk_register_supported_iterator_type(signed char*)
  14632. strtk_register_supported_iterator_type(unsigned char*)
  14633. strtk_register_supported_iterator_type(const char*)
  14634. strtk_register_supported_iterator_type(const signed char*)
  14635. strtk_register_supported_iterator_type(const unsigned char*)
  14636. strtk_register_supported_iterator_type(std::string::iterator)
  14637. strtk_register_supported_iterator_type(std::string::const_iterator)
  14638. strtk_register_sequence_iterator_type(std::vector)
  14639. strtk_register_sequence_iterator_type(std::deque)
  14640. strtk_register_sink_type_tag(float)
  14641. strtk_register_sink_type_tag(double)
  14642. strtk_register_sink_type_tag(long double)
  14643. strtk_register_sink_type_tag(signed char)
  14644. strtk_register_sink_type_tag(char)
  14645. strtk_register_sink_type_tag(short)
  14646. strtk_register_sink_type_tag(int)
  14647. strtk_register_sink_type_tag(long)
  14648. strtk_register_sink_type_tag(long long)
  14649. strtk_register_sink_type_tag(unsigned char)
  14650. strtk_register_sink_type_tag(unsigned short)
  14651. strtk_register_sink_type_tag(unsigned int)
  14652. strtk_register_sink_type_tag(unsigned long)
  14653. strtk_register_sink_type_tag(unsigned long long int)
  14654. strtk_register_sink_type_tag(std::string)
  14655. strtk_register_stl_container_to_string_conv_type_tag(float)
  14656. strtk_register_stl_container_to_string_conv_type_tag(double)
  14657. strtk_register_stl_container_to_string_conv_type_tag(long double)
  14658. strtk_register_stl_container_to_string_conv_type_tag(signed char)
  14659. strtk_register_stl_container_to_string_conv_type_tag(char)
  14660. strtk_register_stl_container_to_string_conv_type_tag(short)
  14661. strtk_register_stl_container_to_string_conv_type_tag(int)
  14662. strtk_register_stl_container_to_string_conv_type_tag(long)
  14663. strtk_register_stl_container_to_string_conv_type_tag(long long)
  14664. strtk_register_stl_container_to_string_conv_type_tag(unsigned char)
  14665. strtk_register_stl_container_to_string_conv_type_tag(unsigned short)
  14666. strtk_register_stl_container_to_string_conv_type_tag(unsigned int)
  14667. strtk_register_stl_container_to_string_conv_type_tag(unsigned long)
  14668. strtk_register_stl_container_to_string_conv_type_tag(unsigned long long int)
  14669. strtk_register_stl_container_to_string_conv_type_tag(std::string)
  14670. strtk_register_inrange_type_tag(float)
  14671. strtk_register_inrange_type_tag(double)
  14672. strtk_register_inrange_type_tag(long double)
  14673. strtk_register_inrange_type_tag(signed char)
  14674. strtk_register_inrange_type_tag(char)
  14675. strtk_register_inrange_type_tag(short)
  14676. strtk_register_inrange_type_tag(int)
  14677. strtk_register_inrange_type_tag(long)
  14678. strtk_register_inrange_type_tag(long long)
  14679. strtk_register_inrange_type_tag(unsigned char)
  14680. strtk_register_inrange_type_tag(unsigned short)
  14681. strtk_register_inrange_type_tag(unsigned int)
  14682. strtk_register_inrange_type_tag(unsigned long)
  14683. strtk_register_inrange_type_tag(unsigned long long int)
  14684. strtk_register_inrange_type_tag(std::string)
  14685. strtk_register_trim_type_tag(float)
  14686. strtk_register_trim_type_tag(double)
  14687. strtk_register_trim_type_tag(long double)
  14688. strtk_register_trim_type_tag(signed char)
  14689. strtk_register_trim_type_tag(char)
  14690. strtk_register_trim_type_tag(short)
  14691. strtk_register_trim_type_tag(int)
  14692. strtk_register_trim_type_tag(long)
  14693. strtk_register_trim_type_tag(long long)
  14694. strtk_register_trim_type_tag(unsigned char)
  14695. strtk_register_trim_type_tag(unsigned short)
  14696. strtk_register_trim_type_tag(unsigned int)
  14697. strtk_register_trim_type_tag(unsigned long)
  14698. strtk_register_trim_type_tag(unsigned long long int)
  14699. strtk_register_trim_type_tag(std::string)
  14700. strtk_register_trim_type_tag(truncated_int<short>)
  14701. strtk_register_trim_type_tag(truncated_int<int>)
  14702. strtk_register_trim_type_tag(truncated_int<long>)
  14703. strtk_register_trim_type_tag(truncated_int<long long>)
  14704. strtk_register_trim_type_tag(truncated_int<unsigned char>)
  14705. strtk_register_trim_type_tag(truncated_int<unsigned short>)
  14706. strtk_register_trim_type_tag(truncated_int<unsigned int>)
  14707. strtk_register_trim_type_tag(truncated_int<unsigned long long int>)
  14708. strtk_register_truncint_type_tag(short)
  14709. strtk_register_truncint_type_tag(int)
  14710. strtk_register_truncint_type_tag(long)
  14711. strtk_register_truncint_type_tag(long long)
  14712. strtk_register_truncint_type_tag(unsigned short)
  14713. strtk_register_truncint_type_tag(unsigned int)
  14714. strtk_register_truncint_type_tag(unsigned long)
  14715. strtk_register_truncint_type_tag(unsigned long long int)
  14716. strtk_register_decsink_type_tag(float)
  14717. strtk_register_decsink_type_tag(double)
  14718. strtk_register_decsink_type_tag(long double)
  14719. #define strtk_register_userdef_type_sink(T) \
  14720. namespace strtk { namespace details { strtk_register_sink_type_tag(T) }}
  14721. #undef strtk_register_unsigned_type_tag
  14722. #undef strtk_register_signed_type_tag
  14723. #undef strtk_register_real_type_tag
  14724. #undef strtk_register_byte_type_tag
  14725. #undef strtk_register_hex_number_type_tag
  14726. #undef strtk_register_base64_type_tag
  14727. #undef strtk_register_supported_iterator_type
  14728. #undef strtk_register_stdstring_range_type_tag
  14729. #undef strtk_register_sequence_iterator_type
  14730. #undef strtk_register_stl_container_to_string_conv_type_tag
  14731. #undef strtk_register_inrange_type_tag
  14732. #undef strtk_register_trim_type_tag
  14733. #undef strtk_register_truncint_type_tag
  14734. #undef strtk_register_decsink_type_tag
  14735. template <typename T>
  14736. struct precision
  14737. { static void set(std::iostream&) {} };
  14738. #define strtk_register_iostream_precision(T) \
  14739. template<> struct precision<T> { static void set(std::iostream& s, const std::streamsize& p = 10) { s.precision(p);} };
  14740. strtk_register_iostream_precision(float)
  14741. strtk_register_iostream_precision(double)
  14742. strtk_register_iostream_precision(long double)
  14743. #undef strtk_register_iostream_precision
  14744. template <typename Iterator, typename T, typename Tag>
  14745. inline bool string_to_type_converter_impl(Iterator& begin, const Iterator end, T& t, not_supported_type_tag)
  14746. {
  14747. #ifdef strtk_enable_lexical_cast
  14748. try
  14749. {
  14750. t = boost::lexical_cast<T>(std::string(begin,end));
  14751. }
  14752. catch (const boost::bad_lexical_cast&)
  14753. {
  14754. return false;
  14755. }
  14756. begin = end;
  14757. return true;
  14758. #else
  14759. try
  14760. {
  14761. std::stringstream ss(std::string(begin,end));
  14762. ss >> t;
  14763. }
  14764. catch (const std::exception&)
  14765. {
  14766. return false;
  14767. }
  14768. begin = end;
  14769. return true;
  14770. #endif
  14771. }
  14772. template <typename Iterator>
  14773. inline bool string_to_type_converter_impl(Iterator& begin, const Iterator end, strtk::util::value& v, value_type_tag)
  14774. {
  14775. return v(begin,end);
  14776. }
  14777. template <typename Iterator>
  14778. inline bool string_to_type_converter_impl(Iterator& begin, const Iterator end, std::string& t, stdstring_type_tag)
  14779. {
  14780. t.assign(begin,end);
  14781. begin = end;
  14782. return true;
  14783. }
  14784. template <typename Iterator, typename Expect>
  14785. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, Expect& t, expect_type_tag)
  14786. {
  14787. if (!t(itr,end))
  14788. return false;
  14789. itr = end;
  14790. return true;
  14791. }
  14792. template <typename Iterator, typename Like>
  14793. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, Like& t, like_type_tag)
  14794. {
  14795. if (!t(itr,end))
  14796. return false;
  14797. itr = end;
  14798. return true;
  14799. }
  14800. template <typename Iterator, typename InRange>
  14801. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, InRange& t, inrange_type_tag)
  14802. {
  14803. if (!t(itr,end))
  14804. return false;
  14805. itr = end;
  14806. return true;
  14807. }
  14808. template <typename Iterator, typename TrimToken>
  14809. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, TrimToken& t, trim_type_tag)
  14810. {
  14811. if (!t(itr,end))
  14812. return false;
  14813. itr = end;
  14814. return true;
  14815. }
  14816. template <typename Iterator, typename CaseToken>
  14817. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, CaseToken& t, lcase_type_tag)
  14818. {
  14819. if (!t(itr,end))
  14820. return false;
  14821. itr = end;
  14822. return true;
  14823. }
  14824. template <typename Iterator, typename CaseToken>
  14825. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, CaseToken& t, ucase_type_tag)
  14826. {
  14827. if (!t(itr,end))
  14828. return false;
  14829. itr = end;
  14830. return true;
  14831. }
  14832. template <typename Iterator, typename Array>
  14833. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, Array& t, fillchararray_type_tag)
  14834. {
  14835. if (!t(itr,end))
  14836. return false;
  14837. itr = end;
  14838. return true;
  14839. }
  14840. template <typename Iterator, typename TruncatedInt>
  14841. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, TruncatedInt& t, truncint_type_tag)
  14842. {
  14843. if (!t(itr,end))
  14844. return false;
  14845. itr = end;
  14846. return true;
  14847. }
  14848. #ifdef __builtin_expect
  14849. # define strtk_likely(x) __builtin_expect((x),1)
  14850. # define strtk_unlikely(x) __builtin_expect((x),0)
  14851. #else
  14852. # define strtk_likely(x) (x)
  14853. # define strtk_unlikely(x) (x)
  14854. #endif
  14855. template <typename Iterator, typename T>
  14856. inline bool string_to_type_converter_impl(Iterator& itr_external, const Iterator end, T& result, unsigned_type_tag)
  14857. {
  14858. Iterator itr = itr_external;
  14859. if (itr == end)
  14860. return false;
  14861. else if (('+' == *itr) && end == (++itr))
  14862. return false;
  14863. while ((end != itr) && ('0' == (*itr))) ++itr;
  14864. T t = 0;
  14865. unsigned int digit = 0;
  14866. std::size_t length;
  14867. if (strtk_unlikely((length = std::distance(itr,end)) > numeric<T>::bound_length))
  14868. return false;
  14869. switch (length)
  14870. {
  14871. case 19 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14872. case 18 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14873. case 17 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14874. case 16 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14875. case 15 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14876. case 14 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14877. case 13 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14878. case 12 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14879. case 11 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14880. case 10 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14881. case 9 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14882. case 8 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14883. case 7 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14884. case 6 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14885. case 5 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14886. case 4 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14887. case 3 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14888. case 2 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14889. case 1 : if (strtk_unlikely((digit = (*itr - '0'))>= 10)) return false;
  14890. }
  14891. if (length == numeric<T>::bound_length)
  14892. {
  14893. if (!(
  14894. (t < numeric<T>::m10) ||
  14895. (
  14896. (t == numeric<T>::m10) &&
  14897. (digit <= numeric<T>::ldpos)
  14898. )
  14899. )
  14900. )
  14901. return false;
  14902. }
  14903. result = t * 10 + static_cast<T>(digit);
  14904. itr_external = itr;
  14905. return true;
  14906. }
  14907. template <typename Iterator, typename T>
  14908. inline bool string_to_type_converter_impl(Iterator& itr_external, const Iterator end, T& result, signed_type_tag)
  14909. {
  14910. Iterator itr;
  14911. if ((itr = itr_external) == end)
  14912. return false;
  14913. T last_digit = (*itr == '-') ? numeric<T>::ldneg : numeric<T>::ldpos;
  14914. if ((numeric<T>::ldneg == last_digit) || (*itr == '+'))
  14915. {
  14916. if (end == ++itr)
  14917. return false;
  14918. }
  14919. while ((end != itr) && ('0' == (*itr))) ++itr;
  14920. T t = 0;
  14921. unsigned int digit = 0;
  14922. std::size_t length;
  14923. if (strtk_unlikely((length = std::distance(itr,end)) > numeric<T>::bound_length))
  14924. return false;
  14925. switch (length)
  14926. {
  14927. case 19 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14928. case 18 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14929. case 17 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14930. case 16 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14931. case 15 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14932. case 14 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14933. case 13 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14934. case 12 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14935. case 11 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14936. case 10 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14937. case 9 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14938. case 8 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14939. case 7 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14940. case 6 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14941. case 5 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14942. case 4 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14943. case 3 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14944. case 2 : if (strtk_likely((digit = (*itr++ - '0')) < 10)) t = t * 10 + static_cast<T>(digit); else return false;
  14945. case 1 : if (strtk_unlikely((digit = (*itr - '0'))>= 10)) return false;
  14946. }
  14947. if (length == numeric<T>::bound_length)
  14948. {
  14949. if (!(
  14950. (t < numeric<T>::m10) ||
  14951. (
  14952. (t == numeric<T>::m10) &&
  14953. (static_cast<T>(digit) <= last_digit)
  14954. )
  14955. )
  14956. )
  14957. return false;
  14958. }
  14959. t = t * 10 + static_cast<T>(digit);
  14960. result = (last_digit == numeric<T>::ldpos) ? t : -t;
  14961. itr_external = itr;
  14962. return true;
  14963. }
  14964. template <typename Iterator, typename T>
  14965. inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, T& result, signed_type_tag)
  14966. {
  14967. if (itr == end)
  14968. return false;
  14969. bool negative = ('-' == (*itr));
  14970. if (negative || ('+' == (*itr)))
  14971. {
  14972. if (end == ++itr)
  14973. return false;
  14974. }
  14975. while ((end != itr) && ('0' == (*itr))) ++itr;
  14976. bool return_result = true;
  14977. unsigned int digit = 0;
  14978. std::size_t length;
  14979. if ((length = std::distance(itr,end)) <= 4)
  14980. {
  14981. switch (length)
  14982. {
  14983. #ifdef strtk_use_lut
  14984. #define strtk_process_digit \
  14985. if (strtk_likely((digit = details::digit_table[(int)*itr++]) < 10)) result = result * 10 + (digit); else { return_result = false; break; }
  14986. #else
  14987. #define strtk_process_digit \
  14988. if (strtk_likely((digit = (*itr++ - '0')) < 10)) result = result * 10 + (digit); else { return_result = false; break; }
  14989. #endif
  14990. case 4 : strtk_process_digit
  14991. case 3 : strtk_process_digit
  14992. case 2 : strtk_process_digit
  14993. case 1 : if (strtk_unlikely((digit = (*itr - '0'))>= 10)) { digit = 0; return_result = false; }
  14994. #undef strtk_process_digit
  14995. }
  14996. }
  14997. else
  14998. return_result = false;
  14999. if (length && return_result)
  15000. {
  15001. result = result * 10 + static_cast<T>(digit);
  15002. ++itr;
  15003. }
  15004. result = negative ? -result : result;
  15005. return return_result;
  15006. }
  15007. template <typename Iterator, typename T>
  15008. inline bool parse_nan(Iterator& itr, const Iterator end, T& t)
  15009. {
  15010. typedef typename std::iterator_traits<Iterator>::value_type type;
  15011. static const std::size_t nan_length = 3;
  15012. if (std::distance(itr,end) != static_cast<int>(nan_length))
  15013. return false;
  15014. if (static_cast<type>('n') == (*itr))
  15015. {
  15016. if ((static_cast<type>('a') != *(itr + 1)) || (static_cast<type>('n') != *(itr + 2)))
  15017. {
  15018. return false;
  15019. }
  15020. }
  15021. else if ((static_cast<type>('A') != *(itr + 1)) || (static_cast<type>('N') != *(itr + 2)))
  15022. {
  15023. return false;
  15024. }
  15025. t = std::numeric_limits<T>::quiet_NaN();
  15026. return true;
  15027. }
  15028. template <typename Iterator, typename T>
  15029. inline bool parse_inf(Iterator& itr, const Iterator end, T& t, bool negative)
  15030. {
  15031. static const char inf_uc[] = "INFINITY";
  15032. static const char inf_lc[] = "infinity";
  15033. static const std::size_t inf_length = 8;
  15034. const std::size_t length = std::distance(itr,end);
  15035. if ((3 != length) && (inf_length != length))
  15036. return false;
  15037. const char* inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc;
  15038. while (end != itr)
  15039. {
  15040. if (*inf_itr == static_cast<char>(*itr))
  15041. {
  15042. ++itr;
  15043. ++inf_itr;
  15044. continue;
  15045. }
  15046. else
  15047. return false;
  15048. }
  15049. if (negative)
  15050. t = -std::numeric_limits<T>::infinity();
  15051. else
  15052. t = std::numeric_limits<T>::infinity();
  15053. return true;
  15054. }
  15055. template <typename Iterator, typename T>
  15056. inline bool string_to_type_converter_impl(Iterator& itr_external, const Iterator end, T& t, real_type_tag)
  15057. {
  15058. if (end == itr_external) return false;
  15059. Iterator itr = itr_external;
  15060. typedef typename real_type<T>::type real_t;
  15061. real_t d = real_t(0);
  15062. bool negative = ('-' == (*itr));
  15063. if (negative || '+' == (*itr))
  15064. {
  15065. if (end == ++itr)
  15066. return false;
  15067. }
  15068. bool instate = false;
  15069. #ifdef strtk_use_lut
  15070. #define parse_digit_1(d) \
  15071. if (strtk_likely((digit = details::digit_table[(int)*itr]) < 10)) { d = d * real_t(10) + digit; } else break; if (end == ++itr) break; \
  15072. #define parse_digit_2(d) \
  15073. if (strtk_likely((digit = details::digit_table[(int)*itr]) < 10)) { d = d * real_t(10) + digit; } else break; ++itr; \
  15074. #else
  15075. #define parse_digit_1(d) \
  15076. if (strtk_likely((digit = (*itr - '0')) < 10)) { d = d * real_t(10) + digit; } else break; if (end == ++itr) break; \
  15077. #define parse_digit_2(d) \
  15078. if (strtk_likely((digit = (*itr - '0')) < 10)) { d = d * real_t(10) + digit; } else break; ++itr; \
  15079. #endif
  15080. if (strtk_likely('.' != (*itr)))
  15081. {
  15082. const Iterator curr = itr;
  15083. while ((end != itr) && ('0' == (*itr))) ++itr;
  15084. unsigned int digit;
  15085. while (end != itr)
  15086. {
  15087. // Note: For 'physical' superscalar architectures it
  15088. // is advised that the following loop be: 4xPD1 and 1xPD2
  15089. #ifdef strtk_enable_superscalar
  15090. parse_digit_1(d)
  15091. parse_digit_1(d)
  15092. #endif
  15093. parse_digit_1(d)
  15094. parse_digit_1(d)
  15095. parse_digit_2(d)
  15096. }
  15097. if (curr != itr) instate = true;
  15098. }
  15099. int exponent = 0;
  15100. if (end != itr)
  15101. {
  15102. if ('.' == (*itr))
  15103. {
  15104. const Iterator curr = ++itr;
  15105. unsigned int digit;
  15106. real_t tmp_d = real_t(0);
  15107. while (end != itr)
  15108. {
  15109. #ifdef strtk_enable_superscalar
  15110. parse_digit_1(tmp_d)
  15111. parse_digit_1(tmp_d)
  15112. parse_digit_1(tmp_d)
  15113. #endif
  15114. parse_digit_1(tmp_d)
  15115. parse_digit_1(tmp_d)
  15116. parse_digit_2(tmp_d)
  15117. }
  15118. if (curr != itr)
  15119. {
  15120. instate = true;
  15121. d += pow10(tmp_d,-std::distance(curr,itr));
  15122. }
  15123. #undef parse_digit_1
  15124. #undef parse_digit_2
  15125. }
  15126. if (end != itr)
  15127. {
  15128. typename std::iterator_traits<Iterator>::value_type c = (*itr);
  15129. if (('e' == c) || ('E' == c))
  15130. {
  15131. int exp = 0;
  15132. if (!details::string_to_type_converter_impl_ref(++itr,end,exp,details::signed_type_tag()))
  15133. {
  15134. if (end == itr)
  15135. return false;
  15136. else
  15137. c = (*itr);
  15138. }
  15139. exponent += exp;
  15140. }
  15141. if (end != itr)
  15142. {
  15143. if (('f' == c) || ('F' == c) || ('l' == c) || ('L' == c))
  15144. ++itr;
  15145. else if ('#' == c)
  15146. {
  15147. if (end == ++itr)
  15148. return false;
  15149. else if (('I' <= (*itr)) && ((*itr) <= 'n'))
  15150. {
  15151. if (('i' == (*itr)) || ('I' == (*itr)))
  15152. {
  15153. return parse_inf(itr,end,t,negative);
  15154. }
  15155. else if (('n' == (*itr)) || ('N' == (*itr)))
  15156. {
  15157. return parse_nan(itr,end,t);
  15158. }
  15159. else
  15160. return false;
  15161. }
  15162. else
  15163. return false;
  15164. }
  15165. else if (('I' <= (*itr)) && ((*itr) <= 'n'))
  15166. {
  15167. if (('i' == (*itr)) || ('I' == (*itr)))
  15168. {
  15169. return parse_inf(itr,end,t,negative);
  15170. }
  15171. else if (('n' == (*itr)) || ('N' == (*itr)))
  15172. {
  15173. return parse_nan(itr,end,t);
  15174. }
  15175. else
  15176. return false;
  15177. }
  15178. else
  15179. return false;
  15180. }
  15181. }
  15182. }
  15183. if (strtk_unlikely((end != itr) || (!instate)))
  15184. return false;
  15185. else if (exponent)
  15186. d = pow10(d,exponent);
  15187. t = static_cast<T>((negative) ? -d : d);
  15188. return true;
  15189. }
  15190. #undef strtk_likely
  15191. #undef strtk_unlikely
  15192. template <typename Iterator, typename T>
  15193. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, T& t, byte_type_tag)
  15194. {
  15195. if (1 != std::distance(itr,end))
  15196. return false;
  15197. t = static_cast<T>(*itr);
  15198. itr = end;
  15199. return true;
  15200. }
  15201. template <typename Iterator>
  15202. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, bool& t, bool_type_tag)
  15203. {
  15204. if (1 != std::distance(itr,end))
  15205. return false;
  15206. t = (('0' == (*itr)) ? false : true);
  15207. itr = end;
  15208. return true;
  15209. }
  15210. template <typename Iterator, typename IgnoreTokenType>
  15211. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, IgnoreTokenType&, ignore_token_type_tag)
  15212. {
  15213. itr = end;
  15214. return true;
  15215. }
  15216. template <typename Iterator, typename HexSinkType>
  15217. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, HexSinkType& t, hex_number_type_tag)
  15218. {
  15219. t = std::pair<Iterator,Iterator>(itr,end);
  15220. if (!t.valid())
  15221. return false;
  15222. itr = end;
  15223. return true;
  15224. }
  15225. template <typename Iterator, typename HexSinkType>
  15226. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, HexSinkType& t, hex_string_type_tag)
  15227. {
  15228. t = std::pair<Iterator,Iterator>(itr,end);
  15229. if (!t.valid())
  15230. return false;
  15231. itr = end;
  15232. return true;
  15233. }
  15234. template <typename Iterator, typename Base64SinkType>
  15235. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, Base64SinkType& t, base64_type_tag)
  15236. {
  15237. t = std::pair<Iterator,Iterator>(itr,end);
  15238. if (!t.valid())
  15239. return false;
  15240. itr = end;
  15241. return true;
  15242. }
  15243. template <typename Iterator, typename SinkType>
  15244. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, SinkType& t, sink_type_tag)
  15245. {
  15246. if (!t.parse(itr,end))
  15247. return false;
  15248. itr = end;
  15249. return true;
  15250. }
  15251. template <typename T>
  15252. inline bool type_to_string_converter_impl(const T& t, std::string& s, not_supported_type_tag)
  15253. {
  15254. #ifdef strtk_enable_lexical_cast
  15255. try
  15256. {
  15257. s = boost::lexical_cast<std::string>(t);
  15258. }
  15259. catch (const boost::bad_lexical_cast&)
  15260. {
  15261. return false;
  15262. }
  15263. #else
  15264. try
  15265. {
  15266. std::stringstream ss;
  15267. precision<T>::set(ss);
  15268. ss << t;
  15269. s = ss.str();
  15270. }
  15271. catch (const std::exception&)
  15272. {
  15273. return false;
  15274. }
  15275. #endif
  15276. return true;
  15277. }
  15278. template <typename T>
  15279. inline bool type_to_string_converter_impl(T value, std::string& result, unsigned_type_tag)
  15280. {
  15281. static const std::size_t radix = 10;
  15282. static const std::size_t radix_sqr = radix * radix;
  15283. static const std::size_t radix_cube = radix * radix * radix;
  15284. static const std::size_t buffer_size = ((strtk::details::numeric<T>::size < 16) ? 16 : 32);
  15285. unsigned char buffer[buffer_size];
  15286. unsigned char* itr = buffer + buffer_size;
  15287. if (value)
  15288. {
  15289. while (value >= static_cast<T>(radix_sqr))
  15290. {
  15291. itr -= 3;
  15292. T temp_v = value / radix_cube;
  15293. memcpy(itr,&details::rev_3digit_lut[3 * (value - (temp_v * radix_cube))],3);
  15294. value = temp_v;
  15295. }
  15296. while (value >= static_cast<T>(radix))
  15297. {
  15298. itr -= 2;
  15299. T temp_v = value / radix_sqr;
  15300. memcpy(itr,&details::rev_2digit_lut[2 * (value - (temp_v * radix_sqr))],2);
  15301. value = temp_v;
  15302. }
  15303. if (value)
  15304. {
  15305. *(--itr) = static_cast<unsigned char>('0' + value);
  15306. }
  15307. }
  15308. else
  15309. *(--itr) = '0';
  15310. result.assign(reinterpret_cast<char*>(itr), (buffer + buffer_size) - itr);
  15311. return true;
  15312. }
  15313. template <typename T>
  15314. struct tsci_type {};
  15315. #define define_tsci_type(Type,ReType) \
  15316. template <> \
  15317. struct tsci_type<Type> \
  15318. { \
  15319. typedef ReType type; \
  15320. }; \
  15321. define_tsci_type(short ,unsigned short )
  15322. define_tsci_type(int ,unsigned int )
  15323. define_tsci_type(long ,unsigned long )
  15324. define_tsci_type(long long,unsigned long long)
  15325. #undef define_tsci_type
  15326. template <typename T>
  15327. inline bool type_to_string_converter_impl(T valuex, std::string& result, signed_type_tag)
  15328. {
  15329. static const std::size_t radix = 10;
  15330. static const std::size_t radix_sqr = radix * radix;
  15331. static const std::size_t radix_cube = radix * radix * radix;
  15332. static const std::size_t buffer_size = ((strtk::details::numeric<T>::size < 16) ? 16 : 32);
  15333. unsigned char buffer[buffer_size];
  15334. unsigned char* itr = buffer + buffer_size;
  15335. bool negative = (valuex < 0);
  15336. typedef typename tsci_type<T>::type TT;
  15337. TT value = (negative) ? -valuex : valuex;
  15338. if (value)
  15339. {
  15340. while (value >= static_cast<T>(radix_sqr))
  15341. {
  15342. itr -= 3;
  15343. T temp_v = value / radix_cube;
  15344. memcpy(itr,&details::rev_3digit_lut[3 * (value - (temp_v * radix_cube))],3);
  15345. value = temp_v;
  15346. }
  15347. while (value >= static_cast<T>(radix))
  15348. {
  15349. itr -= 2;
  15350. T temp_v = value / radix_sqr;
  15351. memcpy(itr,&details::rev_2digit_lut[2 * (value - (temp_v * radix_sqr))],2);
  15352. value = temp_v;
  15353. }
  15354. if (value)
  15355. {
  15356. *(--itr) = static_cast<unsigned char>('0' + value);
  15357. }
  15358. if (negative)
  15359. {
  15360. *(--itr) = '-';
  15361. }
  15362. }
  15363. else
  15364. *(--itr) = '0';
  15365. result.assign(reinterpret_cast<char*>(itr), (buffer + buffer_size) - itr);
  15366. return true;
  15367. }
  15368. template <typename T>
  15369. inline bool type_to_string_converter_impl(const T& value, std::string& result, byte_type_tag)
  15370. {
  15371. result.resize(1);
  15372. result[0] = static_cast<char>(value);
  15373. return true;
  15374. }
  15375. inline bool type_to_string_converter_impl(const bool& value, std::string& result, bool_type_tag)
  15376. {
  15377. result.resize(1);
  15378. result[0] = value ? '1' : '0';
  15379. return true;
  15380. }
  15381. inline bool type_to_string_converter_impl(const std::string& value, std::string& result, stdstring_type_tag)
  15382. {
  15383. result = value;
  15384. return true;
  15385. }
  15386. template <typename Iterator>
  15387. inline bool type_to_string_converter_impl(const std::pair<Iterator,Iterator>& range, std::string& result, stdstring_range_type_tag)
  15388. {
  15389. result.assign(range.first,range.second);
  15390. return true;
  15391. }
  15392. template <typename SinkType>
  15393. inline bool type_to_string_converter_impl(const SinkType&, std::string&, sink_type_tag)
  15394. {
  15395. //Generic conversion not supported for sinks. Use joins or custom converters.
  15396. return false;
  15397. }
  15398. template <typename STLContainerType>
  15399. inline bool type_to_string_converter_impl(const STLContainerType&, std::string&, stl_seq_type_tag)
  15400. {
  15401. //Generic conversion not supported for stl containers. Use joins or custom converters.
  15402. return false;
  15403. }
  15404. template <typename T>
  15405. inline std::string type_name()
  15406. {
  15407. static const std::string s("Unknown");
  15408. return s;
  15409. }
  15410. #define strtk_register_type_name(Type) \
  15411. template <> inline std::string type_name<Type>() { static const std::string s(#Type); return s; }
  15412. strtk_register_type_name(signed char)
  15413. strtk_register_type_name(unsigned char)
  15414. strtk_register_type_name(short)
  15415. strtk_register_type_name(int)
  15416. strtk_register_type_name(long)
  15417. strtk_register_type_name(long long)
  15418. strtk_register_type_name(unsigned short)
  15419. strtk_register_type_name(unsigned int)
  15420. strtk_register_type_name(unsigned long)
  15421. strtk_register_type_name(unsigned long long int)
  15422. strtk_register_type_name(double)
  15423. strtk_register_type_name(float)
  15424. strtk_register_type_name(long double)
  15425. strtk_register_type_name(std::string)
  15426. #undef strtk_register_type_name
  15427. template <typename T>
  15428. inline std::string type_name(const T&)
  15429. {
  15430. static const std::string s = type_name<T>();
  15431. return s;
  15432. }
  15433. template <typename T1, typename T2>
  15434. inline std::string type_name(const std::pair<T1,T2>& p)
  15435. {
  15436. static const std::string s = std::string("std::pair<" +
  15437. type_name(p.first) +
  15438. "," +
  15439. type_name(p.second) +
  15440. ">");
  15441. return s;
  15442. }
  15443. template <typename T>
  15444. inline std::size_t type_length()
  15445. {
  15446. return numeric<T>::length;
  15447. }
  15448. template <typename T>
  15449. inline std::size_t type_length(const T&)
  15450. {
  15451. return type_length<T>();
  15452. }
  15453. inline std::size_t type_length(const std::string& s)
  15454. {
  15455. return s.size();
  15456. }
  15457. template <typename T1, typename T2>
  15458. inline std::size_t type_length(const std::pair<T1,T2>&)
  15459. {
  15460. return type_length<T1>() + type_length<T2>();
  15461. }
  15462. } // namespace details
  15463. template <typename T>
  15464. inline std::string type_name(const T& t)
  15465. {
  15466. static const std::string s = details::type_name<T>(t);
  15467. return s;
  15468. }
  15469. template <typename T, std::size_t N>
  15470. inline std::string type_name(const T(&)[N])
  15471. {
  15472. static const std::string s = details::type_name<T>() +
  15473. std::string("[") + type_to_string(N) + std::string("]");
  15474. return s;
  15475. }
  15476. template <typename T1, typename T2>
  15477. inline std::string type_name(const std::pair<T1,T2>& p)
  15478. {
  15479. static const std::string s = std::string("std::pair<" +
  15480. type_name(p.first) +
  15481. "," +
  15482. type_name(p.second) +
  15483. ">");
  15484. return s;
  15485. }
  15486. #define strtk_register_sequence_type_name(Type) \
  15487. template <typename T, typename Allocator> \
  15488. inline std::string type_name(const Type<T,Allocator>&) \
  15489. { \
  15490. static const std::string s = std::string(#Type) + std::string("<" + details::type_name<T>() + ">");\
  15491. return s; \
  15492. } \
  15493. #define strtk_register_set_type_name(Type) \
  15494. template <typename T, typename Comparator, typename Allocator> \
  15495. inline std::string type_name(const Type<T,Comparator,Allocator>&) \
  15496. { \
  15497. static const std::string s = std::string(#Type) + std::string("<" + details::type_name<T>() + ">");\
  15498. return s; \
  15499. } \
  15500. strtk_register_sequence_type_name(std::vector)
  15501. strtk_register_sequence_type_name(std::deque)
  15502. strtk_register_sequence_type_name(std::list)
  15503. strtk_register_set_type_name(std::set)
  15504. strtk_register_set_type_name(std::multiset)
  15505. template <typename T>
  15506. inline std::size_t type_length()
  15507. {
  15508. return details::type_length<T>();
  15509. }
  15510. template <typename T>
  15511. inline std::size_t type_length(const T&)
  15512. {
  15513. return type_length<T>();
  15514. }
  15515. class ext_string
  15516. {
  15517. public:
  15518. explicit ext_string()
  15519. {}
  15520. explicit ext_string(const std::string& s)
  15521. : s_(s)
  15522. {}
  15523. explicit ext_string(const char* s)
  15524. : s_(s)
  15525. {}
  15526. explicit ext_string(const range::adapter<char>& r)
  15527. : s_(r.begin(),r.end())
  15528. {}
  15529. ext_string(const ext_string& es)
  15530. : s_(es.s_)
  15531. {}
  15532. template <typename T>
  15533. inline ext_string& operator << (const T& t)
  15534. {
  15535. s_ += type_to_string(t);
  15536. return (*this);
  15537. }
  15538. inline operator std::string () const
  15539. {
  15540. return s_;
  15541. }
  15542. inline std::string clone() const
  15543. {
  15544. return s_;
  15545. }
  15546. inline const std::string& as_string() const
  15547. {
  15548. return s_;
  15549. }
  15550. inline std::string& as_string()
  15551. {
  15552. return s_;
  15553. }
  15554. template <typename T>
  15555. inline T as_type() const
  15556. {
  15557. return string_to_type_converter<T>(s_);
  15558. }
  15559. template <typename T>
  15560. inline bool as_type(T& t) const
  15561. {
  15562. return string_to_type_converter(s_,t);
  15563. }
  15564. inline bool imatch(const std::string& s) const
  15565. {
  15566. return strtk::imatch(s_,s);
  15567. }
  15568. inline bool imatch(const ext_string& es) const
  15569. {
  15570. return strtk::imatch(s_,es.s_);
  15571. }
  15572. inline ext_string& to_lowercase()
  15573. {
  15574. convert_to_lowercase(s_);
  15575. return (*this);
  15576. }
  15577. inline ext_string& to_uppercase()
  15578. {
  15579. convert_to_uppercase(s_);
  15580. return (*this);
  15581. }
  15582. template <typename Predicate>
  15583. inline ext_string& remove_leading(const Predicate& p)
  15584. {
  15585. if (s_.empty()) return (*this);
  15586. strtk::remove_leading(p,s_);
  15587. return (*this);
  15588. }
  15589. inline ext_string& remove_leading(const std::string& removal_set)
  15590. {
  15591. if (removal_set.empty())
  15592. return (*this);
  15593. else if (1 == removal_set.size())
  15594. strtk::remove_leading(single_delimiter_predicate<std::string::value_type>(removal_set[0]),s_);
  15595. else
  15596. strtk::remove_leading(multiple_char_delimiter_predicate(removal_set),s_);
  15597. return (*this);
  15598. }
  15599. template <typename Predicate>
  15600. inline ext_string& remove_trailing(const Predicate& p)
  15601. {
  15602. if (s_.empty()) return (*this);
  15603. strtk::remove_trailing(p,s_);
  15604. return (*this);
  15605. }
  15606. inline ext_string& remove_trailing(const std::string& removal_set)
  15607. {
  15608. if (removal_set.empty())
  15609. return (*this);
  15610. else if (1 == removal_set.size())
  15611. strtk::remove_trailing(single_delimiter_predicate<std::string::value_type>(removal_set[0]),s_);
  15612. else
  15613. strtk::remove_trailing(multiple_char_delimiter_predicate(removal_set),s_);
  15614. return (*this);
  15615. }
  15616. template <typename T>
  15617. inline ext_string& operator += (const T& t)
  15618. {
  15619. s_.append(type_to_string(t));
  15620. return (*this);
  15621. }
  15622. inline ext_string& operator -= (const std::string& pattern)
  15623. {
  15624. replace(pattern,"");
  15625. return (*this);
  15626. }
  15627. inline ext_string& operator *= (const std::size_t& n)
  15628. {
  15629. strtk::replicate_inplace(n,s_);
  15630. return (*this);
  15631. }
  15632. inline void replace(const std::string& pattern, const std::string& replace_pattern)
  15633. {
  15634. std::string result;
  15635. result.reserve(s_.size());
  15636. strtk::replace_pattern(s_,pattern,replace_pattern,result);
  15637. s_.assign(result);
  15638. }
  15639. template <typename DelimiterPredicate, typename OutputIterator>
  15640. inline std::size_t split(const DelimiterPredicate& p,
  15641. OutputIterator out,
  15642. const split_options::type split_option = split_options::default_mode) const
  15643. {
  15644. return strtk::split(p,s_,out,split_option);
  15645. }
  15646. template <typename DelimiterPredicate,
  15647. typename Allocator,
  15648. template <typename,typename> class Sequence>
  15649. inline std::size_t split(const DelimiterPredicate& p,
  15650. Sequence<std::string,Allocator>& seq,
  15651. const split_options::type split_option = split_options::default_mode) const
  15652. {
  15653. return strtk::split(p,s_,range_to_type_back_inserter(seq),split_option);
  15654. }
  15655. template <typename DelimiterPredicate, typename OutputIterator>
  15656. inline std::size_t split_n(const DelimiterPredicate& p,
  15657. const std::size_t& n,
  15658. OutputIterator out,
  15659. const split_options::type split_option = split_options::default_mode) const
  15660. {
  15661. return strtk::split_n(p,s_,n,out,split_option);
  15662. }
  15663. template <typename DelimiterPredicate,
  15664. typename Allocator,
  15665. template <typename,typename> class Sequence>
  15666. inline std::size_t split_n(const DelimiterPredicate& p,
  15667. const std::size_t& n,
  15668. Sequence<std::string,Allocator>& seq,
  15669. const split_options::type split_option = split_options::default_mode) const
  15670. {
  15671. return strtk::split_n(p,s_,n,range_to_type_back_inserter(seq),split_option);
  15672. }
  15673. template <typename T,
  15674. typename Allocator,
  15675. template <typename,typename> class Sequence>
  15676. inline std::size_t parse(const std::string& delimiters, Sequence<T,Allocator>& seq) const
  15677. {
  15678. return strtk::parse(s_,delimiters,seq);
  15679. }
  15680. template <typename T,
  15681. typename Allocator,
  15682. template <typename,typename> class Sequence>
  15683. inline std::size_t parse(const char* delimiters, Sequence<T,Allocator>& seq) const
  15684. {
  15685. return parse(std::string(delimiters),seq);
  15686. }
  15687. friend inline ext_string operator * (const std::size_t& n, const ext_string& s);
  15688. friend inline ext_string operator * (const ext_string& s, const std::size_t& n);
  15689. template <typename T>
  15690. friend inline ext_string operator + (const ext_string& s, const T& t);
  15691. template <typename T>
  15692. friend inline ext_string operator + (const T& t, const ext_string& s);
  15693. friend inline ext_string operator - (const ext_string& s, const std::string& pattern);
  15694. friend inline ext_string operator - (const ext_string& s, const char* pattern);
  15695. friend inline ext_string operator - (const ext_string& s, const ext_string& pattern);
  15696. static inline ext_string all_digits()
  15697. {
  15698. static const ext_string digits("0123456789");
  15699. return digits;
  15700. }
  15701. static inline ext_string all_letters()
  15702. {
  15703. static const ext_string letters("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
  15704. return letters;
  15705. }
  15706. static inline ext_string all_lowercase_letters()
  15707. {
  15708. static const ext_string letters("abcdefghijklmnopqrstuvwxyz");
  15709. return letters;
  15710. }
  15711. static inline ext_string all_uppercase_letters()
  15712. {
  15713. static const ext_string letters("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  15714. return letters;
  15715. }
  15716. static inline ext_string all_chars()
  15717. {
  15718. ext_string s;
  15719. s.as_string().resize(256);
  15720. strtk::iota(s.as_string().begin(),
  15721. s.as_string().end(),
  15722. static_cast<std::string::value_type>(0x00));
  15723. return s;
  15724. }
  15725. private:
  15726. std::string s_;
  15727. };
  15728. inline ext_string operator * (const std::size_t& n, const ext_string& s)
  15729. {
  15730. return ext_string(replicate(n, s.s_));
  15731. }
  15732. inline ext_string operator * (const ext_string& s, const std::size_t& n)
  15733. {
  15734. return ext_string(replicate(n, s.s_));
  15735. }
  15736. template <typename T>
  15737. inline ext_string operator + (const ext_string& s, const T& t)
  15738. {
  15739. return ext_string(s.s_ + type_to_string(t));
  15740. }
  15741. template <typename T>
  15742. inline ext_string operator + (const T& t, const ext_string& s)
  15743. {
  15744. return ext_string(type_to_string(t) + s.s_);
  15745. }
  15746. inline ext_string operator - (const ext_string& s, const std::string& pattern)
  15747. {
  15748. std::string tmp;
  15749. tmp.reserve(s.s_.size());
  15750. remove_pattern(s,pattern,tmp);
  15751. return ext_string(tmp);
  15752. }
  15753. inline ext_string operator - (const ext_string& s, const char* pattern)
  15754. {
  15755. return s - std::string(pattern);
  15756. }
  15757. inline ext_string operator - (const ext_string& s, const ext_string& pattern)
  15758. {
  15759. return s - std::string(pattern.as_string());
  15760. }
  15761. static inline std::ostream& operator<<(std::ostream& os, const ext_string& es)
  15762. {
  15763. return (os << es.as_string());
  15764. }
  15765. namespace fileio
  15766. {
  15767. inline bool file_exists(const std::string& file_name)
  15768. {
  15769. std::ifstream file(file_name.c_str(), std::ios::binary);
  15770. return ((!file) ? false : true);
  15771. }
  15772. inline std::size_t file_size(const std::string& file_name)
  15773. {
  15774. std::ifstream file(file_name.c_str(),std::ios::binary);
  15775. if (!file) return 0;
  15776. file.seekg (0, std::ios::end);
  15777. return static_cast<std::size_t>(file.tellg());
  15778. }
  15779. inline bool load_file(const std::string& file_name, char* buffer, std::size_t buffer_size)
  15780. {
  15781. std::ifstream in_stream(file_name.c_str(),std::ios::binary);
  15782. if (!in_stream) return false;
  15783. in_stream.read(buffer,static_cast<std::streamsize>(buffer_size));
  15784. in_stream.close();
  15785. return true;
  15786. }
  15787. inline bool load_file(const std::string& file_name, std::string& buffer)
  15788. {
  15789. buffer.resize(file_size(file_name));
  15790. return load_file(file_name,const_cast<char*>(buffer.data()),buffer.size());
  15791. }
  15792. inline bool write_file(const std::string& file_name, char* buffer, const std::size_t& buffer_size)
  15793. {
  15794. std::ofstream out_stream(file_name.c_str(),std::ios::binary);
  15795. if (!out_stream) return false;
  15796. out_stream.write(buffer,static_cast<std::streamsize>(buffer_size));
  15797. out_stream.close();
  15798. return true;
  15799. }
  15800. inline bool write_file(const std::string& file_name, const std::string& buffer)
  15801. {
  15802. return write_file(file_name,const_cast<char*>(buffer.data()),buffer.size());
  15803. }
  15804. inline bool copy_file(const std::string& src_file_name, const std::string& dest_file_name)
  15805. {
  15806. std::ifstream src_file(src_file_name.c_str(),std::ios::binary);
  15807. std::ofstream dest_file(dest_file_name.c_str(),std::ios::binary);
  15808. if (!src_file) return false;
  15809. if (!dest_file) return false;
  15810. static const std::size_t block_size = 16 * one_kilobyte;
  15811. char buffer[block_size];
  15812. std::size_t remaining_bytes = file_size(src_file_name);
  15813. while (remaining_bytes >= block_size)
  15814. {
  15815. src_file.read(&buffer[0],static_cast<std::streamsize>(block_size));
  15816. dest_file.write(&buffer[0],static_cast<std::streamsize>(block_size));
  15817. remaining_bytes -= block_size;
  15818. }
  15819. if (remaining_bytes > 0)
  15820. {
  15821. src_file.read(&buffer[0],static_cast<std::streamsize>(remaining_bytes));
  15822. dest_file.write(&buffer[0],static_cast<std::streamsize>(remaining_bytes));
  15823. remaining_bytes = 0;
  15824. }
  15825. src_file.close();
  15826. dest_file.close();
  15827. return true;
  15828. }
  15829. inline bool concatenate(const std::string& file_name1,
  15830. const std::string& file_name2,
  15831. const std::string& output_file_name)
  15832. {
  15833. std::ifstream file1(file_name1.c_str(),std::ios::binary);
  15834. std::ifstream file2(file_name2.c_str(),std::ios::binary);
  15835. std::ofstream out_file(output_file_name.c_str(),std::ios::binary);
  15836. if (!file1 || !file2 || !out_file) return false;
  15837. static const std::size_t block_size = 16 * one_kilobyte;
  15838. char buffer[block_size];
  15839. unsigned int round = 0;
  15840. std::size_t remaining_bytes = 0;
  15841. while (round < 2)
  15842. {
  15843. std::ifstream& input_stream = ((0 == round) ? file1 : file2);
  15844. remaining_bytes = ((0 == round) ? file_size(file_name1) : file_size(file_name2));
  15845. while (remaining_bytes >= block_size)
  15846. {
  15847. input_stream.read(&buffer[0],static_cast<std::streamsize>(block_size));
  15848. out_file.write(&buffer[0],static_cast<std::streamsize>(block_size));
  15849. remaining_bytes -= block_size;
  15850. }
  15851. if (remaining_bytes > 0)
  15852. {
  15853. input_stream.read(&buffer[0],static_cast<std::streamsize>(remaining_bytes));
  15854. out_file.write(&buffer[0],static_cast<std::streamsize>(remaining_bytes));
  15855. remaining_bytes = 0;
  15856. }
  15857. input_stream.close();
  15858. ++round;
  15859. }
  15860. out_file.close();
  15861. return true;
  15862. }
  15863. inline bool files_identical(const std::string& file_name1, const std::string& file_name2)
  15864. {
  15865. std::ifstream file1(file_name1.c_str(),std::ios::binary);
  15866. std::ifstream file2(file_name2.c_str(),std::ios::binary);
  15867. if (!file1) return false;
  15868. if (!file2) return false;
  15869. if (file_size(file_name1) != file_size(file_name2)) return false;
  15870. static const std::size_t block_size = 16 * one_kilobyte;
  15871. char buffer1[block_size];
  15872. char buffer2[block_size];
  15873. std::size_t remaining_bytes = file_size(file_name1);
  15874. while (remaining_bytes >= block_size)
  15875. {
  15876. file1.read(&buffer1[0],static_cast<std::streamsize>(block_size));
  15877. file2.read(&buffer2[0],static_cast<std::streamsize>(block_size));
  15878. if (0 != std::memcmp(buffer1,buffer2,block_size))
  15879. return false;
  15880. remaining_bytes -= block_size;
  15881. }
  15882. if (remaining_bytes > 0)
  15883. {
  15884. file1.read(&buffer1[0],static_cast<std::streamsize>(remaining_bytes));
  15885. file2.read(&buffer2[0],static_cast<std::streamsize>(remaining_bytes));
  15886. if (0 != std::memcmp(buffer1,buffer2,remaining_bytes))
  15887. return false;
  15888. remaining_bytes = 0;
  15889. }
  15890. file1.close();
  15891. file2.close();
  15892. return true;
  15893. }
  15894. namespace details
  15895. {
  15896. template <typename T>
  15897. inline bool read_pod_proxy(std::ifstream& stream, T& t)
  15898. {
  15899. return (false == stream.read(reinterpret_cast<char*>(&t),
  15900. static_cast<std::streamsize>(sizeof(T))).fail());
  15901. }
  15902. template <typename T>
  15903. inline bool write_pod_proxy(std::ofstream& stream, const T& t)
  15904. {
  15905. return (false == stream.write(reinterpret_cast<char*>(&t),
  15906. static_cast<std::streamsize>(sizeof(T))).fail());
  15907. }
  15908. }
  15909. template <typename T1, typename T2, typename T3, typename T4,
  15910. typename T5, typename T6, typename T7, typename T8,
  15911. typename T9, typename T10>
  15912. inline bool read_pod(std::ifstream& stream,
  15913. T1& t1, T2& t2, T3& t3, T4& t4,
  15914. T5& t5, T6& t6, T7& t7, T8& t8,
  15915. T9& t9, T10& t10)
  15916. {
  15917. return details::read_pod_proxy(stream, t1) &&
  15918. details::read_pod_proxy(stream, t2) &&
  15919. details::read_pod_proxy(stream, t3) &&
  15920. details::read_pod_proxy(stream, t4) &&
  15921. details::read_pod_proxy(stream, t5) &&
  15922. details::read_pod_proxy(stream, t6) &&
  15923. details::read_pod_proxy(stream, t7) &&
  15924. details::read_pod_proxy(stream, t8) &&
  15925. details::read_pod_proxy(stream, t9) &&
  15926. details::read_pod_proxy(stream,t10);
  15927. }
  15928. template <typename T1, typename T2, typename T3, typename T4,
  15929. typename T5, typename T6, typename T7, typename T8,
  15930. typename T9>
  15931. inline bool read_pod(std::ifstream& stream,
  15932. T1& t1, T2& t2, T3& t3, T4& t4,
  15933. T5& t5, T6& t6, T7& t7, T8& t8,
  15934. T9& t9)
  15935. {
  15936. return details::read_pod_proxy(stream,t1) &&
  15937. details::read_pod_proxy(stream,t2) &&
  15938. details::read_pod_proxy(stream,t3) &&
  15939. details::read_pod_proxy(stream,t4) &&
  15940. details::read_pod_proxy(stream,t5) &&
  15941. details::read_pod_proxy(stream,t6) &&
  15942. details::read_pod_proxy(stream,t7) &&
  15943. details::read_pod_proxy(stream,t8) &&
  15944. details::read_pod_proxy(stream,t9);
  15945. }
  15946. template <typename T1, typename T2, typename T3, typename T4,
  15947. typename T5, typename T6, typename T7, typename T8>
  15948. inline bool read_pod(std::ifstream& stream,
  15949. T1& t1, T2& t2, T3& t3, T4& t4,
  15950. T5& t5, T6& t6, T7& t7, T8& t8)
  15951. {
  15952. return details::read_pod_proxy(stream,t1) &&
  15953. details::read_pod_proxy(stream,t2) &&
  15954. details::read_pod_proxy(stream,t3) &&
  15955. details::read_pod_proxy(stream,t4) &&
  15956. details::read_pod_proxy(stream,t5) &&
  15957. details::read_pod_proxy(stream,t6) &&
  15958. details::read_pod_proxy(stream,t7) &&
  15959. details::read_pod_proxy(stream,t8);
  15960. }
  15961. template <typename T1, typename T2, typename T3, typename T4,
  15962. typename T5, typename T6, typename T7>
  15963. inline bool read_pod(std::ifstream& stream,
  15964. T1& t1, T2& t2, T3& t3, T4& t4,
  15965. T5& t5, T6& t6, T7& t7)
  15966. {
  15967. return details::read_pod_proxy(stream,t1) &&
  15968. details::read_pod_proxy(stream,t2) &&
  15969. details::read_pod_proxy(stream,t3) &&
  15970. details::read_pod_proxy(stream,t4) &&
  15971. details::read_pod_proxy(stream,t5) &&
  15972. details::read_pod_proxy(stream,t6) &&
  15973. details::read_pod_proxy(stream,t7);
  15974. }
  15975. template <typename T1, typename T2, typename T3, typename T4,
  15976. typename T5, typename T6>
  15977. inline bool read_pod(std::ifstream& stream,
  15978. T1& t1, T2& t2, T3& t3, T4& t4,
  15979. T5& t5, T6& t6)
  15980. {
  15981. return details::read_pod_proxy(stream,t1) &&
  15982. details::read_pod_proxy(stream,t2) &&
  15983. details::read_pod_proxy(stream,t3) &&
  15984. details::read_pod_proxy(stream,t4) &&
  15985. details::read_pod_proxy(stream,t5) &&
  15986. details::read_pod_proxy(stream,t6);
  15987. }
  15988. template <typename T1, typename T2, typename T3, typename T4,
  15989. typename T5>
  15990. inline bool read_pod(std::ifstream& stream,
  15991. T1& t1, T2& t2, T3& t3, T4& t4,
  15992. T5& t5)
  15993. {
  15994. return details::read_pod_proxy(stream,t1) &&
  15995. details::read_pod_proxy(stream,t2) &&
  15996. details::read_pod_proxy(stream,t3) &&
  15997. details::read_pod_proxy(stream,t4) &&
  15998. details::read_pod_proxy(stream,t5);
  15999. }
  16000. template <typename T1, typename T2, typename T3, typename T4>
  16001. inline bool read_pod(std::ifstream& stream,
  16002. T1& t1, T2& t2, T3& t3, T4& t4)
  16003. {
  16004. return details::read_pod_proxy(stream,t1) &&
  16005. details::read_pod_proxy(stream,t2) &&
  16006. details::read_pod_proxy(stream,t3) &&
  16007. details::read_pod_proxy(stream,t4);
  16008. }
  16009. template <typename T1, typename T2, typename T3>
  16010. inline bool read_pod(std::ifstream& stream,
  16011. T1& t1, T2& t2, T3& t3)
  16012. {
  16013. return details::read_pod_proxy(stream,t1) &&
  16014. details::read_pod_proxy(stream,t2) &&
  16015. details::read_pod_proxy(stream,t3);
  16016. }
  16017. template <typename T1, typename T2>
  16018. inline bool read_pod(std::ifstream& stream,
  16019. T1& t1, T2& t2)
  16020. {
  16021. return details::read_pod_proxy(stream,t1) &&
  16022. details::read_pod_proxy(stream,t2);
  16023. }
  16024. template <typename T>
  16025. inline bool read_pod(std::ifstream& stream, T& t)
  16026. {
  16027. return details::read_pod_proxy(stream,t);
  16028. }
  16029. template <typename T, std::size_t N>
  16030. inline bool read_pod(std::ifstream& stream, T (&t)[N])
  16031. {
  16032. return (false != stream.read(reinterpret_cast<char*>(&t[0]),sizeof(T) * N).fail());
  16033. }
  16034. template <typename T,
  16035. typename Allocator,
  16036. template <typename,typename> class Sequence>
  16037. inline bool read_pod(std::ifstream& stream,
  16038. const std::size_t& count,
  16039. Sequence<T,Allocator>& sequence)
  16040. {
  16041. T t;
  16042. for (std::size_t i = 0; i < count; ++i)
  16043. {
  16044. if (details::read_pod_proxy(stream,t))
  16045. sequence.push_back(t);
  16046. else
  16047. return false;
  16048. }
  16049. return true;
  16050. }
  16051. template <typename T,
  16052. typename Comparator,
  16053. typename Allocator>
  16054. inline bool read_pod(std::ifstream& stream,
  16055. const std::size_t& count,
  16056. std::set<T,Comparator,Allocator>& set)
  16057. {
  16058. T t;
  16059. for (std::size_t i = 0; i < count; ++i)
  16060. {
  16061. if (details::read_pod_proxy(stream,t))
  16062. set.insert(t);
  16063. else
  16064. return false;
  16065. }
  16066. return true;
  16067. }
  16068. template <typename T,
  16069. typename Comparator,
  16070. typename Allocator>
  16071. inline bool read_pod(std::ifstream& stream,
  16072. const std::size_t& count,
  16073. std::multiset<T,Comparator,Allocator>& multiset)
  16074. {
  16075. T t;
  16076. for (std::size_t i = 0; i < count; ++i)
  16077. {
  16078. if (details::read_pod_proxy(stream,t))
  16079. multiset.insert(t);
  16080. else
  16081. return false;
  16082. }
  16083. return true;
  16084. }
  16085. template <typename T1, typename T2, typename T3, typename T4,
  16086. typename T5, typename T6, typename T7, typename T8,
  16087. typename T9, typename T10>
  16088. inline bool write_pod(std::ofstream& stream,
  16089. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16090. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  16091. const T9& t9, const T10& t10)
  16092. {
  16093. return details::write_pod_proxy(stream, t1) &&
  16094. details::write_pod_proxy(stream, t2) &&
  16095. details::write_pod_proxy(stream, t3) &&
  16096. details::write_pod_proxy(stream, t4) &&
  16097. details::write_pod_proxy(stream, t5) &&
  16098. details::write_pod_proxy(stream, t6) &&
  16099. details::write_pod_proxy(stream, t7) &&
  16100. details::write_pod_proxy(stream, t8) &&
  16101. details::write_pod_proxy(stream, t9) &&
  16102. details::write_pod_proxy(stream,t10);
  16103. }
  16104. template <typename T1, typename T2, typename T3, typename T4,
  16105. typename T5, typename T6, typename T7, typename T8,
  16106. typename T9>
  16107. inline bool write_pod(std::ofstream& stream,
  16108. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16109. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  16110. const T9& t9)
  16111. {
  16112. return details::write_pod_proxy(stream,t1) &&
  16113. details::write_pod_proxy(stream,t2) &&
  16114. details::write_pod_proxy(stream,t3) &&
  16115. details::write_pod_proxy(stream,t4) &&
  16116. details::write_pod_proxy(stream,t5) &&
  16117. details::write_pod_proxy(stream,t6) &&
  16118. details::write_pod_proxy(stream,t7) &&
  16119. details::write_pod_proxy(stream,t8) &&
  16120. details::write_pod_proxy(stream,t9);
  16121. }
  16122. template <typename T1, typename T2, typename T3, typename T4,
  16123. typename T5, typename T6, typename T7, typename T8>
  16124. inline bool write_pod(std::ofstream& stream,
  16125. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16126. const T5& t5, const T6& t6, const T7& t7, const T8& t8)
  16127. {
  16128. return details::write_pod_proxy(stream,t1) &&
  16129. details::write_pod_proxy(stream,t2) &&
  16130. details::write_pod_proxy(stream,t3) &&
  16131. details::write_pod_proxy(stream,t4) &&
  16132. details::write_pod_proxy(stream,t5) &&
  16133. details::write_pod_proxy(stream,t6) &&
  16134. details::write_pod_proxy(stream,t7) &&
  16135. details::write_pod_proxy(stream,t8);
  16136. }
  16137. template <typename T1, typename T2, typename T3, typename T4,
  16138. typename T5, typename T6, typename T7>
  16139. inline bool write_pod(std::ofstream& stream,
  16140. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16141. const T5& t5, const T6& t6, const T7& t7)
  16142. {
  16143. return details::write_pod_proxy(stream,t1) &&
  16144. details::write_pod_proxy(stream,t2) &&
  16145. details::write_pod_proxy(stream,t3) &&
  16146. details::write_pod_proxy(stream,t4) &&
  16147. details::write_pod_proxy(stream,t5) &&
  16148. details::write_pod_proxy(stream,t6) &&
  16149. details::write_pod_proxy(stream,t7);
  16150. }
  16151. template <typename T1, typename T2, typename T3, typename T4,
  16152. typename T5, typename T6>
  16153. inline bool write_pod(std::ofstream& stream,
  16154. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16155. const T5& t5, const T6& t6)
  16156. {
  16157. return details::write_pod_proxy(stream,t1) &&
  16158. details::write_pod_proxy(stream,t2) &&
  16159. details::write_pod_proxy(stream,t3) &&
  16160. details::write_pod_proxy(stream,t4) &&
  16161. details::write_pod_proxy(stream,t5) &&
  16162. details::write_pod_proxy(stream,t6);
  16163. }
  16164. template <typename T1, typename T2, typename T3, typename T4,
  16165. typename T5>
  16166. inline bool write_pod(std::ofstream& stream,
  16167. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16168. const T5& t5)
  16169. {
  16170. return details::write_pod_proxy(stream,t1) &&
  16171. details::write_pod_proxy(stream,t2) &&
  16172. details::write_pod_proxy(stream,t3) &&
  16173. details::write_pod_proxy(stream,t4) &&
  16174. details::write_pod_proxy(stream,t5);
  16175. }
  16176. template <typename T1, typename T2, typename T3, typename T4>
  16177. inline bool write_pod(std::ofstream& stream,
  16178. const T1& t1, const T2& t2, const T3& t3, const T4& t4)
  16179. {
  16180. return details::write_pod_proxy(stream,t1) &&
  16181. details::write_pod_proxy(stream,t2) &&
  16182. details::write_pod_proxy(stream,t3) &&
  16183. details::write_pod_proxy(stream,t4);
  16184. }
  16185. template <typename T1, typename T2, typename T3>
  16186. inline bool write_pod(std::ofstream& stream,
  16187. const T1& t1, const T2& t2, const T3& t3)
  16188. {
  16189. return details::write_pod_proxy(stream,t1) &&
  16190. details::write_pod_proxy(stream,t2) &&
  16191. details::write_pod_proxy(stream,t3);
  16192. }
  16193. template <typename T1, typename T2>
  16194. inline bool write_pod(std::ofstream& stream,
  16195. const T1& t1, const T2& t2)
  16196. {
  16197. return details::write_pod_proxy(stream,t1) &&
  16198. details::write_pod_proxy(stream,t2);
  16199. }
  16200. template <typename T>
  16201. inline bool write_pod(std::ofstream& stream, const T& t)
  16202. {
  16203. return details::write_pod_proxy(stream,t);
  16204. }
  16205. template <typename T, std::size_t N>
  16206. inline bool write_pod(std::ofstream& stream, T (&t)[N])
  16207. {
  16208. return (false != stream.write(reinterpret_cast<char*>(&t[0]),sizeof(T) * N).fail());
  16209. }
  16210. template <typename T,
  16211. typename Allocator,
  16212. template <typename,typename> class Sequence>
  16213. inline bool write_pod(std::ofstream& stream,
  16214. const Sequence<T,Allocator>& sequence)
  16215. {
  16216. typename Sequence<T,Allocator>::iterator itr = sequence.begin();
  16217. typename Sequence<T,Allocator>::iterator end = sequence.end();
  16218. while (end != itr)
  16219. {
  16220. if (details::write_pod_proxy(stream,*itr))
  16221. ++itr;
  16222. else
  16223. return false;
  16224. }
  16225. }
  16226. template <typename T,
  16227. typename Comparator,
  16228. typename Allocator>
  16229. inline bool write_pod(std::ofstream& stream,
  16230. const std::set<T,Comparator,Allocator>& set)
  16231. {
  16232. typename std::set<T,Comparator,Allocator>::iterator itr = set.begin();
  16233. typename std::set<T,Comparator,Allocator>::iterator end = set.end();
  16234. while (end != itr)
  16235. {
  16236. if (details::write_pod_proxy(stream,*itr))
  16237. ++itr;
  16238. else
  16239. return false;
  16240. }
  16241. }
  16242. template <typename T,
  16243. typename Comparator,
  16244. typename Allocator>
  16245. inline bool write_pod(std::ofstream& stream,
  16246. const std::multiset<T,Comparator,Allocator>& multiset)
  16247. {
  16248. typename std::multiset<T,Comparator,Allocator>::iterator itr = multiset.begin();
  16249. typename std::multiset<T,Comparator,Allocator>::iterator end = multiset.end();
  16250. while (end != itr)
  16251. {
  16252. if (details::write_pod_proxy(stream,*itr))
  16253. ++itr;
  16254. else
  16255. return false;
  16256. }
  16257. }
  16258. inline bool read_at_offset(std::ifstream& stream,
  16259. const std::size_t& offset,
  16260. char* buffer,
  16261. const std::size_t& buffer_size)
  16262. {
  16263. if (!stream) return false;
  16264. stream.seekg(static_cast<std::ifstream::off_type>(offset),std::ios_base::beg);
  16265. if (stream.fail()) return false;
  16266. stream.read(buffer,static_cast<std::streamsize>(buffer_size));
  16267. if (stream.fail()) return false;
  16268. stream.close();
  16269. return true;
  16270. }
  16271. inline bool read_at_offset(const std::string& file_name,
  16272. const std::size_t& offset,
  16273. char* buffer,
  16274. const std::size_t& buffer_size)
  16275. {
  16276. std::ifstream stream(file_name.c_str(), std::ios::in | std::ios::binary);
  16277. if (!stream) return false;
  16278. return read_at_offset(stream,offset,buffer,buffer_size);
  16279. }
  16280. inline bool read_at_offset(const std::string& file_name,
  16281. const std::size_t& offset,
  16282. std::string& buffer,
  16283. const std::size_t& buffer_size)
  16284. {
  16285. std::ifstream stream(file_name.c_str(), std::ios::in | std::ios::binary);
  16286. if (!stream) return false;
  16287. buffer.resize(buffer_size);
  16288. return read_at_offset(stream,
  16289. offset,
  16290. const_cast<char*>(buffer.data()),
  16291. buffer_size);
  16292. }
  16293. } // namespace fileio
  16294. template <typename T1, typename T2, typename T3, typename T4,
  16295. typename T5, typename T6, typename T7, typename T8,
  16296. typename T9, typename T10, typename T11, typename T12>
  16297. inline unsigned char* read_pod(unsigned char* data,
  16298. T1& t1, T2& t2, T3& t3, T4& t4,
  16299. T5& t5, T6& t6, T7& t7, T8& t8,
  16300. T9& t9, T10& t10, T11& t11, T12& t12)
  16301. {
  16302. t1 = (*reinterpret_cast< T1*>(data)); data += sizeof( T1);
  16303. t2 = (*reinterpret_cast< T2*>(data)); data += sizeof( T2);
  16304. t3 = (*reinterpret_cast< T3*>(data)); data += sizeof( T3);
  16305. t4 = (*reinterpret_cast< T4*>(data)); data += sizeof( T4);
  16306. t5 = (*reinterpret_cast< T5*>(data)); data += sizeof( T5);
  16307. t6 = (*reinterpret_cast< T6*>(data)); data += sizeof( T6);
  16308. t7 = (*reinterpret_cast< T7*>(data)); data += sizeof( T7);
  16309. t8 = (*reinterpret_cast< T8*>(data)); data += sizeof( T8);
  16310. t9 = (*reinterpret_cast< T9*>(data)); data += sizeof( T9);
  16311. t10 = (*reinterpret_cast<T10*>(data)); data += sizeof(T10);
  16312. t11 = (*reinterpret_cast<T11*>(data)); data += sizeof(T11);
  16313. t12 = (*reinterpret_cast<T12*>(data)); data += sizeof(T12);
  16314. return data;
  16315. }
  16316. template <typename T1, typename T2, typename T3, typename T4,
  16317. typename T5, typename T6, typename T7, typename T8,
  16318. typename T9, typename T10, typename T11>
  16319. inline unsigned char* read_pod(unsigned char* data,
  16320. T1& t1, T2& t2, T3& t3, T4& t4,
  16321. T5& t5, T6& t6, T7& t7, T8& t8,
  16322. T9& t9, T10& t10, T11& t11)
  16323. {
  16324. t1 = (*reinterpret_cast< T1*>(data)); data += sizeof( T1);
  16325. t2 = (*reinterpret_cast< T2*>(data)); data += sizeof( T2);
  16326. t3 = (*reinterpret_cast< T3*>(data)); data += sizeof( T3);
  16327. t4 = (*reinterpret_cast< T4*>(data)); data += sizeof( T4);
  16328. t5 = (*reinterpret_cast< T5*>(data)); data += sizeof( T5);
  16329. t6 = (*reinterpret_cast< T6*>(data)); data += sizeof( T6);
  16330. t7 = (*reinterpret_cast< T7*>(data)); data += sizeof( T7);
  16331. t8 = (*reinterpret_cast< T8*>(data)); data += sizeof( T8);
  16332. t9 = (*reinterpret_cast< T9*>(data)); data += sizeof( T9);
  16333. t10 = (*reinterpret_cast<T10*>(data)); data += sizeof(T10);
  16334. t11 = (*reinterpret_cast<T11*>(data)); data += sizeof(T11);
  16335. return data;
  16336. }
  16337. template <typename T1, typename T2, typename T3, typename T4,
  16338. typename T5, typename T6, typename T7, typename T8,
  16339. typename T9, typename T10>
  16340. inline unsigned char* read_pod(unsigned char* data,
  16341. T1& t1, T2& t2, T3& t3, T4& t4,
  16342. T5& t5, T6& t6, T7& t7, T8& t8,
  16343. T9& t9, T10& t10)
  16344. {
  16345. t1 = (*reinterpret_cast< T1*>(data)); data += sizeof( T1);
  16346. t2 = (*reinterpret_cast< T2*>(data)); data += sizeof( T2);
  16347. t3 = (*reinterpret_cast< T3*>(data)); data += sizeof( T3);
  16348. t4 = (*reinterpret_cast< T4*>(data)); data += sizeof( T4);
  16349. t5 = (*reinterpret_cast< T5*>(data)); data += sizeof( T5);
  16350. t6 = (*reinterpret_cast< T6*>(data)); data += sizeof( T6);
  16351. t7 = (*reinterpret_cast< T7*>(data)); data += sizeof( T7);
  16352. t8 = (*reinterpret_cast< T8*>(data)); data += sizeof( T8);
  16353. t9 = (*reinterpret_cast< T9*>(data)); data += sizeof( T9);
  16354. t10 = (*reinterpret_cast<T10*>(data)); data += sizeof(T10);
  16355. return data;
  16356. }
  16357. template <typename T1, typename T2, typename T3, typename T4,
  16358. typename T5, typename T6, typename T7, typename T8,
  16359. typename T9>
  16360. inline unsigned char* read_pod(unsigned char* data,
  16361. T1& t1, T2& t2, T3& t3, T4& t4,
  16362. T5& t5, T6& t6, T7& t7, T8& t8,
  16363. T9& t9)
  16364. {
  16365. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16366. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16367. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16368. t4 = (*reinterpret_cast<T4*>(data)); data += sizeof(T4);
  16369. t5 = (*reinterpret_cast<T5*>(data)); data += sizeof(T5);
  16370. t6 = (*reinterpret_cast<T6*>(data)); data += sizeof(T6);
  16371. t7 = (*reinterpret_cast<T7*>(data)); data += sizeof(T7);
  16372. t8 = (*reinterpret_cast<T8*>(data)); data += sizeof(T8);
  16373. t9 = (*reinterpret_cast<T9*>(data)); data += sizeof(T9);
  16374. return data;
  16375. }
  16376. template <typename T1, typename T2, typename T3, typename T4,
  16377. typename T5, typename T6, typename T7, typename T8>
  16378. inline unsigned char* read_pod(unsigned char* data,
  16379. T1& t1, T2& t2, T3& t3, T4& t4,
  16380. T5& t5, T6& t6, T7& t7, T8& t8)
  16381. {
  16382. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16383. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16384. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16385. t4 = (*reinterpret_cast<T4*>(data)); data += sizeof(T4);
  16386. t5 = (*reinterpret_cast<T5*>(data)); data += sizeof(T5);
  16387. t6 = (*reinterpret_cast<T6*>(data)); data += sizeof(T6);
  16388. t7 = (*reinterpret_cast<T7*>(data)); data += sizeof(T7);
  16389. t8 = (*reinterpret_cast<T8*>(data)); data += sizeof(T8);
  16390. return data;
  16391. }
  16392. template <typename T1, typename T2, typename T3, typename T4,
  16393. typename T5, typename T6, typename T7>
  16394. inline unsigned char* read_pod(unsigned char* data,
  16395. T1& t1, T2& t2, T3& t3, T4& t4,
  16396. T5& t5, T6& t6, T7& t7)
  16397. {
  16398. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16399. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16400. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16401. t4 = (*reinterpret_cast<T4*>(data)); data += sizeof(T4);
  16402. t5 = (*reinterpret_cast<T5*>(data)); data += sizeof(T5);
  16403. t6 = (*reinterpret_cast<T6*>(data)); data += sizeof(T6);
  16404. t7 = (*reinterpret_cast<T7*>(data)); data += sizeof(T7);
  16405. return data;
  16406. }
  16407. template <typename T1, typename T2, typename T3, typename T4,
  16408. typename T5, typename T6>
  16409. inline unsigned char* read_pod(unsigned char* data,
  16410. T1& t1, T2& t2, T3& t3, T4& t4,
  16411. T5& t5, T6& t6)
  16412. {
  16413. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16414. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16415. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16416. t4 = (*reinterpret_cast<T4*>(data)); data += sizeof(T4);
  16417. t5 = (*reinterpret_cast<T5*>(data)); data += sizeof(T5);
  16418. t6 = (*reinterpret_cast<T6*>(data)); data += sizeof(T6);
  16419. return data;
  16420. }
  16421. template <typename T1, typename T2, typename T3, typename T4,
  16422. typename T5>
  16423. inline unsigned char* read_pod(unsigned char* data,
  16424. T1& t1, T2& t2, T3& t3, T4& t4,
  16425. T5& t5)
  16426. {
  16427. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16428. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16429. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16430. t4 = (*reinterpret_cast<T4*>(data)); data += sizeof(T4);
  16431. t5 = (*reinterpret_cast<T5*>(data)); data += sizeof(T5);
  16432. return data;
  16433. }
  16434. template <typename T1, typename T2, typename T3, typename T4>
  16435. inline unsigned char* read_pod(unsigned char* data,
  16436. T1& t1, T2& t2, T3& t3, T4& t4)
  16437. {
  16438. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16439. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16440. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16441. t4 = (*reinterpret_cast<T4*>(data)); data += sizeof(T4);
  16442. return data;
  16443. }
  16444. template <typename T1, typename T2, typename T3>
  16445. inline unsigned char* read_pod(unsigned char* data,
  16446. T1& t1, T2& t2, T3& t3)
  16447. {
  16448. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16449. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16450. t3 = (*reinterpret_cast<T3*>(data)); data += sizeof(T3);
  16451. return data;
  16452. }
  16453. template <typename T1, typename T2>
  16454. inline unsigned char* read_pod(unsigned char* data,
  16455. T1& t1, T2& t2)
  16456. {
  16457. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16458. t2 = (*reinterpret_cast<T2*>(data)); data += sizeof(T2);
  16459. return data;
  16460. }
  16461. template <typename T1>
  16462. inline unsigned char* read_pod(unsigned char* data,
  16463. T1& t1)
  16464. {
  16465. t1 = (*reinterpret_cast<T1*>(data)); data += sizeof(T1);
  16466. return data;
  16467. }
  16468. template <typename T, std::size_t N>
  16469. inline unsigned char* read_pod(unsigned char* data, T (&t)[N])
  16470. {
  16471. T* begin = reinterpret_cast<T*>(data);
  16472. T* end = begin + N;
  16473. std::copy(begin,end,&t[0]);
  16474. return data + (N * sizeof(T));
  16475. }
  16476. template <typename T,
  16477. typename Allocator,
  16478. template <typename,typename> class Sequence>
  16479. inline unsigned char* read_pod(unsigned char* data,
  16480. const std::size_t& n,
  16481. const Sequence<T,Allocator>& sequence)
  16482. {
  16483. T* ptr = reinterpret_cast<T>(data);
  16484. std::copy(ptr, ptr + n, std::back_inserter(sequence));
  16485. return data + (sequence.size() * sizeof(T));
  16486. }
  16487. template <typename T,
  16488. typename Comparator,
  16489. typename Allocator>
  16490. inline unsigned char* read_pod(unsigned char* data,
  16491. const std::size_t& n,
  16492. const std::set<T,Comparator,Allocator>& set)
  16493. {
  16494. T* ptr = reinterpret_cast<T>(data);
  16495. std::copy(ptr, ptr + n, std::inserter(set,set.begin()));
  16496. return data + (set.size() * sizeof(T));
  16497. }
  16498. template <typename T,
  16499. typename Comparator,
  16500. typename Allocator>
  16501. inline unsigned char* read_pod(unsigned char* data,
  16502. const std::size_t& n,
  16503. const std::multiset<T,Comparator,Allocator>& multiset)
  16504. {
  16505. T* ptr = reinterpret_cast<T>(data);
  16506. std::copy(ptr, ptr + n, std::inserter(multiset,multiset.begin()));
  16507. return data + (multiset.size() * sizeof(T));
  16508. }
  16509. template <typename T1, typename T2, typename T3, typename T4,
  16510. typename T5, typename T6, typename T7, typename T8,
  16511. typename T9, typename T10, typename T11, typename T12>
  16512. inline unsigned char* write_pod(unsigned char* data,
  16513. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16514. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  16515. const T9& t9, const T10& t10, const T11& t11, const T12& t12)
  16516. {
  16517. (*reinterpret_cast< T1*>(data)) = t1; data += sizeof( T1);
  16518. (*reinterpret_cast< T2*>(data)) = t2; data += sizeof( T2);
  16519. (*reinterpret_cast< T3*>(data)) = t3; data += sizeof( T3);
  16520. (*reinterpret_cast< T4*>(data)) = t4; data += sizeof( T4);
  16521. (*reinterpret_cast< T5*>(data)) = t5; data += sizeof( T5);
  16522. (*reinterpret_cast< T6*>(data)) = t6; data += sizeof( T6);
  16523. (*reinterpret_cast< T7*>(data)) = t7; data += sizeof( T7);
  16524. (*reinterpret_cast< T8*>(data)) = t8; data += sizeof( T8);
  16525. (*reinterpret_cast< T9*>(data)) = t9; data += sizeof( T9);
  16526. (*reinterpret_cast<T10*>(data)) = t10; data += sizeof(T10);
  16527. (*reinterpret_cast<T11*>(data)) = t11; data += sizeof(T11);
  16528. (*reinterpret_cast<T12*>(data)) = t12; data += sizeof(T12);
  16529. return data;
  16530. }
  16531. template <typename T1, typename T2, typename T3, typename T4,
  16532. typename T5, typename T6, typename T7, typename T8,
  16533. typename T9, typename T10, typename T11>
  16534. inline unsigned char* write_pod(unsigned char* data,
  16535. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16536. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  16537. const T9& t9, const T10& t10, const T11& t11)
  16538. {
  16539. (*reinterpret_cast< T1*>(data)) = t1; data += sizeof( T1);
  16540. (*reinterpret_cast< T2*>(data)) = t2; data += sizeof( T2);
  16541. (*reinterpret_cast< T3*>(data)) = t3; data += sizeof( T3);
  16542. (*reinterpret_cast< T4*>(data)) = t4; data += sizeof( T4);
  16543. (*reinterpret_cast< T5*>(data)) = t5; data += sizeof( T5);
  16544. (*reinterpret_cast< T6*>(data)) = t6; data += sizeof( T6);
  16545. (*reinterpret_cast< T7*>(data)) = t7; data += sizeof( T7);
  16546. (*reinterpret_cast< T8*>(data)) = t8; data += sizeof( T8);
  16547. (*reinterpret_cast< T9*>(data)) = t9; data += sizeof( T9);
  16548. (*reinterpret_cast<T10*>(data)) = t10; data += sizeof(T10);
  16549. (*reinterpret_cast<T11*>(data)) = t11; data += sizeof(T11);
  16550. return data;
  16551. }
  16552. template <typename T1, typename T2, typename T3, typename T4,
  16553. typename T5, typename T6, typename T7, typename T8,
  16554. typename T9, typename T10>
  16555. inline unsigned char* write_pod(unsigned char* data,
  16556. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16557. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  16558. const T9& t9, const T10& t10)
  16559. {
  16560. (*reinterpret_cast< T1*>(data)) = t1; data += sizeof( T1);
  16561. (*reinterpret_cast< T2*>(data)) = t2; data += sizeof( T2);
  16562. (*reinterpret_cast< T3*>(data)) = t3; data += sizeof( T3);
  16563. (*reinterpret_cast< T4*>(data)) = t4; data += sizeof( T4);
  16564. (*reinterpret_cast< T5*>(data)) = t5; data += sizeof( T5);
  16565. (*reinterpret_cast< T6*>(data)) = t6; data += sizeof( T6);
  16566. (*reinterpret_cast< T7*>(data)) = t7; data += sizeof( T7);
  16567. (*reinterpret_cast< T8*>(data)) = t8; data += sizeof( T8);
  16568. (*reinterpret_cast< T9*>(data)) = t9; data += sizeof( T9);
  16569. (*reinterpret_cast<T10*>(data)) = t10; data += sizeof(T10);
  16570. return data;
  16571. }
  16572. template <typename T1, typename T2, typename T3, typename T4,
  16573. typename T5, typename T6, typename T7, typename T8,
  16574. typename T9>
  16575. inline unsigned char* write_pod(unsigned char* data,
  16576. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16577. const T5& t5, const T6& t6, const T7& t7, const T8& t8,
  16578. const T9& t9)
  16579. {
  16580. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16581. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16582. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16583. (*reinterpret_cast<T4*>(data)) = t4; data += sizeof(T4);
  16584. (*reinterpret_cast<T5*>(data)) = t5; data += sizeof(T5);
  16585. (*reinterpret_cast<T6*>(data)) = t6; data += sizeof(T6);
  16586. (*reinterpret_cast<T7*>(data)) = t7; data += sizeof(T7);
  16587. (*reinterpret_cast<T8*>(data)) = t8; data += sizeof(T8);
  16588. (*reinterpret_cast<T9*>(data)) = t9; data += sizeof(T9);
  16589. return data;
  16590. }
  16591. template <typename T1, typename T2, typename T3, typename T4,
  16592. typename T5, typename T6, typename T7, typename T8>
  16593. inline unsigned char* write_pod(unsigned char* data,
  16594. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16595. const T5& t5, const T6& t6, const T7& t7, const T8& t8)
  16596. {
  16597. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16598. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16599. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16600. (*reinterpret_cast<T4*>(data)) = t4; data += sizeof(T4);
  16601. (*reinterpret_cast<T5*>(data)) = t5; data += sizeof(T5);
  16602. (*reinterpret_cast<T6*>(data)) = t6; data += sizeof(T6);
  16603. (*reinterpret_cast<T7*>(data)) = t7; data += sizeof(T7);
  16604. (*reinterpret_cast<T8*>(data)) = t8; data += sizeof(T8);
  16605. return data;
  16606. }
  16607. template <typename T1, typename T2, typename T3, typename T4,
  16608. typename T5, typename T6, typename T7>
  16609. inline unsigned char* write_pod(unsigned char* data,
  16610. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16611. const T5& t5, const T6& t6, const T7& t7)
  16612. {
  16613. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16614. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16615. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16616. (*reinterpret_cast<T4*>(data)) = t4; data += sizeof(T4);
  16617. (*reinterpret_cast<T5*>(data)) = t5; data += sizeof(T5);
  16618. (*reinterpret_cast<T6*>(data)) = t6; data += sizeof(T6);
  16619. (*reinterpret_cast<T7*>(data)) = t7; data += sizeof(T7);
  16620. return data;
  16621. }
  16622. template <typename T1, typename T2, typename T3, typename T4,
  16623. typename T5, typename T6>
  16624. inline unsigned char* write_pod(unsigned char* data,
  16625. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16626. const T5& t5, const T6& t6)
  16627. {
  16628. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16629. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16630. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16631. (*reinterpret_cast<T4*>(data)) = t4; data += sizeof(T4);
  16632. (*reinterpret_cast<T5*>(data)) = t5; data += sizeof(T5);
  16633. (*reinterpret_cast<T6*>(data)) = t6; data += sizeof(T6);
  16634. return data;
  16635. }
  16636. template <typename T1, typename T2, typename T3, typename T4,
  16637. typename T5>
  16638. inline unsigned char* write_pod(unsigned char* data,
  16639. const T1& t1, const T2& t2, const T3& t3, const T4& t4,
  16640. const T5& t5)
  16641. {
  16642. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16643. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16644. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16645. (*reinterpret_cast<T4*>(data)) = t4; data += sizeof(T4);
  16646. (*reinterpret_cast<T5*>(data)) = t5; data += sizeof(T5);
  16647. return data;
  16648. }
  16649. template <typename T1, typename T2, typename T3, typename T4>
  16650. inline unsigned char* write_pod(unsigned char* data,
  16651. const T1& t1, const T2& t2, const T3& t3, const T4& t4)
  16652. {
  16653. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16654. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16655. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16656. (*reinterpret_cast<T4*>(data)) = t4; data += sizeof(T4);
  16657. return data;
  16658. }
  16659. template <typename T1, typename T2, typename T3>
  16660. inline unsigned char* write_pod(unsigned char* data,
  16661. const T1& t1, const T2& t2, const T3& t3)
  16662. {
  16663. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16664. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16665. (*reinterpret_cast<T3*>(data)) = t3; data += sizeof(T3);
  16666. return data;
  16667. }
  16668. template <typename T1, typename T2>
  16669. inline unsigned char* write_pod(unsigned char* data,
  16670. const T1& t1, const T2& t2)
  16671. {
  16672. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16673. (*reinterpret_cast<T2*>(data)) = t2; data += sizeof(T2);
  16674. return data;
  16675. }
  16676. template <typename T1>
  16677. inline unsigned char* write_pod(unsigned char* data,
  16678. const T1& t1)
  16679. {
  16680. (*reinterpret_cast<T1*>(data)) = t1; data += sizeof(T1);
  16681. return data;
  16682. }
  16683. template <typename T, std::size_t N>
  16684. inline unsigned char* write_pod(unsigned char* data, const T (&t)[N])
  16685. {
  16686. T* ptr = reinterpret_cast<T*>(data);
  16687. std::copy(t,t + N,ptr);
  16688. return data + (N * sizeof(T));
  16689. }
  16690. template <typename T,
  16691. typename Allocator,
  16692. template <typename,typename> class Sequence>
  16693. inline unsigned char* write_pod(unsigned char* data,
  16694. const Sequence<T,Allocator>& sequence)
  16695. {
  16696. T* ptr = reinterpret_cast<T>(data);
  16697. std::copy(sequence.begin(),sequence.end(),ptr);
  16698. return data + (sequence.size() * sizeof(T));
  16699. }
  16700. template <typename T,
  16701. typename Comparator,
  16702. typename Allocator>
  16703. inline unsigned char* write_pod(unsigned char* data,
  16704. const std::set<T,Comparator,Allocator>& set)
  16705. {
  16706. T* ptr = reinterpret_cast<T>(data);
  16707. std::copy(set.begin(),set.end(),ptr);
  16708. return data + (set.size() * sizeof(T));
  16709. }
  16710. template <typename T,
  16711. typename Comparator,
  16712. typename Allocator>
  16713. inline unsigned char* write_pod(unsigned char* data,
  16714. const std::multiset<T,Comparator,Allocator>& multiset)
  16715. {
  16716. T* ptr = reinterpret_cast<T>(data);
  16717. std::copy(multiset.begin(),multiset.end(),ptr);
  16718. return data + (multiset.size() * sizeof(T));
  16719. }
  16720. class string_condition
  16721. {
  16722. private:
  16723. typedef const unsigned char* itr_type;
  16724. inline bool condition_equal(const itr_type begin, const itr_type end) const
  16725. {
  16726. if (s.size() == static_cast<std::size_t>(std::distance(begin,end)))
  16727. {
  16728. return std::equal(s_begin,s_end,begin);
  16729. }
  16730. else
  16731. return false;
  16732. }
  16733. inline bool condition_notequal(const itr_type begin, const itr_type end) const
  16734. {
  16735. if (s.size() == static_cast<std::size_t>(std::distance(begin,end)))
  16736. {
  16737. return !std::equal(s_begin,s_end,begin);
  16738. }
  16739. else
  16740. return true;
  16741. }
  16742. inline bool condition_like(const itr_type begin, const itr_type end) const
  16743. {
  16744. return match(s_begin,s_end,begin,end,(unsigned char)'*',(unsigned char)'?');
  16745. }
  16746. inline bool condition_begins_with(const itr_type begin, const itr_type end) const
  16747. {
  16748. if (s.size() == static_cast<std::size_t>(std::distance(begin,end)))
  16749. {
  16750. return strtk::begins_with(s_begin,s_end,begin,end);
  16751. }
  16752. else
  16753. return false;
  16754. }
  16755. inline bool condition_ends_with(const itr_type begin, const itr_type end) const
  16756. {
  16757. if (s.size() == static_cast<std::size_t>(std::distance(begin,end)))
  16758. {
  16759. return strtk::ends_with(s_begin,s_end,begin,end);
  16760. }
  16761. else
  16762. return false;
  16763. }
  16764. inline bool condition_within(const itr_type begin, const itr_type end) const
  16765. {
  16766. if (s.size() <= static_cast<std::size_t>(std::distance(begin,end)))
  16767. {
  16768. return (end != std::search(begin,end,s_begin,s_end));
  16769. }
  16770. else
  16771. return false;
  16772. }
  16773. inline bool condition_notwithin(const itr_type begin, const itr_type end) const
  16774. {
  16775. if (s.size() <= static_cast<std::size_t>(std::distance(begin,end)))
  16776. {
  16777. return (end == std::search(begin,end,s_begin,s_end));
  16778. }
  16779. else
  16780. return true;
  16781. }
  16782. typedef bool (string_condition::*condition_method)(const itr_type begin, const itr_type end) const;
  16783. public:
  16784. enum condition_type
  16785. {
  16786. equal = 0,
  16787. notequal = 1,
  16788. like = 2,
  16789. begins_with = 4,
  16790. ends_with = 8,
  16791. within = 16,
  16792. notwithin = 32
  16793. };
  16794. inline explicit string_condition(condition_type cond_type, const std::string& str)
  16795. : cond_type_(cond_type),
  16796. s(str),
  16797. s_begin(reinterpret_cast<const unsigned char*>(s.data())),
  16798. s_end(reinterpret_cast<const unsigned char*>(s.data() + str.size())),
  16799. condition_method_(0)
  16800. {
  16801. switch (cond_type_)
  16802. {
  16803. case equal : condition_method_ = &string_condition::condition_equal;
  16804. break;
  16805. case notequal : condition_method_ = &string_condition::condition_notequal;
  16806. break;
  16807. case like : condition_method_ = &string_condition::condition_like;
  16808. break;
  16809. case begins_with : condition_method_ = &string_condition::condition_begins_with;
  16810. break;
  16811. case ends_with : condition_method_ = &string_condition::condition_ends_with;
  16812. break;
  16813. case within : condition_method_ = &string_condition::condition_within;
  16814. break;
  16815. case notwithin : condition_method_ = &string_condition::condition_notwithin;
  16816. break;
  16817. }
  16818. }
  16819. template <typename Iterator>
  16820. inline bool operator()(const Iterator begin, const Iterator end)
  16821. {
  16822. return ((*this).*condition_method_)(begin,end);
  16823. }
  16824. inline bool operator()(const std::string& str)
  16825. {
  16826. return operator()(reinterpret_cast<const unsigned char*>(str.data()),
  16827. reinterpret_cast<const unsigned char*>(str.data() + str.size()));
  16828. }
  16829. private:
  16830. condition_type cond_type_;
  16831. std::string s;
  16832. const unsigned char* s_begin;
  16833. const unsigned char* s_end;
  16834. condition_method condition_method_;
  16835. };
  16836. namespace trie
  16837. {
  16838. template <typename KeyIterator, typename ValueType>
  16839. class prefix
  16840. {
  16841. template <typename Iterator,
  16842. typename Value,
  16843. typename KeyValue = typename std::iterator_traits<Iterator>::value_type>
  16844. struct node
  16845. {
  16846. public:
  16847. typedef KeyValue key_value_t;
  16848. typedef Value value_t;
  16849. typedef node<Iterator,Value,KeyValue> node_t;
  16850. typedef node_t* node_ptr;
  16851. typedef const node_ptr const_node_ptr;
  16852. typedef std::vector<node_ptr> node_list_t;
  16853. typedef typename node_list_t::const_iterator node_list_iterator;
  16854. explicit node(const key_value_t& key_value)
  16855. : key_value_(key_value),
  16856. value_holder_(false)
  16857. {}
  16858. node(const key_value_t& key_value, const value_t& v)
  16859. : key_value_(key_value),
  16860. value_holder_(true),
  16861. value_(v)
  16862. {}
  16863. ~node()
  16864. {
  16865. if (!node_list_.empty())
  16866. {
  16867. node_list_iterator itr = node_list_.begin();
  16868. node_list_iterator end = node_list_.end();
  16869. while (end != itr)
  16870. {
  16871. delete (*itr);
  16872. ++itr;
  16873. }
  16874. }
  16875. }
  16876. inline node_ptr get_node(const key_value_t& key_value)
  16877. {
  16878. if (node_list_.empty())
  16879. return 0;
  16880. node_list_iterator itr = node_list_.begin();
  16881. const node_list_iterator end = node_list_.end();
  16882. while (end != itr)
  16883. {
  16884. if (key_value == (*itr)->key_value_)
  16885. return (*itr);
  16886. else
  16887. ++itr;
  16888. }
  16889. return 0;
  16890. }
  16891. inline void assign_value(const value_t& v)
  16892. {
  16893. value_ = v;
  16894. value_holder_ = true;
  16895. }
  16896. inline void add_node(node_ptr n)
  16897. {
  16898. node_list_.push_back(n);
  16899. }
  16900. inline bool value_holder() const
  16901. {
  16902. return value_holder_;
  16903. }
  16904. inline const value_t& value() const
  16905. {
  16906. return value_;
  16907. }
  16908. inline const key_value_t& key() const
  16909. {
  16910. return key_value_;
  16911. }
  16912. private:
  16913. node(const node_t& n);
  16914. node_t& operator=(const node_t& n);
  16915. key_value_t key_value_;
  16916. bool value_holder_;
  16917. value_t value_;
  16918. node_list_t node_list_;
  16919. };
  16920. public:
  16921. //typedef KeyIterator key_iterator_t;
  16922. typedef typename std::iterator_traits<KeyIterator>::value_type key_value_t;
  16923. typedef ValueType value_t;
  16924. typedef node<KeyIterator,value_t> node_t;
  16925. typedef node_t* node_ptr;
  16926. prefix()
  16927. : head_(0)
  16928. {}
  16929. template <typename key_iterator_t>
  16930. inline void insert(const key_iterator_t begin,
  16931. const key_iterator_t end,
  16932. const value_t& v)
  16933. {
  16934. if (0 == std::distance(begin,end))
  16935. return;
  16936. key_iterator_t itr = begin;
  16937. key_value_t key = (*itr);
  16938. node_ptr parent = 0;
  16939. node_ptr next_node = 0;
  16940. node_ptr n = head_ = ((0 == head_) ? new node_t(*itr) : head_);
  16941. while (end != itr)
  16942. {
  16943. key = (*itr);
  16944. if (0 == (next_node = n->get_node(key)))
  16945. {
  16946. n->add_node(next_node = new node_t(key));
  16947. }
  16948. parent = n;
  16949. n = next_node;
  16950. ++itr;
  16951. }
  16952. parent->assign_value(v);
  16953. }
  16954. template <typename key_iterator_t>
  16955. inline bool find(const key_iterator_t begin,
  16956. const key_iterator_t end,
  16957. value_t& v) const
  16958. {
  16959. if ((0 == head_) || (0 == std::distance(begin,end)))
  16960. return false;
  16961. key_iterator_t itr = begin;
  16962. node_ptr parent = head_;
  16963. node_ptr n = head_;
  16964. while (end != itr)
  16965. {
  16966. node_ptr next_node = n->get_node(*itr);
  16967. if (0 == next_node)
  16968. return false;
  16969. parent = n;
  16970. n = next_node;
  16971. ++itr;
  16972. }
  16973. if (!parent->value_holder())
  16974. return false;
  16975. v = parent->value();
  16976. return true;
  16977. }
  16978. template <typename key_iterator_t>
  16979. inline bool find_prefix(const key_iterator_t begin, const key_iterator_t end) const
  16980. {
  16981. if ((0 == head_) || (0 == std::distance(begin,end)))
  16982. return false;
  16983. key_iterator_t itr = begin;
  16984. node_ptr n = head_;
  16985. while (end != itr)
  16986. {
  16987. if (0 == (n = n->get_node(*itr)))
  16988. return false;
  16989. ++itr;
  16990. }
  16991. return true;
  16992. }
  16993. ~prefix()
  16994. {
  16995. delete head_;
  16996. }
  16997. private:
  16998. node_ptr head_;
  16999. };
  17000. template <typename Value>
  17001. inline void insert(prefix<std::string::const_iterator,Value>& trie,
  17002. const std::string& key,
  17003. const Value& value = Value(0))
  17004. {
  17005. trie.insert(key.begin(),key.end(),value);
  17006. }
  17007. template <typename Value>
  17008. inline void insert(prefix<std::string::iterator,Value>& trie,
  17009. const char* key,
  17010. const Value& value = Value(0))
  17011. {
  17012. trie.insert(std::string(key),value);
  17013. }
  17014. template <typename Value>
  17015. inline bool find(prefix<std::string::const_iterator,Value>& trie,
  17016. const std::string& key,
  17017. Value& v)
  17018. {
  17019. return trie.find(key.begin(),key.end(),v);
  17020. }
  17021. template <typename Value>
  17022. inline bool find(prefix<std::string::const_iterator,Value>& trie,
  17023. const char* key,
  17024. Value& v)
  17025. {
  17026. return trie.find_prefix(trie,std::string(key),v);
  17027. }
  17028. template <typename Value>
  17029. inline bool find_prefix(prefix<std::string::const_iterator,Value>& trie,
  17030. const std::string& key)
  17031. {
  17032. return trie.find_prefix(key.begin(),key.end());
  17033. }
  17034. template <typename Value>
  17035. inline bool find_prefix(prefix<std::string::const_iterator,Value>& trie,
  17036. const char* key)
  17037. {
  17038. return trie.find_prefix(trie,std::string(key));
  17039. }
  17040. } // namespace trie
  17041. template <typename ValueType, typename KeyIterator = std::string::const_iterator>
  17042. struct prefix_trie
  17043. {
  17044. typedef trie::prefix<KeyIterator,ValueType> type;
  17045. typedef trie::prefix<KeyIterator,ValueType> std_string;
  17046. typedef trie::prefix<char*,ValueType> char_ptr;
  17047. typedef trie::prefix<const char*,ValueType> const_char_ptr;
  17048. typedef trie::prefix<unsigned char*,ValueType> uchar_ptr;
  17049. typedef trie::prefix<const unsigned char*,ValueType> const_uchar_ptr;
  17050. };
  17051. namespace bloom
  17052. {
  17053. static const std::size_t bits_per_char = 0x08; // 8 bits in 1 char(unsigned)
  17054. static const unsigned char bit_mask[bits_per_char] = {
  17055. 0x01, //00000001
  17056. 0x02, //00000010
  17057. 0x04, //00000100
  17058. 0x08, //00001000
  17059. 0x10, //00010000
  17060. 0x20, //00100000
  17061. 0x40, //01000000
  17062. 0x80 //10000000
  17063. };
  17064. class parameters
  17065. {
  17066. public:
  17067. parameters()
  17068. : minimum_size(1),
  17069. maximum_size(std::numeric_limits<unsigned long long int>::max()),
  17070. minimum_number_of_hashes(1),
  17071. maximum_number_of_hashes(std::numeric_limits<unsigned int>::max()),
  17072. projected_element_count(10000),
  17073. false_positive_probability(1.0 / projected_element_count),
  17074. random_seed(0xA5A5A5A55A5A5A5AULL)
  17075. {}
  17076. virtual ~parameters()
  17077. {}
  17078. inline bool operator!()
  17079. {
  17080. return (minimum_size > maximum_size) ||
  17081. (minimum_number_of_hashes > maximum_number_of_hashes) ||
  17082. (minimum_number_of_hashes < 1) ||
  17083. (0 == maximum_number_of_hashes) ||
  17084. (0 == projected_element_count) ||
  17085. (false_positive_probability < 0.0) ||
  17086. (std::numeric_limits<double>::infinity() == std::abs(false_positive_probability)) ||
  17087. (0 == random_seed) ||
  17088. (0xFFFFFFFFFFFFFFFFULL == random_seed);
  17089. }
  17090. //Allowed min/max size of the bloom filter in bits
  17091. unsigned long long int minimum_size;
  17092. unsigned long long int maximum_size;
  17093. //Allowed min/max number of hash functions
  17094. unsigned int minimum_number_of_hashes;
  17095. unsigned int maximum_number_of_hashes;
  17096. //The approximate number of elements to be inserted
  17097. //into the bloom filter, should be within one order
  17098. //of magnitude. The default is 10000.
  17099. unsigned long long int projected_element_count;
  17100. //The approximate false positive probability expected
  17101. //from the bloom filter. The default is the reciprocal
  17102. //of the projected_element_count.
  17103. double false_positive_probability;
  17104. unsigned long long int random_seed;
  17105. inline bool operator()(strtk::binary::reader& reader)
  17106. {
  17107. return reader(minimum_size) &&
  17108. reader(maximum_size) &&
  17109. reader(minimum_number_of_hashes) &&
  17110. reader(maximum_number_of_hashes) &&
  17111. reader(projected_element_count) &&
  17112. reader(false_positive_probability) &&
  17113. reader(random_seed);
  17114. }
  17115. inline bool operator()(strtk::binary::writer& writer)
  17116. {
  17117. return writer(minimum_size) &&
  17118. writer(maximum_size) &&
  17119. writer(minimum_number_of_hashes) &&
  17120. writer(maximum_number_of_hashes) &&
  17121. writer(projected_element_count) &&
  17122. writer(false_positive_probability) &&
  17123. writer(random_seed);
  17124. }
  17125. struct optimal_parameters_t
  17126. {
  17127. optimal_parameters_t()
  17128. : number_of_hashes(0),
  17129. table_size(0)
  17130. {}
  17131. unsigned int number_of_hashes;
  17132. unsigned long long int table_size;
  17133. };
  17134. optimal_parameters_t optimal_parameters;
  17135. virtual bool compute_optimal_parameters()
  17136. {
  17137. /*
  17138. Note:
  17139. The following will attempt to find the number of hash functions
  17140. and minimum amount of storage bits required to construct a bloom
  17141. filter consistent with the user defined false positive probability
  17142. and estimated element insertion count.
  17143. */
  17144. if (!(*this))
  17145. return false;
  17146. double min_m = std::numeric_limits<double>::infinity();
  17147. double min_k = 0.0;
  17148. double curr_m = 0.0;
  17149. double k = 1.0;
  17150. while (k < 1000.0)
  17151. {
  17152. double numerator = -k * projected_element_count;
  17153. double denominator = std::log(1.0 - std::pow(false_positive_probability, 1.0 / k));
  17154. curr_m = numerator / denominator;
  17155. if (curr_m < min_m)
  17156. {
  17157. min_m = curr_m;
  17158. min_k = k;
  17159. }
  17160. k += 1.0;
  17161. }
  17162. optimal_parameters_t& optp = optimal_parameters;
  17163. optp.number_of_hashes = static_cast<unsigned int>(min_k);
  17164. optp.table_size = static_cast<unsigned long long int>(min_m);
  17165. optp.table_size += (((optp.table_size % bits_per_char) != 0) ? (bits_per_char - (optp.table_size % bits_per_char)) : 0);
  17166. if (optp.number_of_hashes < minimum_number_of_hashes)
  17167. optp.number_of_hashes = minimum_number_of_hashes;
  17168. else if (optp.number_of_hashes > maximum_number_of_hashes)
  17169. optp.number_of_hashes = maximum_number_of_hashes;
  17170. if (optp.table_size < minimum_size)
  17171. optp.table_size = minimum_size;
  17172. else if (optp.table_size > maximum_size)
  17173. optp.table_size = maximum_size;
  17174. return true;
  17175. }
  17176. };
  17177. class filter
  17178. {
  17179. protected:
  17180. typedef unsigned int bloom_type;
  17181. typedef unsigned char cell_type;
  17182. public:
  17183. filter()
  17184. : bit_table_(0),
  17185. salt_count_(0),
  17186. table_size_(0),
  17187. raw_table_size_(0),
  17188. projected_element_count_(0),
  17189. inserted_element_count_(0),
  17190. random_seed_(0),
  17191. desired_false_positive_probability_(0.0)
  17192. {}
  17193. filter(const parameters& p)
  17194. : bit_table_(0),
  17195. projected_element_count_(p.projected_element_count),
  17196. inserted_element_count_(0),
  17197. random_seed_((p.random_seed * 0xA5A5A5A5) + 1),
  17198. desired_false_positive_probability_(p.false_positive_probability)
  17199. {
  17200. salt_count_ = p.optimal_parameters.number_of_hashes;
  17201. table_size_ = p.optimal_parameters.table_size;
  17202. generate_unique_salt();
  17203. raw_table_size_ = table_size_ / bits_per_char;
  17204. bit_table_ = new cell_type[static_cast<std::size_t>(raw_table_size_)];
  17205. std::fill_n(bit_table_,raw_table_size_,0x00);
  17206. }
  17207. filter(const filter& filter)
  17208. {
  17209. this->operator=(filter);
  17210. }
  17211. inline bool operator == (const filter& f) const
  17212. {
  17213. if (this != &f)
  17214. {
  17215. return
  17216. (salt_count_ == f.salt_count_) &&
  17217. (table_size_ == f.table_size_) &&
  17218. (raw_table_size_ == f.raw_table_size_) &&
  17219. (projected_element_count_ == f.projected_element_count_) &&
  17220. (inserted_element_count_ == f.inserted_element_count_) &&
  17221. (random_seed_ == f.random_seed_) &&
  17222. (desired_false_positive_probability_ == f.desired_false_positive_probability_) &&
  17223. (salt_ == f.salt_) &&
  17224. std::equal(f.bit_table_,f.bit_table_ + raw_table_size_,bit_table_);
  17225. }
  17226. else
  17227. return true;
  17228. }
  17229. inline bool operator != (const filter& f) const
  17230. {
  17231. return !operator==(f);
  17232. }
  17233. inline filter& operator = (const filter& f)
  17234. {
  17235. if (this != &f)
  17236. {
  17237. salt_count_ = f.salt_count_;
  17238. table_size_ = f.table_size_;
  17239. raw_table_size_ = f.raw_table_size_;
  17240. projected_element_count_ = f.projected_element_count_;
  17241. inserted_element_count_ = f.inserted_element_count_;
  17242. random_seed_ = f.random_seed_;
  17243. desired_false_positive_probability_ = f.desired_false_positive_probability_;
  17244. delete[] bit_table_;
  17245. bit_table_ = new cell_type[static_cast<std::size_t>(raw_table_size_)];
  17246. std::copy(f.bit_table_,f.bit_table_ + raw_table_size_,bit_table_);
  17247. salt_ = f.salt_;
  17248. }
  17249. return *this;
  17250. }
  17251. virtual ~filter()
  17252. {
  17253. delete[] bit_table_;
  17254. }
  17255. inline bool operator!() const
  17256. {
  17257. return (0 == table_size_);
  17258. }
  17259. inline void clear()
  17260. {
  17261. std::fill_n(bit_table_,raw_table_size_,0x00);
  17262. inserted_element_count_ = 0;
  17263. }
  17264. inline void insert(const unsigned char* key_begin, const std::size_t& length)
  17265. {
  17266. std::size_t bit_index = 0;
  17267. std::size_t bit = 0;
  17268. for (std::size_t i = 0; i < salt_.size(); ++i)
  17269. {
  17270. compute_indices(hash_ap(key_begin,length,salt_[i]),bit_index,bit);
  17271. bit_table_[bit_index / bits_per_char] |= bit_mask[bit];
  17272. }
  17273. ++inserted_element_count_;
  17274. }
  17275. template <typename T>
  17276. inline void insert(const T& t)
  17277. {
  17278. // Note: T must be a C++ POD type.
  17279. insert(reinterpret_cast<const unsigned char*>(&t),sizeof(T));
  17280. }
  17281. inline void insert(const std::string& key)
  17282. {
  17283. insert(reinterpret_cast<const unsigned char*>(key.data()),key.size());
  17284. }
  17285. inline void insert(const char* data, const std::size_t& length)
  17286. {
  17287. insert(reinterpret_cast<const unsigned char*>(data),length);
  17288. }
  17289. template <typename InputIterator>
  17290. inline void insert(const InputIterator begin, const InputIterator end)
  17291. {
  17292. InputIterator itr = begin;
  17293. while (end != itr)
  17294. {
  17295. insert(*(itr++));
  17296. }
  17297. }
  17298. inline virtual bool contains(const unsigned char* key_begin, const std::size_t length) const
  17299. {
  17300. std::size_t bit_index = 0;
  17301. std::size_t bit = 0;
  17302. for (std::size_t i = 0; i < salt_.size(); ++i)
  17303. {
  17304. compute_indices(hash_ap(key_begin,length,salt_[i]),bit_index,bit);
  17305. if ((bit_table_[bit_index / bits_per_char] & bit_mask[bit]) != bit_mask[bit])
  17306. {
  17307. return false;
  17308. }
  17309. }
  17310. return true;
  17311. }
  17312. template <typename T>
  17313. inline bool contains(const T& t) const
  17314. {
  17315. return contains(reinterpret_cast<const unsigned char*>(&t),static_cast<std::size_t>(sizeof(T)));
  17316. }
  17317. inline bool contains(const std::string& key) const
  17318. {
  17319. return contains(reinterpret_cast<const unsigned char*>(key.data()),key.size());
  17320. }
  17321. inline bool contains(const char* data, const std::size_t& length) const
  17322. {
  17323. return contains(reinterpret_cast<const unsigned char*>(data),length);
  17324. }
  17325. template <typename InputIterator>
  17326. inline InputIterator contains_all(const InputIterator begin, const InputIterator end) const
  17327. {
  17328. InputIterator itr = begin;
  17329. while (end != itr)
  17330. {
  17331. if (!contains(*itr))
  17332. {
  17333. return itr;
  17334. }
  17335. ++itr;
  17336. }
  17337. return end;
  17338. }
  17339. template <typename InputIterator>
  17340. inline InputIterator contains_none(const InputIterator begin, const InputIterator end) const
  17341. {
  17342. InputIterator itr = begin;
  17343. while (end != itr)
  17344. {
  17345. if (contains(*itr))
  17346. {
  17347. return itr;
  17348. }
  17349. ++itr;
  17350. }
  17351. return end;
  17352. }
  17353. inline virtual unsigned long long int size() const
  17354. {
  17355. return table_size_;
  17356. }
  17357. inline std::size_t element_count() const
  17358. {
  17359. return inserted_element_count_;
  17360. }
  17361. inline double effective_fpp() const
  17362. {
  17363. /*
  17364. Note:
  17365. The effective false positive probability is calculated using the
  17366. designated table size and hash function count in conjunction with
  17367. the current number of inserted elements - not the user defined
  17368. predicated/expected number of inserted elements.
  17369. */
  17370. return std::pow(1.0 - std::exp(-1.0 * salt_.size() * inserted_element_count_ / size()), 1.0 * salt_.size());
  17371. }
  17372. inline filter& operator &= (const filter& f)
  17373. {
  17374. /* intersection */
  17375. if (
  17376. (salt_count_ == f.salt_count_) &&
  17377. (table_size_ == f.table_size_) &&
  17378. (random_seed_ == f.random_seed_)
  17379. )
  17380. {
  17381. for (std::size_t i = 0; i < raw_table_size_; ++i)
  17382. {
  17383. bit_table_[i] &= f.bit_table_[i];
  17384. }
  17385. }
  17386. return *this;
  17387. }
  17388. inline filter& operator |= (const filter& f)
  17389. {
  17390. /* union */
  17391. if (
  17392. (salt_count_ == f.salt_count_) &&
  17393. (table_size_ == f.table_size_) &&
  17394. (random_seed_ == f.random_seed_)
  17395. )
  17396. {
  17397. for (std::size_t i = 0; i < raw_table_size_; ++i)
  17398. {
  17399. bit_table_[i] |= f.bit_table_[i];
  17400. }
  17401. }
  17402. return *this;
  17403. }
  17404. inline filter& operator ^= (const filter& f)
  17405. {
  17406. /* difference */
  17407. if (
  17408. (salt_count_ == f.salt_count_) &&
  17409. (table_size_ == f.table_size_) &&
  17410. (random_seed_ == f.random_seed_)
  17411. )
  17412. {
  17413. for (std::size_t i = 0; i < raw_table_size_; ++i)
  17414. {
  17415. bit_table_[i] ^= f.bit_table_[i];
  17416. }
  17417. }
  17418. return *this;
  17419. }
  17420. inline const cell_type* table() const
  17421. {
  17422. return bit_table_;
  17423. }
  17424. inline bool write_to_file(const std::string& file_name) const
  17425. {
  17426. if (0 == table_size_)
  17427. return false;
  17428. const std::size_t buffer_size = sizeof( salt_count_) +
  17429. sizeof( table_size_) +
  17430. sizeof( raw_table_size_) +
  17431. sizeof( projected_element_count_) +
  17432. sizeof( inserted_element_count_) +
  17433. sizeof( random_seed_) +
  17434. sizeof(desired_false_positive_probability_) +
  17435. salt_count_ * sizeof( bloom_type) +
  17436. static_cast<std::size_t>(raw_table_size_) *
  17437. sizeof(cell_type) +
  17438. 64; // handle array sizes etc.
  17439. std::ofstream ostream(file_name.c_str(),std::ios::binary);
  17440. if (!ostream)
  17441. return false;
  17442. unsigned char* buffer = new unsigned char[buffer_size];
  17443. strtk::binary::writer writer(buffer,buffer_size);
  17444. writer.reset(true);
  17445. bool result = writer(salt_count_) &&
  17446. writer(table_size_) &&
  17447. writer(raw_table_size_) &&
  17448. writer(projected_element_count_) &&
  17449. writer(inserted_element_count_) &&
  17450. writer(random_seed_) &&
  17451. writer(desired_false_positive_probability_) &&
  17452. writer(salt_) &&
  17453. writer(bit_table_,raw_table_size_);
  17454. if (result)
  17455. {
  17456. writer(ostream);
  17457. }
  17458. ostream.close();
  17459. delete[] buffer;
  17460. return result;
  17461. }
  17462. inline bool read_from_file(const std::string& file_name)
  17463. {
  17464. std::ifstream istream(file_name.c_str(),std::ios::binary);
  17465. if (!istream)
  17466. return false;
  17467. salt_count_ = 0;
  17468. table_size_ = 0;
  17469. raw_table_size_ = 0;
  17470. projected_element_count_ = 0;
  17471. inserted_element_count_ = 0;
  17472. random_seed_ = 0;
  17473. desired_false_positive_probability_ = 0.0;
  17474. salt_.clear();
  17475. if (0 != bit_table_)
  17476. delete [] bit_table_;
  17477. bit_table_= 0;
  17478. const std::size_t buffer_size = strtk::fileio::file_size(file_name);
  17479. unsigned char* buffer = new unsigned char[buffer_size];
  17480. strtk::binary::reader reader(buffer,buffer_size);
  17481. reader.reset(true);
  17482. reader(istream,buffer_size);
  17483. istream.close();
  17484. bool result = reader(salt_count_) &&
  17485. reader(table_size_) &&
  17486. reader(raw_table_size_) &&
  17487. reader(projected_element_count_) &&
  17488. reader(inserted_element_count_) &&
  17489. reader(random_seed_) &&
  17490. reader(desired_false_positive_probability_) &&
  17491. reader(salt_) &&
  17492. reader(bit_table_,raw_table_size_);
  17493. delete[] buffer;
  17494. return result;
  17495. }
  17496. inline std::size_t hash_count()
  17497. {
  17498. return salt_.size();
  17499. }
  17500. protected:
  17501. inline virtual void compute_indices(const bloom_type& hash, std::size_t& bit_index, std::size_t& bit) const
  17502. {
  17503. bit_index = static_cast<std::size_t>(hash % table_size_);
  17504. bit = bit_index % bits_per_char;
  17505. }
  17506. void generate_unique_salt()
  17507. {
  17508. /*
  17509. Note:
  17510. A distinct hash function need not be implementation-wise
  17511. distinct. In the current implementation "seeding" a common
  17512. hash function with different values seems to be adequate.
  17513. */
  17514. const unsigned int predef_salt_count = 128;
  17515. static const bloom_type predef_salt[predef_salt_count] =
  17516. {
  17517. 0xAAAAAAAA, 0x55555555, 0x33333333, 0xCCCCCCCC,
  17518. 0x66666666, 0x99999999, 0xB5B5B5B5, 0x4B4B4B4B,
  17519. 0xAA55AA55, 0x55335533, 0x33CC33CC, 0xCC66CC66,
  17520. 0x66996699, 0x99B599B5, 0xB54BB54B, 0x4BAA4BAA,
  17521. 0xAA33AA33, 0x55CC55CC, 0x33663366, 0xCC99CC99,
  17522. 0x66B566B5, 0x994B994B, 0xB5AAB5AA, 0xAAAAAA33,
  17523. 0x555555CC, 0x33333366, 0xCCCCCC99, 0x666666B5,
  17524. 0x9999994B, 0xB5B5B5AA, 0xFFFFFFFF, 0xFFFF0000,
  17525. 0xB823D5EB, 0xC1191CDF, 0xF623AEB3, 0xDB58499F,
  17526. 0xC8D42E70, 0xB173F616, 0xA91A5967, 0xDA427D63,
  17527. 0xB1E8A2EA, 0xF6C0D155, 0x4909FEA3, 0xA68CC6A7,
  17528. 0xC395E782, 0xA26057EB, 0x0CD5DA28, 0x467C5492,
  17529. 0xF15E6982, 0x61C6FAD3, 0x9615E352, 0x6E9E355A,
  17530. 0x689B563E, 0x0C9831A8, 0x6753C18B, 0xA622689B,
  17531. 0x8CA63C47, 0x42CC2884, 0x8E89919B, 0x6EDBD7D3,
  17532. 0x15B6796C, 0x1D6FDFE4, 0x63FF9092, 0xE7401432,
  17533. 0xEFFE9412, 0xAEAEDF79, 0x9F245A31, 0x83C136FC,
  17534. 0xC3DA4A8C, 0xA5112C8C, 0x5271F491, 0x9A948DAB,
  17535. 0xCEE59A8D, 0xB5F525AB, 0x59D13217, 0x24E7C331,
  17536. 0x697C2103, 0x84B0A460, 0x86156DA9, 0xAEF2AC68,
  17537. 0x23243DA5, 0x3F649643, 0x5FA495A8, 0x67710DF8,
  17538. 0x9A6C499E, 0xDCFB0227, 0x46A43433, 0x1832B07A,
  17539. 0xC46AFF3C, 0xB9C8FFF0, 0xC9500467, 0x34431BDF,
  17540. 0xB652432B, 0xE367F12B, 0x427F4C1B, 0x224C006E,
  17541. 0x2E7E5A89, 0x96F99AA5, 0x0BEB452A, 0x2FD87C39,
  17542. 0x74B2E1FB, 0x222EFD24, 0xF357F60C, 0x440FCB1E,
  17543. 0x8BBE030F, 0x6704DC29, 0x1144D12F, 0x948B1355,
  17544. 0x6D8FD7E9, 0x1C11A014, 0xADD1592F, 0xFB3C712E,
  17545. 0xFC77642F, 0xF9C4CE8C, 0x31312FB9, 0x08B0DD79,
  17546. 0x318FA6E7, 0xC040D23D, 0xC0589AA7, 0x0CA5C075,
  17547. 0xF874B172, 0x0CF914D5, 0x784D3280, 0x4E8CFEBC,
  17548. 0xC569F575, 0xCDB2A091, 0x2CC016B4, 0x5C5F4421
  17549. };
  17550. if (salt_count_ <= predef_salt_count)
  17551. {
  17552. std::copy(predef_salt,
  17553. predef_salt + salt_count_,
  17554. std::back_inserter(salt_));
  17555. for (unsigned int i = 0; i < salt_.size(); ++i)
  17556. {
  17557. /*
  17558. Note:
  17559. This is done to integrate the user defined random seed,
  17560. so as to allow for the generation of unique bloom filter
  17561. instances.
  17562. */
  17563. salt_[i] = salt_[i] * salt_[(i + 3) % salt_.size()] + static_cast<bloom_type>(random_seed_);
  17564. }
  17565. }
  17566. else
  17567. {
  17568. std::copy(predef_salt,predef_salt + predef_salt_count,std::back_inserter(salt_));
  17569. srand(static_cast<unsigned int>(random_seed_));
  17570. while (salt_.size() < salt_count_)
  17571. {
  17572. bloom_type current_salt = static_cast<bloom_type>(rand()) * static_cast<bloom_type>(rand());
  17573. if (0 == current_salt) continue;
  17574. if (salt_.end() == std::find(salt_.begin(), salt_.end(), current_salt))
  17575. {
  17576. salt_.push_back(current_salt);
  17577. }
  17578. }
  17579. }
  17580. }
  17581. inline bloom_type hash_ap(const unsigned char* begin, std::size_t remaining_length, bloom_type hash) const
  17582. {
  17583. const unsigned char* itr = begin;
  17584. unsigned int loop = 0;
  17585. while (remaining_length >= 8)
  17586. {
  17587. const unsigned int& i1 = *(reinterpret_cast<const unsigned int*>(itr)); itr += sizeof(unsigned int);
  17588. const unsigned int& i2 = *(reinterpret_cast<const unsigned int*>(itr)); itr += sizeof(unsigned int);
  17589. hash ^= (hash << 7) ^ i1 * (hash >> 3) ^
  17590. (~((hash << 11) + (i2 ^ (hash >> 5))));
  17591. remaining_length -= 8;
  17592. }
  17593. if (remaining_length)
  17594. {
  17595. if (remaining_length >= 4)
  17596. {
  17597. const unsigned int& i = *(reinterpret_cast<const unsigned int*>(itr));
  17598. if (loop & 0x01)
  17599. hash ^= (hash << 7) ^ i * (hash >> 3);
  17600. else
  17601. hash ^= (~((hash << 11) + (i ^ (hash >> 5))));
  17602. ++loop;
  17603. remaining_length -= 4;
  17604. itr += sizeof(unsigned int);
  17605. }
  17606. if (remaining_length >= 2)
  17607. {
  17608. const unsigned short& i = *(reinterpret_cast<const unsigned short*>(itr));
  17609. if (loop & 0x01)
  17610. hash ^= (hash << 7) ^ i * (hash >> 3);
  17611. else
  17612. hash ^= (~((hash << 11) + (i ^ (hash >> 5))));
  17613. ++loop;
  17614. remaining_length -= 2;
  17615. itr += sizeof(unsigned short);
  17616. }
  17617. if (remaining_length)
  17618. {
  17619. hash += ((*itr) ^ (hash * 0xA5A5A5A5)) + loop;
  17620. }
  17621. }
  17622. return hash;
  17623. }
  17624. std::vector<bloom_type> salt_;
  17625. unsigned char* bit_table_;
  17626. unsigned int salt_count_;
  17627. unsigned long long int table_size_;
  17628. unsigned long long int raw_table_size_;
  17629. unsigned long long int projected_element_count_;
  17630. unsigned int inserted_element_count_;
  17631. unsigned long long int random_seed_;
  17632. double desired_false_positive_probability_;
  17633. };
  17634. inline filter operator & (const filter& a, const filter& b)
  17635. {
  17636. filter result = a;
  17637. result &= b;
  17638. return result;
  17639. }
  17640. inline filter operator | (const filter& a, const filter& b)
  17641. {
  17642. filter result = a;
  17643. result |= b;
  17644. return result;
  17645. }
  17646. inline filter operator ^ (const filter& a, const filter& b)
  17647. {
  17648. filter result = a;
  17649. result ^= b;
  17650. return result;
  17651. }
  17652. class compressible_filter : public filter
  17653. {
  17654. public:
  17655. compressible_filter(const parameters& p)
  17656. : filter(p)
  17657. {
  17658. size_list.push_back(table_size_);
  17659. }
  17660. inline virtual unsigned long long int size() const
  17661. {
  17662. return size_list.back();
  17663. }
  17664. inline bool compress(const double& percentage)
  17665. {
  17666. if ((0.0 >= percentage) || (percentage >= 100.0))
  17667. {
  17668. return false;
  17669. }
  17670. unsigned long long int original_table_size = size_list.back();
  17671. unsigned long long int new_table_size = static_cast<unsigned long long int>((size_list.back() * (1.0 - (percentage / 100.0))));
  17672. new_table_size -= (((new_table_size % bits_per_char) != 0) ? (new_table_size % bits_per_char) : 0);
  17673. if ((bits_per_char > new_table_size) || (new_table_size >= original_table_size))
  17674. {
  17675. return false;
  17676. }
  17677. desired_false_positive_probability_ = effective_fpp();
  17678. cell_type* tmp = new cell_type[static_cast<std::size_t>(new_table_size / bits_per_char)];
  17679. std::copy(bit_table_, bit_table_ + (new_table_size / bits_per_char), tmp);
  17680. cell_type* itr = bit_table_ + (new_table_size / bits_per_char);
  17681. cell_type* end = bit_table_ + (original_table_size / bits_per_char);
  17682. cell_type* itr_tmp = tmp;
  17683. while (end != itr)
  17684. {
  17685. *(itr_tmp++) |= (*itr++);
  17686. }
  17687. delete[] bit_table_;
  17688. bit_table_ = tmp;
  17689. size_list.push_back(new_table_size);
  17690. return true;
  17691. }
  17692. private:
  17693. inline virtual void compute_indices(const bloom_type& hash, std::size_t& bit_index, std::size_t& bit) const
  17694. {
  17695. bit_index = hash;
  17696. for (std::size_t i = 0; i < size_list.size(); ++i)
  17697. {
  17698. bit_index %= size_list[i];
  17699. }
  17700. bit = bit_index % bits_per_char;
  17701. }
  17702. std::vector<unsigned long long int> size_list;
  17703. };
  17704. }
  17705. namespace details
  17706. {
  17707. inline void compute_pod_hash(const char data[], unsigned int& hash)
  17708. {
  17709. hash ^= ((hash << 7) ^ data[0] * (hash >> 3));
  17710. hash ^= ~((hash << 11) + (data[1] ^ (hash >> 5)));
  17711. }
  17712. inline void compute_pod_hash(const unsigned char data[], unsigned int& hash)
  17713. {
  17714. hash ^= ((hash << 7) ^ data[0] * (hash >> 3));
  17715. hash ^= ~((hash << 11) + (data[1] ^ (hash >> 5)));
  17716. }
  17717. inline void compute_pod_hash(const int& data, unsigned int& hash)
  17718. {
  17719. const unsigned char* itr = reinterpret_cast<const unsigned char*>(&data);
  17720. hash ^= ((hash << 7) ^ itr[0] * (hash >> 3));
  17721. hash ^= ~((hash << 11) + (itr[1] ^ (hash >> 5)));
  17722. hash ^= ((hash << 7) ^ itr[2] * (hash >> 3));
  17723. hash ^= ~((hash << 11) + (itr[3] ^ (hash >> 5)));
  17724. }
  17725. inline void compute_pod_hash(const unsigned int& data, unsigned int& hash)
  17726. {
  17727. compute_pod_hash(static_cast<int>(data),hash);
  17728. }
  17729. inline void compute_pod_hash(const unsigned long long int& data, unsigned int& hash)
  17730. {
  17731. const unsigned char* itr = reinterpret_cast<const unsigned char*>(&data);
  17732. hash ^= ((hash << 7) ^ itr[0] * (hash >> 3));
  17733. hash ^= ~((hash << 11) + (itr[1] ^ (hash >> 5)));
  17734. hash ^= ((hash << 7) ^ itr[2] * (hash >> 3));
  17735. hash ^= ~((hash << 11) + (itr[3] ^ (hash >> 5)));
  17736. hash ^= ((hash << 7) ^ itr[4] * (hash >> 3));
  17737. hash ^= ~((hash << 11) + (itr[5] ^ (hash >> 5)));
  17738. hash ^= ((hash << 7) ^ itr[6] * (hash >> 3));
  17739. hash ^= ~((hash << 11) + (itr[7] ^ (hash >> 5)));
  17740. }
  17741. inline void compute_pod_hash(const double& data, unsigned int& hash)
  17742. {
  17743. const unsigned char* itr = reinterpret_cast<const unsigned char*>(&data);
  17744. hash ^= ((hash << 7) ^ itr[0] * (hash >> 3));
  17745. hash ^= ~((hash << 11) + (itr[1] ^ (hash >> 5)));
  17746. hash ^= ((hash << 7) ^ itr[2] * (hash >> 3));
  17747. hash ^= ~((hash << 11) + (itr[3] ^ (hash >> 5)));
  17748. hash ^= ((hash << 7) ^ itr[4] * (hash >> 3));
  17749. hash ^= ~((hash << 11) + (itr[5] ^ (hash >> 5)));
  17750. hash ^= ((hash << 7) ^ itr[6] * (hash >> 3));
  17751. hash ^= ~((hash << 11) + (itr[7] ^ (hash >> 5)));
  17752. }
  17753. template <std::size_t block_size, typename Iterator>
  17754. inline void compute_block(Iterator itr, std::size_t& length, unsigned int& hash)
  17755. {
  17756. while (length >= block_size)
  17757. {
  17758. for (std::size_t i = 0; i < block_size; ++i, ++itr)
  17759. {
  17760. compute_pod_hash((*itr),hash);
  17761. }
  17762. length -= block_size;
  17763. }
  17764. }
  17765. template <std::size_t block_size>
  17766. inline void compute_block(unsigned char* itr, std::size_t& length, unsigned int& hash)
  17767. {
  17768. unsigned int local_hash = hash;
  17769. while (length >= block_size)
  17770. {
  17771. for (std::size_t i = 0; i < block_size; ++i, ++itr)
  17772. {
  17773. compute_pod_hash((*itr),local_hash);
  17774. }
  17775. length -= block_size;
  17776. }
  17777. hash = local_hash;
  17778. }
  17779. template <std::size_t block_size>
  17780. inline void compute_block(char* itr, std::size_t& length, unsigned int& hash)
  17781. {
  17782. compute_block<block_size>(reinterpret_cast<unsigned char*>(itr),length,hash);
  17783. }
  17784. static const unsigned int hash_seed = 0xAAAAAAAA;
  17785. template <typename Iterator>
  17786. inline void hash(const Iterator itr, std::size_t length, unsigned int& hash_value)
  17787. {
  17788. if (length >= 64) compute_block<64>(itr,length,hash_value);
  17789. if (length >= 32) compute_block<32>(itr,length,hash_value);
  17790. if (length >= 16) compute_block<16>(itr,length,hash_value);
  17791. if (length >= 8) compute_block< 8>(itr,length,hash_value);
  17792. if (length >= 4) compute_block< 4>(itr,length,hash_value);
  17793. if (length >= 2) compute_block< 2>(itr,length,hash_value);
  17794. if (length == 0) compute_block< 1>(itr,length,hash_value);
  17795. }
  17796. } // namespace details
  17797. template <typename Iterator>
  17798. inline unsigned int hash(const Iterator itr,
  17799. std::size_t length,
  17800. unsigned int seed = details::hash_seed)
  17801. {
  17802. unsigned int hash_value = seed;
  17803. details::hash(itr,length,hash_value);
  17804. return hash_value;
  17805. }
  17806. inline unsigned int hash(const std::string& s, unsigned int seed = details::hash_seed)
  17807. {
  17808. unsigned int hash_value = seed;
  17809. return hash(s.begin(),s.size(),hash_value);
  17810. }
  17811. template <typename T,
  17812. typename Allocator,
  17813. template <typename,typename> class Sequence>
  17814. inline unsigned int hash(const Sequence<T,Allocator>& sequence, unsigned int seed = details::hash_seed)
  17815. {
  17816. unsigned int hash_value = seed;
  17817. return hash(sequence.begin(),sequence.size(),hash_value);
  17818. }
  17819. namespace util
  17820. {
  17821. template <typename T>
  17822. class scoped_restore
  17823. {
  17824. public:
  17825. scoped_restore(T& t, const bool restore = true)
  17826. : restore_(restore),
  17827. reference_(t),
  17828. copy_(t)
  17829. {}
  17830. ~scoped_restore()
  17831. {
  17832. if (restore_)
  17833. {
  17834. reference_ = copy_;
  17835. }
  17836. }
  17837. inline bool& restore()
  17838. {
  17839. return restore_;
  17840. }
  17841. private:
  17842. scoped_restore(const scoped_restore&);
  17843. scoped_restore& operator=(const scoped_restore&);
  17844. bool restore_;
  17845. T& reference_;
  17846. T copy_;
  17847. };
  17848. template <typename T>
  17849. class attribute
  17850. {
  17851. public:
  17852. attribute()
  17853. : initialised_(false)
  17854. {}
  17855. attribute(const T& t)
  17856. {
  17857. assign(t);
  17858. prev_t_ = t;
  17859. }
  17860. inline attribute& operator=(const T& t)
  17861. {
  17862. prev_t_ = t_;
  17863. assign(t);
  17864. return *this;
  17865. }
  17866. inline bool operator==(const T& t)
  17867. {
  17868. return initialised_ && (t_ == t);
  17869. }
  17870. template <typename TConvertibleType>
  17871. inline bool operator!=(const TConvertibleType& t)
  17872. {
  17873. return !(operator==(t));
  17874. }
  17875. inline T& operator()()
  17876. {
  17877. return t_;
  17878. }
  17879. inline const T& operator()() const
  17880. {
  17881. return t_;
  17882. }
  17883. inline operator T() const
  17884. {
  17885. return t_;
  17886. }
  17887. inline operator T()
  17888. {
  17889. return t_;
  17890. }
  17891. inline bool initialised() const
  17892. {
  17893. return initialised_;
  17894. }
  17895. inline bool& initialised()
  17896. {
  17897. return initialised_;
  17898. }
  17899. inline bool changed() const
  17900. {
  17901. return (initialised_ && (t_ != prev_t_));
  17902. }
  17903. inline const T& value() const
  17904. {
  17905. return t_;
  17906. }
  17907. inline T& value()
  17908. {
  17909. return t_;
  17910. }
  17911. inline const T& previous() const
  17912. {
  17913. return prev_t_;
  17914. }
  17915. inline T& previous()
  17916. {
  17917. return prev_t_;
  17918. }
  17919. private:
  17920. inline void assign(const T& t)
  17921. {
  17922. t_ = t;
  17923. initialised_ = true;
  17924. }
  17925. T t_;
  17926. T prev_t_;
  17927. bool initialised_;
  17928. };
  17929. inline bool operator==(const char* s, const attribute<std::string>& attrib)
  17930. {
  17931. return attrib.value() == s;
  17932. }
  17933. inline bool operator!=(const char* s, const attribute<std::string>& attrib)
  17934. {
  17935. return !(s == attrib.value());
  17936. }
  17937. template <typename T>
  17938. static inline std::ostream& operator<<(std::ostream& os, const attribute<T>& attrib)
  17939. {
  17940. return (os << attrib.value());
  17941. }
  17942. class semantic_action_impl
  17943. {
  17944. private:
  17945. class function_holder_base
  17946. {
  17947. public:
  17948. typedef const unsigned char* itr_type;
  17949. virtual ~function_holder_base(){}
  17950. virtual bool operator()(itr_type begin, itr_type end) const = 0;
  17951. inline bool operator()(const char* begin, const char* end) const
  17952. {
  17953. return operator()(reinterpret_cast<itr_type>(begin),
  17954. reinterpret_cast<itr_type>(end));
  17955. }
  17956. template <typename Iterator>
  17957. inline bool operator()(const std::pair<Iterator,Iterator>& p) const
  17958. {
  17959. return operator()(p.first,p.second);
  17960. }
  17961. };
  17962. template <typename Function>
  17963. class function_holder : public function_holder_base
  17964. {
  17965. public:
  17966. explicit function_holder(Function& f)
  17967. : function_(&f)
  17968. {}
  17969. inline virtual bool operator()(itr_type begin, itr_type end) const
  17970. {
  17971. return (*function_)(begin,end);
  17972. }
  17973. private:
  17974. Function* function_;
  17975. };
  17976. public:
  17977. semantic_action_impl()
  17978. : function_holder_(0)
  17979. {
  17980. std::fill_n(function_holder_buffer_,sizeof(function_holder_buffer_),0x00);
  17981. }
  17982. template <typename Function>
  17983. inline explicit semantic_action_impl(const Function& f)
  17984. {
  17985. std::fill_n(function_holder_buffer_,sizeof(function_holder_buffer_),0x00);
  17986. assign(f);
  17987. }
  17988. inline bool operator!() const
  17989. {
  17990. return (0 == function_holder_);
  17991. }
  17992. inline bool operator==(const semantic_action_impl& sa) const
  17993. {
  17994. return (0 != function_holder_) &&
  17995. (0 != sa.function_holder_) &&
  17996. (function_holder_ == sa.function_holder_);
  17997. }
  17998. template <typename InputIterator>
  17999. inline bool operator()(InputIterator begin, InputIterator end) const
  18000. {
  18001. if (0 != function_holder_)
  18002. return (*function_holder_).operator()(begin,end);
  18003. else
  18004. return false;
  18005. }
  18006. template <typename InputIterator>
  18007. inline bool operator()(const std::pair<InputIterator,InputIterator>& r) const
  18008. {
  18009. return operator()(r.first,r.second);
  18010. }
  18011. inline bool operator()(const std::string& s) const
  18012. {
  18013. return operator()(s.data(),s.data() + s.size());
  18014. }
  18015. template <typename Function>
  18016. inline void assign(Function& f)
  18017. {
  18018. static const std::size_t type_size = sizeof(function_holder<Function>(f));
  18019. function_holder_ = construct<Function,type_size <= function_holder_buffer_size>::type(f,function_holder_buffer_);
  18020. }
  18021. inline semantic_action_impl& ref()
  18022. {
  18023. return (*this);
  18024. }
  18025. private:
  18026. typedef function_holder_base* function_holder_ptr;
  18027. inline semantic_action_impl& operator=(const semantic_action_impl&);
  18028. template <typename Function, bool b>
  18029. struct construct
  18030. {
  18031. inline static function_holder_ptr type(Function&, unsigned char*)
  18032. {
  18033. return reinterpret_cast<function_holder_ptr>(0);
  18034. }
  18035. };
  18036. template <typename Function>
  18037. struct construct<Function,true>
  18038. {
  18039. inline static function_holder_ptr type(Function& f, unsigned char* buffer)
  18040. {
  18041. return new(buffer)function_holder<Function>(f);
  18042. }
  18043. };
  18044. function_holder_ptr function_holder_;
  18045. enum { function_holder_buffer_size = 64 };
  18046. unsigned char function_holder_buffer_[function_holder_buffer_size];
  18047. };
  18048. template <typename Function>
  18049. inline semantic_action_impl semantic_action(Function& f)
  18050. {
  18051. return semantic_action_impl(f);
  18052. }
  18053. } // namespace util
  18054. namespace details
  18055. {
  18056. #define strtk_register_attribute_type_tag(T) \
  18057. template<> struct supported_conversion_to_type< strtk::util::attribute<T> >{ typedef attribute_type_tag type; }; \
  18058. template<> struct supported_conversion_from_type< strtk::util::attribute<T> > { typedef attribute_type_tag type; };\
  18059. strtk_register_attribute_type_tag(unsigned short)
  18060. strtk_register_attribute_type_tag(unsigned int)
  18061. strtk_register_attribute_type_tag(unsigned long)
  18062. strtk_register_attribute_type_tag(unsigned long long int)
  18063. strtk_register_attribute_type_tag(short)
  18064. strtk_register_attribute_type_tag(int)
  18065. strtk_register_attribute_type_tag(long)
  18066. strtk_register_attribute_type_tag(long long)
  18067. strtk_register_attribute_type_tag(float)
  18068. strtk_register_attribute_type_tag(double)
  18069. strtk_register_attribute_type_tag(long double)
  18070. strtk_register_attribute_type_tag(unsigned char)
  18071. strtk_register_attribute_type_tag(signed char)
  18072. strtk_register_attribute_type_tag(char)
  18073. strtk_register_attribute_type_tag(std::string)
  18074. template <typename Iterator, typename T>
  18075. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, strtk::util::attribute<T>& result, attribute_type_tag)
  18076. {
  18077. if (strtk::string_to_type_converter(itr,end,result.value()))
  18078. {
  18079. result.initialised() = true;
  18080. return true;
  18081. }
  18082. else
  18083. return false;
  18084. }
  18085. template <typename T>
  18086. inline bool type_to_string_converter_impl(const strtk::util::attribute<T>& attrib, std::string& result, attribute_type_tag)
  18087. {
  18088. if (!attrib.initialised())
  18089. return false;
  18090. return strtk::type_to_string(attrib.value(),result);
  18091. }
  18092. #undef strtk_register_attribute_type_tag
  18093. template<> struct supported_conversion_to_type < strtk::util::semantic_action_impl > { typedef semantic_action_type_tag type; };
  18094. template<> struct supported_conversion_from_type< strtk::util::semantic_action_impl > { typedef semantic_action_type_tag type; };
  18095. template <typename Iterator>
  18096. inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, strtk::util::semantic_action_impl& result, semantic_action_type_tag)
  18097. {
  18098. return result(itr,end);
  18099. }
  18100. inline bool type_to_string_converter_impl(const strtk::util::semantic_action_impl&, std::string& result, semantic_action_type_tag)
  18101. {
  18102. static std::string result_str = "semantic_action";
  18103. result = result_str;
  18104. return true;
  18105. }
  18106. } // namespace details
  18107. namespace util
  18108. {
  18109. class value
  18110. {
  18111. private:
  18112. class type_holder_base
  18113. {
  18114. public:
  18115. typedef const unsigned char* itr_type;
  18116. virtual ~type_holder_base(){}
  18117. virtual bool operator()(itr_type begin, itr_type end) const = 0;
  18118. virtual bool to_string(std::string& s) const = 0;
  18119. inline bool operator()(const char* begin, const char* end) const
  18120. {
  18121. return operator()(reinterpret_cast<itr_type>(begin),
  18122. reinterpret_cast<itr_type>(end));
  18123. }
  18124. template <typename Iterator>
  18125. inline bool operator()(const std::pair<Iterator,Iterator>& p) const
  18126. {
  18127. return operator()(p.first,p.second);
  18128. }
  18129. };
  18130. template <typename T>
  18131. class type_holder : public type_holder_base
  18132. {
  18133. public:
  18134. typedef T* type_ptr;
  18135. explicit type_holder(T& t)
  18136. : value_ptr_(&t)
  18137. {}
  18138. inline virtual bool operator()(itr_type begin, itr_type end) const
  18139. {
  18140. return strtk::string_to_type_converter(begin,end,(*value_ptr_));
  18141. }
  18142. inline virtual bool to_string(std::string& s) const
  18143. {
  18144. return strtk::type_to_string((*value_ptr_),s);
  18145. }
  18146. inline operator T() const
  18147. {
  18148. return (*value_ptr_);
  18149. }
  18150. private:
  18151. type_ptr value_ptr_;
  18152. };
  18153. public:
  18154. value()
  18155. : type_holder_(0)
  18156. {
  18157. std::fill_n(type_holder_buffer_,sizeof(type_holder_buffer_),0x00);
  18158. }
  18159. template <typename T>
  18160. inline explicit value(T& t)
  18161. {
  18162. std::fill_n(type_holder_buffer_,sizeof(type_holder_buffer_),0x00);
  18163. assign(t);
  18164. }
  18165. inline bool operator!() const
  18166. {
  18167. return (0 == type_holder_);
  18168. }
  18169. inline bool operator==(const value& v) const
  18170. {
  18171. return (0 != type_holder_) &&
  18172. (0 != v.type_holder_) &&
  18173. (type_holder_ == v.type_holder_);
  18174. }
  18175. inline value& operator=(const value& v)
  18176. {
  18177. if (&v != this)
  18178. {
  18179. if (0 != v.type_holder_)
  18180. {
  18181. std::copy(v.type_holder_buffer_,
  18182. v.type_holder_buffer_ + type_holder_buffer_size,
  18183. type_holder_buffer_);
  18184. type_holder_ = reinterpret_cast<type_holder_base*>(type_holder_buffer_);
  18185. }
  18186. }
  18187. return *this;
  18188. }
  18189. template <typename InputIterator>
  18190. inline bool operator()(InputIterator begin, InputIterator end) const
  18191. {
  18192. if (0 != type_holder_)
  18193. return (*type_holder_).operator()(begin,end);
  18194. else
  18195. return false;
  18196. }
  18197. template <typename InputIterator>
  18198. inline bool operator()(const std::pair<InputIterator,InputIterator>& r) const
  18199. {
  18200. return operator()(r.first,r.second);
  18201. }
  18202. inline bool operator()(const std::string& s) const
  18203. {
  18204. return operator()(s.data(),s.data() + s.size());
  18205. }
  18206. template <typename T>
  18207. inline void assign(T& t)
  18208. {
  18209. static const std::size_t type_size = sizeof(type_holder<T>(t));
  18210. type_holder_ = construct<T,type_size <= type_holder_buffer_size>::type(t,type_holder_buffer_);
  18211. }
  18212. inline bool to_string(std::string& s) const
  18213. {
  18214. if (0 != type_holder_)
  18215. return (*type_holder_).to_string(s);
  18216. else
  18217. return false;
  18218. }
  18219. template <typename T>
  18220. inline operator T() const
  18221. {
  18222. if (0 != type_holder_)
  18223. return (*type_holder_);
  18224. else
  18225. return T();
  18226. }
  18227. private:
  18228. typedef type_holder_base* type_holder_ptr;
  18229. template <typename T, bool b>
  18230. struct construct
  18231. {
  18232. inline static type_holder_ptr type(T&, unsigned char*)
  18233. {
  18234. return reinterpret_cast<type_holder_ptr>(0);
  18235. }
  18236. };
  18237. template <typename T>
  18238. struct construct<T,true>
  18239. {
  18240. inline static type_holder_ptr type(T& t, unsigned char* buffer)
  18241. {
  18242. return new(buffer)type_holder<T>(t);
  18243. }
  18244. };
  18245. type_holder_ptr type_holder_;
  18246. enum { type_holder_buffer_size = 2 * sizeof(type_holder<unsigned long long int>) };
  18247. unsigned char type_holder_buffer_[type_holder_buffer_size];
  18248. };
  18249. template <typename Key,
  18250. typename T,
  18251. typename Comparator,
  18252. typename MapAllocator,
  18253. typename OutputIterator>
  18254. inline void make_key_list(const std::map<Key,T,Comparator,MapAllocator>& map,
  18255. OutputIterator out)
  18256. {
  18257. if (map.empty()) return;
  18258. typedef typename std::map<Key,T,Comparator,MapAllocator> map_type;
  18259. typename map_type::const_iterator itr = map.begin();
  18260. typename map_type::const_iterator end = map.end();
  18261. while (end != itr)
  18262. {
  18263. *out++ = (itr++)->first;
  18264. }
  18265. }
  18266. template <typename Key,
  18267. typename T,
  18268. typename Comparator,
  18269. typename MapAllocator,
  18270. typename SetAllocator>
  18271. inline void make_key_list(const std::map<Key,T,Comparator,MapAllocator>& map,
  18272. std::set<Key,Comparator,SetAllocator>& set)
  18273. {
  18274. make_key_list(map,std::inserter(set,set.begin()));
  18275. }
  18276. template <typename Key,
  18277. typename T,
  18278. typename Comparator,
  18279. typename MapAllocator,
  18280. typename SetAllocator>
  18281. inline void make_key_list(const std::map<Key,T,Comparator,MapAllocator>& map,
  18282. std::multiset<Key,Comparator,SetAllocator>& multiset)
  18283. {
  18284. make_key_list(map,std::inserter(multiset,multiset.begin()));
  18285. }
  18286. template <typename Key,
  18287. typename T,
  18288. typename Comparator,
  18289. typename MapAllocator,
  18290. typename SequenceAllocator,
  18291. template <typename,typename> class Sequence>
  18292. inline void make_key_list(const std::map<Key,T,Comparator,MapAllocator>& map,
  18293. Sequence<Key,SequenceAllocator>& sequence)
  18294. {
  18295. make_key_list(map,std::back_inserter(sequence));
  18296. }
  18297. template <typename Key,
  18298. typename T,
  18299. typename Comparator,
  18300. typename MapAllocator,
  18301. typename OutputIterator>
  18302. inline void make_value_list(const std::multimap<Key,T,Comparator,MapAllocator>& map,
  18303. const Key& key,
  18304. OutputIterator out)
  18305. {
  18306. if (map.empty()) return;
  18307. typedef typename std::multimap<Key,T,Comparator,MapAllocator> map_type;
  18308. typename map_type::const_iterator itr = map.find(key);
  18309. typename map_type::const_iterator end = map.end();
  18310. while ((end != itr) && (key == itr->first))
  18311. {
  18312. *out++ = (itr++)->second;
  18313. }
  18314. }
  18315. template <typename Key,
  18316. typename T,
  18317. typename Comparator,
  18318. typename MapAllocator,
  18319. typename SequenceAllocator,
  18320. template <typename,typename> class Sequence>
  18321. inline void make_value_list(const std::multimap<Key,T,Comparator,MapAllocator>& map,
  18322. const Key& key,
  18323. Sequence<T,SequenceAllocator>& sequence)
  18324. {
  18325. make_value_list(map,key,std::back_inserter(sequence));
  18326. }
  18327. template <typename T,
  18328. typename Allocator,
  18329. template <typename,typename> class Sequence>
  18330. inline void delete_all(Sequence<T*,Allocator>& sequence)
  18331. {
  18332. typename Sequence<T*,Allocator>::iterator itr = sequence.begin();
  18333. typename Sequence<T*,Allocator>::iterator end = sequence.end();
  18334. while (end != itr)
  18335. {
  18336. delete (*itr);
  18337. ++itr;
  18338. }
  18339. sequence.clear();
  18340. }
  18341. template <typename Key,
  18342. typename T,
  18343. typename Comparator,
  18344. typename Allocator>
  18345. inline void delete_all(std::map<Key,T*,Comparator,Allocator>& cont)
  18346. {
  18347. typename std::map<Key,T*,Comparator,Allocator>::iterator itr = cont.begin();
  18348. typename std::map<Key,T*,Comparator,Allocator>::iterator end = cont.end();
  18349. while (end != itr)
  18350. {
  18351. delete (*itr).second;
  18352. ++itr;
  18353. }
  18354. cont.clear();
  18355. }
  18356. template <typename Key,
  18357. typename T,
  18358. typename Comparator,
  18359. typename Allocator>
  18360. inline void delete_all(std::multimap<Key,T*,Comparator,Allocator>& cont)
  18361. {
  18362. typename std::multimap<Key,T*,Comparator,Allocator>::iterator itr = cont.begin();
  18363. typename std::multimap<Key,T*,Comparator,Allocator>::iterator end = cont.end();
  18364. while (end != itr)
  18365. {
  18366. delete (*itr).second;
  18367. ++itr;
  18368. }
  18369. cont.clear();
  18370. }
  18371. template <typename T,
  18372. typename Comparator,
  18373. typename Allocator>
  18374. inline void delete_all(std::set<T*,Comparator,Allocator>& cont)
  18375. {
  18376. typename std::set<T*,Comparator,Allocator>::iterator itr = cont.begin();
  18377. typename std::set<T*,Comparator,Allocator>::iterator end = cont.end();
  18378. while (end != itr)
  18379. {
  18380. delete (*itr);
  18381. ++itr;
  18382. }
  18383. cont.clear();
  18384. }
  18385. template <typename T,
  18386. typename Comparator,
  18387. typename Allocator>
  18388. inline void delete_all(std::multiset<T*,Comparator,Allocator>& cont)
  18389. {
  18390. typename std::multiset<T*,Comparator,Allocator>::iterator itr = cont.begin();
  18391. typename std::multiset<T*,Comparator,Allocator>::iterator end = cont.end();
  18392. while (end != itr)
  18393. {
  18394. delete (*itr);
  18395. ++itr;
  18396. }
  18397. cont.clear();
  18398. }
  18399. template <typename Predicate,
  18400. typename T,
  18401. typename Allocator,
  18402. template <typename,typename> class Sequence>
  18403. inline void delete_if(const Predicate& p,
  18404. Sequence<T*,Allocator>& sequence)
  18405. {
  18406. typename Sequence<T*,Allocator>::iterator itr = sequence.begin();
  18407. while (sequence.end() != itr)
  18408. {
  18409. if (p(*itr))
  18410. {
  18411. delete (*itr);
  18412. itr = sequence.erase(itr);
  18413. }
  18414. else
  18415. ++itr;
  18416. }
  18417. }
  18418. template <typename Predicate,
  18419. typename Key,
  18420. typename T,
  18421. typename Comparator,
  18422. typename Allocator>
  18423. inline void delete_if(const Predicate& p,
  18424. std::map<Key,T*,Comparator,Allocator>& cont)
  18425. {
  18426. typename std::map<Key,T*,Comparator,Allocator>::iterator itr = cont.begin();
  18427. while (cont.end() != itr)
  18428. {
  18429. if (p(*itr))
  18430. {
  18431. delete (*itr).second;
  18432. itr = cont.erase(itr);
  18433. }
  18434. else
  18435. ++itr;
  18436. }
  18437. }
  18438. template <typename Predicate,
  18439. typename Key,
  18440. typename T,
  18441. typename Comparator,
  18442. typename Allocator>
  18443. inline void delete_if(const Predicate& p,
  18444. std::multimap<Key,T*,Comparator,Allocator>& cont)
  18445. {
  18446. typename std::multimap<Key,T*,Comparator,Allocator>::iterator itr = cont.begin();
  18447. while (cont.end() != itr)
  18448. {
  18449. if (p(*itr))
  18450. {
  18451. delete (*itr).second;
  18452. itr = cont.erase(itr);
  18453. }
  18454. else
  18455. ++itr;
  18456. }
  18457. }
  18458. template <typename Predicate,
  18459. typename T,
  18460. typename Comparator,
  18461. typename Allocator>
  18462. inline void delete_if(const Predicate& p,
  18463. std::set<T*,Comparator,Allocator>& cont)
  18464. {
  18465. typename std::set<T*,Comparator,Allocator>::iterator itr = cont.begin();
  18466. while (cont.end() != itr)
  18467. {
  18468. if (p(*itr))
  18469. {
  18470. delete (*itr).second;
  18471. itr = cont.erase(itr);
  18472. }
  18473. else
  18474. ++itr;
  18475. }
  18476. }
  18477. template <typename Predicate,
  18478. typename T,
  18479. typename Comparator,
  18480. typename Allocator>
  18481. inline void delete_if(const Predicate& p,
  18482. std::multiset<T*,Comparator,Allocator>& cont)
  18483. {
  18484. typename std::multiset<T*,Comparator,Allocator>::iterator itr = cont.begin();
  18485. while (cont.end() != itr)
  18486. {
  18487. if (p(*itr))
  18488. {
  18489. delete (*itr).second;
  18490. itr = cont.erase(itr);
  18491. }
  18492. else
  18493. ++itr;
  18494. }
  18495. }
  18496. template <typename T,
  18497. typename Allocator,
  18498. template <typename,typename> class Sequence>
  18499. inline void push_back(Sequence<T,Allocator>& sequence,
  18500. const T& v1, const T& v2, const T& v3, const T& v4,
  18501. const T& v5, const T& v6, const T& v7, const T& v8,
  18502. const T& v9, const T& v10, const T& v11)
  18503. {
  18504. sequence.push_back(v1); sequence.push_back(v2);
  18505. sequence.push_back(v3); sequence.push_back(v4);
  18506. sequence.push_back(v5); sequence.push_back(v6);
  18507. sequence.push_back(v7); sequence.push_back(v8);
  18508. sequence.push_back(v9); sequence.push_back(v10);
  18509. sequence.push_back(v11);
  18510. }
  18511. template <typename T,
  18512. typename Allocator,
  18513. template <typename,typename> class Sequence>
  18514. inline void push_back(Sequence<T,Allocator>& sequence,
  18515. const T& v1, const T& v2, const T& v3, const T& v4,
  18516. const T& v5, const T& v6, const T& v7, const T& v8,
  18517. const T& v9, const T& v10)
  18518. {
  18519. sequence.push_back(v1); sequence.push_back(v2);
  18520. sequence.push_back(v3); sequence.push_back(v4);
  18521. sequence.push_back(v5); sequence.push_back(v6);
  18522. sequence.push_back(v7); sequence.push_back(v8);
  18523. sequence.push_back(v9); sequence.push_back(v10);
  18524. }
  18525. template <typename T,
  18526. typename Allocator,
  18527. template <typename,typename> class Sequence>
  18528. inline void push_back(Sequence<T,Allocator>& sequence,
  18529. const T& v1, const T& v2, const T& v3, const T& v4,
  18530. const T& v5, const T& v6, const T& v7, const T& v8,
  18531. const T& v9)
  18532. {
  18533. sequence.push_back(v1); sequence.push_back(v2);
  18534. sequence.push_back(v3); sequence.push_back(v4);
  18535. sequence.push_back(v5); sequence.push_back(v6);
  18536. sequence.push_back(v7); sequence.push_back(v8);
  18537. sequence.push_back(v9);
  18538. }
  18539. template <typename T,
  18540. typename Allocator,
  18541. template <typename,typename> class Sequence>
  18542. inline void push_back(Sequence<T,Allocator>& sequence,
  18543. const T& v1, const T& v2, const T& v3, const T& v4,
  18544. const T& v5, const T& v6, const T& v7, const T& v8)
  18545. {
  18546. sequence.push_back(v1); sequence.push_back(v2);
  18547. sequence.push_back(v3); sequence.push_back(v4);
  18548. sequence.push_back(v5); sequence.push_back(v6);
  18549. sequence.push_back(v7); sequence.push_back(v8);
  18550. }
  18551. template <typename T,
  18552. typename Allocator,
  18553. template <typename,typename> class Sequence>
  18554. inline void push_back(Sequence<T,Allocator>& sequence,
  18555. const T& v1, const T& v2, const T& v3, const T& v4,
  18556. const T& v5, const T& v6, const T& v7)
  18557. {
  18558. sequence.push_back(v1); sequence.push_back(v2);
  18559. sequence.push_back(v3); sequence.push_back(v4);
  18560. sequence.push_back(v5); sequence.push_back(v6);
  18561. sequence.push_back(v7);
  18562. }
  18563. template <typename T,
  18564. typename Allocator,
  18565. template <typename,typename> class Sequence>
  18566. inline void push_back(Sequence<T,Allocator>& sequence,
  18567. const T& v1, const T& v2, const T& v3, const T& v4,
  18568. const T& v5, const T& v6)
  18569. {
  18570. sequence.push_back(v1); sequence.push_back(v2);
  18571. sequence.push_back(v3); sequence.push_back(v4);
  18572. sequence.push_back(v5); sequence.push_back(v6);
  18573. }
  18574. template <typename T,
  18575. typename Allocator,
  18576. template <typename,typename> class Sequence>
  18577. inline void push_back(Sequence<T,Allocator>& sequence,
  18578. const T& v1, const T& v2, const T& v3, const T& v4,
  18579. const T& v5)
  18580. {
  18581. sequence.push_back(v1); sequence.push_back(v2);
  18582. sequence.push_back(v3); sequence.push_back(v4);
  18583. sequence.push_back(v5);
  18584. }
  18585. template <typename T,
  18586. typename Allocator,
  18587. template <typename,typename> class Sequence>
  18588. inline void push_back(Sequence<T,Allocator>& sequence,
  18589. const T& v1, const T& v2, const T& v3, const T& v4)
  18590. {
  18591. sequence.push_back(v1); sequence.push_back(v2);
  18592. sequence.push_back(v3); sequence.push_back(v4);
  18593. }
  18594. template <typename T,
  18595. typename Allocator,
  18596. template <typename,typename> class Sequence>
  18597. inline void push_back(Sequence<T,Allocator>& sequence,
  18598. const T& v1, const T& v2, const T& v3)
  18599. {
  18600. sequence.push_back(v1); sequence.push_back(v2);
  18601. sequence.push_back(v3);
  18602. }
  18603. template <typename T,
  18604. typename Allocator,
  18605. template <typename,typename> class Sequence>
  18606. inline void push_back(Sequence<T,Allocator>& sequence,
  18607. const T& v1, const T& v2)
  18608. {
  18609. sequence.push_back(v1); sequence.push_back(v2);
  18610. }
  18611. template <typename T,
  18612. typename Allocator,
  18613. template <typename,typename> class Sequence>
  18614. inline void push_back(Sequence<T,Allocator>& sequence,
  18615. const T& v1)
  18616. {
  18617. sequence.push_back(v1);
  18618. }
  18619. template <typename T, typename Comparator, typename Allocator>
  18620. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18621. const T& v1, const T& v2, const T& v3, const T& v4,
  18622. const T& v5, const T& v6, const T& v7, const T& v8,
  18623. const T& v9, const T& v10)
  18624. {
  18625. set.insert(v1); set.insert(v2);
  18626. set.insert(v3); set.insert(v4);
  18627. set.insert(v5); set.insert(v6);
  18628. set.insert(v7); set.insert(v8);
  18629. set.insert(v9); set.insert(v10);
  18630. }
  18631. template <typename T, typename Comparator, typename Allocator>
  18632. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18633. const T& v1, const T& v2, const T& v3, const T& v4,
  18634. const T& v5, const T& v6, const T& v7, const T& v8,
  18635. const T& v9)
  18636. {
  18637. set.insert(v1); set.insert(v2);
  18638. set.insert(v3); set.insert(v4);
  18639. set.insert(v5); set.insert(v6);
  18640. set.insert(v7); set.insert(v8);
  18641. set.insert(v9);
  18642. }
  18643. template <typename T, typename Comparator, typename Allocator>
  18644. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18645. const T& v1, const T& v2, const T& v3, const T& v4,
  18646. const T& v5, const T& v6, const T& v7, const T& v8)
  18647. {
  18648. set.insert(v1); set.insert(v2);
  18649. set.insert(v3); set.insert(v4);
  18650. set.insert(v5); set.insert(v6);
  18651. set.insert(v7); set.insert(v8);
  18652. }
  18653. template <typename T, typename Comparator, typename Allocator>
  18654. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18655. const T& v1, const T& v2, const T& v3, const T& v4,
  18656. const T& v5, const T& v6, const T& v7)
  18657. {
  18658. set.insert(v1); set.insert(v2);
  18659. set.insert(v3); set.insert(v4);
  18660. set.insert(v5); set.insert(v6);
  18661. set.insert(v7);
  18662. }
  18663. template <typename T, typename Comparator, typename Allocator>
  18664. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18665. const T& v1, const T& v2, const T& v3, const T& v4,
  18666. const T& v5, const T& v6)
  18667. {
  18668. set.insert(v1); set.insert(v2);
  18669. set.insert(v3); set.insert(v4);
  18670. set.insert(v5); set.insert(v6);
  18671. }
  18672. template <typename T, typename Comparator, typename Allocator>
  18673. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18674. const T& v1, const T& v2, const T& v3, const T& v4,
  18675. const T& v5)
  18676. {
  18677. set.insert(v1); set.insert(v2);
  18678. set.insert(v3); set.insert(v4);
  18679. set.insert(v5);
  18680. }
  18681. template <typename T, typename Comparator, typename Allocator>
  18682. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18683. const T& v1, const T& v2, const T& v3, const T& v4)
  18684. {
  18685. set.insert(v1); set.insert(v2);
  18686. set.insert(v3); set.insert(v4);
  18687. }
  18688. template <typename T, typename Comparator, typename Allocator>
  18689. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18690. const T& v1, const T& v2, const T& v3)
  18691. {
  18692. set.insert(v1); set.insert(v2);
  18693. set.insert(v3);
  18694. }
  18695. template <typename T, typename Comparator, typename Allocator>
  18696. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18697. const T& v1, const T& v2)
  18698. {
  18699. set.insert(v1); set.insert(v2);
  18700. }
  18701. template <typename T, typename Comparator, typename Allocator>
  18702. inline void push_back(std::set<T,Comparator,Allocator>& set,
  18703. const T& v1)
  18704. {
  18705. set.insert(v1);
  18706. }
  18707. template <typename T, typename Comparator, typename Allocator>
  18708. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18709. const T& v1, const T& v2, const T& v3, const T& v4,
  18710. const T& v5, const T& v6, const T& v7, const T& v8,
  18711. const T& v9, const T& v10)
  18712. {
  18713. set.insert(v1); set.insert(v2);
  18714. set.insert(v3); set.insert(v4);
  18715. set.insert(v5); set.insert(v6);
  18716. set.insert(v7); set.insert(v8);
  18717. set.insert(v9); set.insert(v10);
  18718. }
  18719. template <typename T, typename Comparator, typename Allocator>
  18720. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18721. const T& v1, const T& v2, const T& v3, const T& v4,
  18722. const T& v5, const T& v6, const T& v7, const T& v8,
  18723. const T& v9)
  18724. {
  18725. set.insert(v1); set.insert(v2);
  18726. set.insert(v3); set.insert(v4);
  18727. set.insert(v5); set.insert(v6);
  18728. set.insert(v7); set.insert(v8);
  18729. set.insert(v9);
  18730. }
  18731. template <typename T, typename Comparator, typename Allocator>
  18732. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18733. const T& v1, const T& v2, const T& v3, const T& v4,
  18734. const T& v5, const T& v6, const T& v7, const T& v8)
  18735. {
  18736. set.insert(v1); set.insert(v2);
  18737. set.insert(v3); set.insert(v4);
  18738. set.insert(v5); set.insert(v6);
  18739. set.insert(v7); set.insert(v8);
  18740. }
  18741. template <typename T, typename Comparator, typename Allocator>
  18742. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18743. const T& v1, const T& v2, const T& v3, const T& v4,
  18744. const T& v5, const T& v6, const T& v7)
  18745. {
  18746. set.insert(v1); set.insert(v2);
  18747. set.insert(v3); set.insert(v4);
  18748. set.insert(v5); set.insert(v6);
  18749. set.insert(v7);
  18750. }
  18751. template <typename T, typename Comparator, typename Allocator>
  18752. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18753. const T& v1, const T& v2, const T& v3, const T& v4,
  18754. const T& v5, const T& v6)
  18755. {
  18756. set.insert(v1); set.insert(v2);
  18757. set.insert(v3); set.insert(v4);
  18758. set.insert(v5); set.insert(v6);
  18759. }
  18760. template <typename T, typename Comparator, typename Allocator>
  18761. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18762. const T& v1, const T& v2, const T& v3, const T& v4,
  18763. const T& v5)
  18764. {
  18765. set.insert(v1); set.insert(v2);
  18766. set.insert(v3); set.insert(v4);
  18767. set.insert(v5);
  18768. }
  18769. template <typename T, typename Comparator, typename Allocator>
  18770. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18771. const T& v1, const T& v2, const T& v3, const T& v4)
  18772. {
  18773. set.insert(v1); set.insert(v2);
  18774. set.insert(v3); set.insert(v4);
  18775. }
  18776. template <typename T, typename Comparator, typename Allocator>
  18777. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18778. const T& v1, const T& v2, const T& v3)
  18779. {
  18780. set.insert(v1); set.insert(v2);
  18781. set.insert(v3);
  18782. }
  18783. template <typename T, typename Comparator, typename Allocator>
  18784. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18785. const T& v1, const T& v2)
  18786. {
  18787. set.insert(v1); set.insert(v2);
  18788. }
  18789. template <typename T, typename Comparator, typename Allocator>
  18790. inline void push_back(std::multiset<T,Comparator,Allocator>& set,
  18791. const T& v1)
  18792. {
  18793. set.insert(v1);
  18794. }
  18795. template <typename T,
  18796. typename Allocator,
  18797. template <typename,typename> class Sequence>
  18798. inline void clear(Sequence<T,Allocator>& sequence)
  18799. {
  18800. sequence.clear();
  18801. }
  18802. template <typename T,
  18803. typename Comparator,
  18804. typename Allocator>
  18805. inline void clear(std::set<T,Comparator,Allocator>& set)
  18806. {
  18807. std::set<T> null_set;
  18808. std::swap(set,null_set);
  18809. }
  18810. template <typename T,
  18811. typename Comparator,
  18812. typename Allocator>
  18813. inline void clear(std::multiset<T,Comparator,Allocator>& multiset)
  18814. {
  18815. std::multiset<T> null_set;
  18816. std::swap(multiset,null_set);
  18817. }
  18818. template <typename T, typename Container>
  18819. inline void clear(std::queue<T,Container>& queue)
  18820. {
  18821. std::queue<T> null_que;
  18822. std::swap(queue,null_que);
  18823. }
  18824. template <typename T, typename Container>
  18825. inline void clear(std::stack<T,Container>& stack)
  18826. {
  18827. std::stack<T> null_stack;
  18828. std::swap(stack,null_stack);
  18829. }
  18830. template <typename T,
  18831. typename Container,
  18832. typename Comparator>
  18833. inline void clear(std::priority_queue<T,Container,Comparator>& priority_queue)
  18834. {
  18835. std::priority_queue<T> null_pqueue;
  18836. std::swap(priority_queue,null_pqueue);
  18837. }
  18838. } // namespace util
  18839. namespace details
  18840. {
  18841. template <std::size_t N>
  18842. struct column_list_impl
  18843. {
  18844. enum { size = N };
  18845. std::size_t index_list[N];
  18846. };
  18847. template <typename Cli, std::size_t N>
  18848. class column_selector_base
  18849. {
  18850. public:
  18851. typedef column_selector_base<Cli,N> csb_t;
  18852. typedef column_list_impl<N> column_list_t;
  18853. column_selector_base(const column_list_t& column_list)
  18854. : column_list_(column_list),
  18855. current_index_(0),
  18856. target_index_(column_list_.index_list[0]),
  18857. col_list_index_(0),
  18858. error_count_(0)
  18859. {}
  18860. inline csb_t& operator*()
  18861. {
  18862. return (*this);
  18863. }
  18864. inline csb_t& operator++()
  18865. {
  18866. return (*this);
  18867. }
  18868. inline csb_t operator++(int)
  18869. {
  18870. return (*this);
  18871. }
  18872. template <typename Iterator>
  18873. inline csb_t& operator=(const std::pair<Iterator,Iterator>& r)
  18874. {
  18875. process(r);
  18876. return (*this);
  18877. }
  18878. void reset()
  18879. {
  18880. current_index_ = 0;
  18881. col_list_index_ = 0;
  18882. target_index_ = column_list_.index_list[0];
  18883. error_count_ = 0;
  18884. }
  18885. protected:
  18886. class colsel_value_list
  18887. {
  18888. public:
  18889. typedef std::pair<strtk::util::value,bool> value_t;
  18890. colsel_value_list()
  18891. : current_index(0)
  18892. {
  18893. static const value_t null_value(strtk::util::value(),false);
  18894. std::fill_n(value_list,N,null_value);
  18895. }
  18896. template <typename T>
  18897. inline void register_value(T& t)
  18898. {
  18899. if (current_index < N)
  18900. {
  18901. value_list[current_index].first.assign(t);
  18902. value_list[current_index].second = false;
  18903. ++current_index;
  18904. }
  18905. }
  18906. std::size_t current_index;
  18907. value_t value_list[N];
  18908. };
  18909. template <typename Iterator>
  18910. inline void process(const std::pair<Iterator,Iterator>& r)
  18911. {
  18912. if (current_index_ > target_index_)
  18913. return;
  18914. else if (current_index_ == target_index_)
  18915. {
  18916. typename colsel_value_list::value_t& v = cvl_.value_list[col_list_index_];
  18917. if (true != (v.second = v.first(r.first,r.second)))
  18918. {
  18919. ++error_count_;
  18920. }
  18921. ++col_list_index_;
  18922. if (col_list_index_ < column_list_t::size)
  18923. target_index_ = column_list_.index_list[col_list_index_];
  18924. else
  18925. target_index_ = std::numeric_limits<std::size_t>::max();
  18926. }
  18927. ++current_index_;
  18928. }
  18929. inline colsel_value_list& cvl()
  18930. {
  18931. return cvl_;
  18932. }
  18933. const column_list_t& column_list_;
  18934. std::size_t current_index_;
  18935. std::size_t target_index_;
  18936. std::size_t col_list_index_;
  18937. std::size_t error_count_;
  18938. colsel_value_list cvl_;
  18939. private:
  18940. csb_t& operator=(const csb_t& csb);
  18941. };
  18942. template <typename T0 = void, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void,
  18943. typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void, typename T9 = void,
  18944. typename T10 = void, typename T11 = void>
  18945. class column_selector_impl
  18946. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>,12>
  18947. {
  18948. public:
  18949. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>,12> csb_t;
  18950. typedef column_list_impl<12> column_list_t;
  18951. column_selector_impl(const column_list_t& column_list,
  18952. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  18953. T5& t5, T6& t6, T7& t7, T8& t8, T9& t9,
  18954. T10& t10, T11& t11)
  18955. : csb_t(column_list)
  18956. {
  18957. csb_t::cvl().register_value( t0); csb_t::cvl().register_value( t1);
  18958. csb_t::cvl().register_value( t2); csb_t::cvl().register_value( t3);
  18959. csb_t::cvl().register_value( t4); csb_t::cvl().register_value( t5);
  18960. csb_t::cvl().register_value( t6); csb_t::cvl().register_value( t7);
  18961. csb_t::cvl().register_value( t8); csb_t::cvl().register_value( t9);
  18962. csb_t::cvl().register_value(t10); csb_t::cvl().register_value(t11);
  18963. }
  18964. };
  18965. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  18966. typename T5, typename T6, typename T7, typename T8, typename T9,
  18967. typename T10>
  18968. class column_selector_impl <T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>
  18969. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>,11>
  18970. {
  18971. public:
  18972. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>,11> csb_t;
  18973. typedef column_list_impl<11> column_list_t;
  18974. column_selector_impl(const column_list_t& column_list,
  18975. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  18976. T5& t5, T6& t6, T7& t7, T8& t8, T9& t9,
  18977. T10& t10)
  18978. : csb_t(column_list)
  18979. {
  18980. csb_t::cvl().register_value( t0); csb_t::cvl().register_value( t1);
  18981. csb_t::cvl().register_value( t2); csb_t::cvl().register_value( t3);
  18982. csb_t::cvl().register_value( t4); csb_t::cvl().register_value( t5);
  18983. csb_t::cvl().register_value( t6); csb_t::cvl().register_value( t7);
  18984. csb_t::cvl().register_value( t8); csb_t::cvl().register_value( t9);
  18985. csb_t::cvl().register_value(t10);
  18986. }
  18987. };
  18988. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  18989. typename T5, typename T6, typename T7, typename T8, typename T9>
  18990. class column_selector_impl <T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
  18991. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>,10>
  18992. {
  18993. public:
  18994. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>,10> csb_t;
  18995. typedef column_list_impl<10> column_list_t;
  18996. column_selector_impl(const column_list_t& column_list,
  18997. T1& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  18998. T5& t5, T6& t6, T7& t7, T8& t8, T9& t9)
  18999. : csb_t(column_list)
  19000. {
  19001. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  19002. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  19003. csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5);
  19004. csb_t::cvl().register_value(t6); csb_t::cvl().register_value(t7);
  19005. csb_t::cvl().register_value(t8); csb_t::cvl().register_value(t9);
  19006. }
  19007. };
  19008. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  19009. typename T5, typename T6, typename T7, typename T8>
  19010. class column_selector_impl <T0,T1,T2,T3,T4,T5,T6,T7,T8>
  19011. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8>,9>
  19012. {
  19013. public:
  19014. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8>,9> csb_t;
  19015. typedef column_list_impl<9> column_list_t;
  19016. column_selector_impl(const column_list_t& column_list,
  19017. T1& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  19018. T5& t5, T6& t6, T7& t7, T8& t8)
  19019. : csb_t(column_list)
  19020. {
  19021. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  19022. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  19023. csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5);
  19024. csb_t::cvl().register_value(t6); csb_t::cvl().register_value(t7);
  19025. csb_t::cvl().register_value(t8);
  19026. }
  19027. };
  19028. template <typename T0, typename T1, typename T2, typename T3,
  19029. typename T4, typename T5, typename T6, typename T7>
  19030. class column_selector_impl <T0,T1,T2,T3,T4,T5,T6,T7>
  19031. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7>,8>
  19032. {
  19033. public:
  19034. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7>,8> csb_t;
  19035. typedef column_list_impl<8> column_list_t;
  19036. column_selector_impl(const column_list_t& column_list,
  19037. T1& t0, T1& t1, T2& t2, T3& t3,
  19038. T4& t4, T5& t5, T6& t6, T7& t7)
  19039. : csb_t(column_list)
  19040. {
  19041. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  19042. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  19043. csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5);
  19044. csb_t::cvl().register_value(t6); csb_t::cvl().register_value(t7);
  19045. }
  19046. };
  19047. template <typename T0, typename T1, typename T2, typename T3,
  19048. typename T4, typename T5, typename T6>
  19049. class column_selector_impl <T0,T1,T2,T3,T4,T5,T6>
  19050. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6>,7>
  19051. {
  19052. public:
  19053. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5,T6>,7> csb_t;
  19054. typedef column_list_impl<7> column_list_t;
  19055. column_selector_impl(const column_list_t& column_list,
  19056. T1& t0, T1& t1, T2& t2, T3& t3,
  19057. T4& t4, T5& t5, T6& t6)
  19058. : csb_t(column_list)
  19059. {
  19060. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  19061. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  19062. csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5);
  19063. csb_t::cvl().register_value(t6);
  19064. }
  19065. };
  19066. template <typename T0, typename T1, typename T2,
  19067. typename T3, typename T4, typename T5>
  19068. class column_selector_impl <T0,T1,T2,T3,T4,T5>
  19069. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5>,6>
  19070. {
  19071. public:
  19072. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4,T5>,6> csb_t;
  19073. typedef column_list_impl<6> column_list_t;
  19074. column_selector_impl(const column_list_t& column_list,
  19075. T1& t0, T1& t1, T2& t2,
  19076. T3& t3, T4& t4, T5& t5)
  19077. : csb_t(column_list)
  19078. {
  19079. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  19080. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  19081. csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5);
  19082. }
  19083. };
  19084. template <typename T0, typename T1, typename T2,
  19085. typename T3, typename T4>
  19086. class column_selector_impl <T0,T1,T2,T3,T4>
  19087. : public column_selector_base<column_selector_impl<T0,T1,T2,T3,T4>,5>
  19088. {
  19089. public:
  19090. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3,T4>,5> csb_t;
  19091. typedef column_list_impl<5> column_list_t;
  19092. column_selector_impl(const column_list_t& column_list,
  19093. T1& t0, T1& t1, T2& t2,
  19094. T3& t3, T4& t4)
  19095. : csb_t(column_list)
  19096. {
  19097. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  19098. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  19099. csb_t::cvl().register_value(t4);
  19100. }
  19101. };
  19102. template <typename T0, typename T1, typename T2, typename T3>
  19103. class column_selector_impl <T0,T1,T2,T3>
  19104. : public column_selector_base<column_selector_impl<T0,T1,T2,T3>,4>
  19105. {
  19106. public:
  19107. typedef column_selector_base<column_selector_impl<T0,T1,T2,T3>,4> csb_t;
  19108. typedef column_list_impl<4> column_list_t;
  19109. column_selector_impl(const column_list_t& column_list,
  19110. T1& t0, T1& t1, T2& t2, T3& t3)
  19111. : csb_t(column_list)
  19112. {
  19113. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  19114. csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3);
  19115. }
  19116. };
  19117. template <typename T0, typename T1, typename T2>
  19118. class column_selector_impl <T0,T1,T2>
  19119. : public column_selector_base<column_selector_impl<T0,T1,T2>,3>
  19120. {
  19121. public:
  19122. typedef column_selector_base<column_selector_impl<T0,T1,T2>,3> csb_t;
  19123. typedef column_list_impl<3> column_list_t;
  19124. column_selector_impl(const column_list_t& column_list,
  19125. T1& t0, T1& t1, T2& t2)
  19126. : csb_t(column_list)
  19127. {
  19128. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  19129. csb_t::cvl().register_value(t2);
  19130. }
  19131. };
  19132. template <typename T0, typename T1>
  19133. class column_selector_impl <T0,T1>
  19134. : public column_selector_base<column_selector_impl<T0,T1>,2>
  19135. {
  19136. public:
  19137. typedef column_selector_base<column_selector_impl<T0,T1>,2> csb_t;
  19138. typedef column_list_impl<2> column_list_t;
  19139. column_selector_impl(const column_list_t& column_list,
  19140. T1& t0, T1& t1)
  19141. : csb_t(column_list)
  19142. {
  19143. csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1);
  19144. }
  19145. };
  19146. template <typename T0>
  19147. class column_selector_impl <T0>
  19148. : public column_selector_base<column_selector_impl<T0>,1>
  19149. {
  19150. public:
  19151. typedef column_selector_base<column_selector_impl<T0>,1> csb_t;
  19152. typedef column_list_impl<1> column_list_t;
  19153. column_selector_impl(const column_list_t& column_list, T0& t0)
  19154. : csb_t(column_list)
  19155. {
  19156. csb_t::cvl().register_value(t0);
  19157. }
  19158. };
  19159. }
  19160. inline details::column_list_impl<12>
  19161. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19162. const std::size_t& idx2, const std::size_t& idx3,
  19163. const std::size_t& idx4, const std::size_t& idx5,
  19164. const std::size_t& idx6, const std::size_t& idx7,
  19165. const std::size_t& idx8, const std::size_t& idx9,
  19166. const std::size_t& idx10, const std::size_t& idx11)
  19167. {
  19168. details::column_list_impl<12> cli;
  19169. cli.index_list[ 0] = idx0; cli.index_list[ 1] = idx1;
  19170. cli.index_list[ 2] = idx2; cli.index_list[ 3] = idx3;
  19171. cli.index_list[ 4] = idx4; cli.index_list[ 5] = idx5;
  19172. cli.index_list[ 6] = idx6; cli.index_list[ 7] = idx7;
  19173. cli.index_list[ 8] = idx8; cli.index_list[ 9] = idx9;
  19174. cli.index_list[10] = idx10; cli.index_list[11] = idx11;
  19175. return cli;
  19176. }
  19177. inline details::column_list_impl<11>
  19178. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19179. const std::size_t& idx2, const std::size_t& idx3,
  19180. const std::size_t& idx4, const std::size_t& idx5,
  19181. const std::size_t& idx6, const std::size_t& idx7,
  19182. const std::size_t& idx8, const std::size_t& idx9,
  19183. const std::size_t& idx10)
  19184. {
  19185. details::column_list_impl<11> cli;
  19186. cli.index_list[ 0] = idx0; cli.index_list[1] = idx1;
  19187. cli.index_list[ 2] = idx2; cli.index_list[3] = idx3;
  19188. cli.index_list[ 4] = idx4; cli.index_list[5] = idx5;
  19189. cli.index_list[ 6] = idx6; cli.index_list[7] = idx7;
  19190. cli.index_list[ 8] = idx8; cli.index_list[9] = idx9;
  19191. cli.index_list[10] = idx10;
  19192. return cli;
  19193. }
  19194. inline details::column_list_impl<10>
  19195. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19196. const std::size_t& idx2, const std::size_t& idx3,
  19197. const std::size_t& idx4, const std::size_t& idx5,
  19198. const std::size_t& idx6, const std::size_t& idx7,
  19199. const std::size_t& idx8, const std::size_t& idx9)
  19200. {
  19201. details::column_list_impl<10> cli;
  19202. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19203. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  19204. cli.index_list[4] = idx4; cli.index_list[5] = idx5;
  19205. cli.index_list[6] = idx6; cli.index_list[7] = idx7;
  19206. cli.index_list[8] = idx8; cli.index_list[9] = idx9;
  19207. return cli;
  19208. }
  19209. inline details::column_list_impl<9>
  19210. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19211. const std::size_t& idx2, const std::size_t& idx3,
  19212. const std::size_t& idx4, const std::size_t& idx5,
  19213. const std::size_t& idx6, const std::size_t& idx7,
  19214. const std::size_t& idx8)
  19215. {
  19216. details::column_list_impl<9> cli;
  19217. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19218. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  19219. cli.index_list[4] = idx4; cli.index_list[5] = idx5;
  19220. cli.index_list[6] = idx6; cli.index_list[7] = idx7;
  19221. cli.index_list[8] = idx8;
  19222. return cli;
  19223. }
  19224. inline details::column_list_impl<8>
  19225. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19226. const std::size_t& idx2, const std::size_t& idx3,
  19227. const std::size_t& idx4, const std::size_t& idx5,
  19228. const std::size_t& idx6, const std::size_t& idx7)
  19229. {
  19230. details::column_list_impl<8> cli;
  19231. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19232. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  19233. cli.index_list[4] = idx4; cli.index_list[5] = idx5;
  19234. cli.index_list[6] = idx6; cli.index_list[7] = idx7;
  19235. return cli;
  19236. }
  19237. inline details::column_list_impl<7>
  19238. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19239. const std::size_t& idx2, const std::size_t& idx3,
  19240. const std::size_t& idx4, const std::size_t& idx5,
  19241. const std::size_t& idx6)
  19242. {
  19243. details::column_list_impl<7> cli;
  19244. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19245. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  19246. cli.index_list[4] = idx4; cli.index_list[5] = idx5;
  19247. cli.index_list[6] = idx6;
  19248. return cli;
  19249. }
  19250. inline details::column_list_impl<6>
  19251. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19252. const std::size_t& idx2, const std::size_t& idx3,
  19253. const std::size_t& idx4, const std::size_t& idx5)
  19254. {
  19255. details::column_list_impl<6> cli;
  19256. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19257. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  19258. cli.index_list[4] = idx4; cli.index_list[5] = idx5;
  19259. return cli;
  19260. }
  19261. inline details::column_list_impl<5>
  19262. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19263. const std::size_t& idx2, const std::size_t& idx3,
  19264. const std::size_t& idx4)
  19265. {
  19266. details::column_list_impl<5> cli;
  19267. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19268. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  19269. cli.index_list[4] = idx4;
  19270. return cli;
  19271. }
  19272. inline details::column_list_impl<4>
  19273. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19274. const std::size_t& idx2, const std::size_t& idx3)
  19275. {
  19276. details::column_list_impl<4> cli;
  19277. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19278. cli.index_list[2] = idx2; cli.index_list[3] = idx3;
  19279. return cli;
  19280. }
  19281. inline details::column_list_impl<3>
  19282. column_list(const std::size_t& idx0, const std::size_t& idx1,
  19283. const std::size_t& idx2)
  19284. {
  19285. details::column_list_impl<3> cli;
  19286. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19287. cli.index_list[2] = idx2;
  19288. return cli;
  19289. }
  19290. inline details::column_list_impl<2>
  19291. column_list(const std::size_t& idx0, const std::size_t& idx1)
  19292. {
  19293. details::column_list_impl<2> cli;
  19294. cli.index_list[0] = idx0; cli.index_list[1] = idx1;
  19295. return cli;
  19296. }
  19297. inline details::column_list_impl<1>
  19298. column_list(const std::size_t& idx0)
  19299. {
  19300. details::column_list_impl<1> cli;
  19301. cli.index_list[0] = idx0;
  19302. return cli;
  19303. }
  19304. inline details::column_list_impl<12> column_list(const std::size_t (&idx)[12])
  19305. {
  19306. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],
  19307. idx[6],idx[7],idx[8],idx[9],idx[10],idx[11]);
  19308. }
  19309. inline details::column_list_impl<11> column_list(const std::size_t (&idx)[11])
  19310. {
  19311. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],
  19312. idx[6],idx[7],idx[8],idx[9],idx[10]);
  19313. }
  19314. inline details::column_list_impl<10> column_list(const std::size_t (&idx)[10])
  19315. {
  19316. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],
  19317. idx[6],idx[7],idx[8],idx[9]);
  19318. }
  19319. inline details::column_list_impl<9> column_list(const std::size_t (&idx)[9])
  19320. {
  19321. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],
  19322. idx[6],idx[7],idx[8]);
  19323. }
  19324. inline details::column_list_impl<8> column_list(const std::size_t (&idx)[8])
  19325. {
  19326. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],
  19327. idx[6],idx[7]);
  19328. }
  19329. inline details::column_list_impl<7> column_list(const std::size_t (&idx)[7])
  19330. {
  19331. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],idx[6]);
  19332. }
  19333. inline details::column_list_impl<6> column_list(const std::size_t (&idx)[6])
  19334. {
  19335. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5]);
  19336. }
  19337. inline details::column_list_impl<5> column_list(const std::size_t (&idx)[5])
  19338. {
  19339. return column_list(idx[0],idx[1],idx[2],idx[3],idx[4]);
  19340. }
  19341. inline details::column_list_impl<4> column_list(const std::size_t (&idx)[4])
  19342. {
  19343. return column_list(idx[0],idx[1],idx[2],idx[3]);
  19344. }
  19345. inline details::column_list_impl<3> column_list(const std::size_t (&idx)[3])
  19346. {
  19347. return column_list(idx[0],idx[1],idx[2]);
  19348. }
  19349. inline details::column_list_impl<2> column_list(const std::size_t (&idx)[2])
  19350. {
  19351. return column_list(idx[0],idx[1]);
  19352. }
  19353. inline details::column_list_impl<1> column_list(const std::size_t (&idx)[1])
  19354. {
  19355. return column_list(idx[0]);
  19356. }
  19357. template <typename T0, typename T1, typename T2, typename T3,
  19358. typename T4, typename T5, typename T6, typename T7,
  19359. typename T8, typename T9, typename T10, typename T11>
  19360. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
  19361. column_selector(const details::column_list_impl<11>& col_list,
  19362. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19363. T6& t6, T7& t7, T8& t8, T9& t9, T10& t10, T11& t11)
  19364. {
  19365. return
  19366. details::column_selector_impl
  19367. <T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>
  19368. (col_list,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11);
  19369. }
  19370. template <typename T0, typename T1, typename T2, typename T3,
  19371. typename T4, typename T5, typename T6, typename T7,
  19372. typename T8, typename T9, typename T10>
  19373. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
  19374. column_selector(const details::column_list_impl<11>& col_list,
  19375. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19376. T6& t6, T7& t7, T8& t8, T9& t9, T10& t10)
  19377. {
  19378. return
  19379. details::column_selector_impl
  19380. <T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>
  19381. (col_list,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10);
  19382. }
  19383. template <typename T0, typename T1, typename T2, typename T3,
  19384. typename T4, typename T5, typename T6, typename T7,
  19385. typename T8, typename T9>
  19386. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
  19387. column_selector(const details::column_list_impl<10>& col_list,
  19388. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19389. T6& t6, T7& t7, T8& t8, T9& t9)
  19390. {
  19391. return
  19392. details::column_selector_impl
  19393. <T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
  19394. (col_list,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9);
  19395. }
  19396. template <typename T0, typename T1, typename T2, typename T3,
  19397. typename T4, typename T5, typename T6, typename T7,
  19398. typename T8>
  19399. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7,T8>
  19400. column_selector(const details::column_list_impl<9>& col_list,
  19401. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19402. T6& t6, T7& t7, T8& t8)
  19403. {
  19404. return
  19405. details::column_selector_impl
  19406. <T0,T1,T2,T3,T4,T5,T6,T7,T8>
  19407. (col_list,t0,t1,t2,t3,t4,t5,t6,t7,t8);
  19408. }
  19409. template <typename T0, typename T1, typename T2, typename T3,
  19410. typename T4, typename T5, typename T6, typename T7>
  19411. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5,T6,T7>
  19412. column_selector(const details::column_list_impl<8>& col_list,
  19413. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19414. T6& t6, T7& t7)
  19415. {
  19416. return
  19417. details::column_selector_impl
  19418. <T0,T1,T2,T3,T4,T5,T6,T7>
  19419. (col_list,t0,t1,t2,t3,t4,t5,t6,t7);
  19420. }
  19421. template <typename T0, typename T1, typename T2, typename T3,
  19422. typename T4, typename T5, typename T6>
  19423. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5,T6>
  19424. column_selector(const details::column_list_impl<7>& col_list,
  19425. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6)
  19426. {
  19427. return
  19428. details::column_selector_impl
  19429. <T0,T1,T2,T3,T4,T5,T6>
  19430. (col_list,t0,t1,t2,t3,t4,t5,t6);
  19431. }
  19432. template <typename T0, typename T1, typename T2, typename T3,
  19433. typename T4, typename T5>
  19434. inline typename details::column_selector_impl<T0,T1,T2,T3,T4,T5>
  19435. column_selector(const details::column_list_impl<6>& col_list,
  19436. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5)
  19437. {
  19438. return
  19439. details::column_selector_impl
  19440. <T0,T1,T2,T3,T4,T5>
  19441. (col_list,t0,t1,t2,t3,t4,t5);
  19442. }
  19443. template <typename T0, typename T1, typename T2,
  19444. typename T3, typename T4>
  19445. inline typename details::column_selector_impl<T0,T1,T2,T3,T4>
  19446. column_selector(const details::column_list_impl<5>& col_list,
  19447. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4)
  19448. {
  19449. return
  19450. details::column_selector_impl
  19451. <T0,T1,T2,T3,T4>
  19452. (col_list,t0,t1,t2,t3,t4);
  19453. }
  19454. template <typename T0, typename T1, typename T2, typename T3>
  19455. inline typename details::column_selector_impl<T0,T1,T2,T3>
  19456. column_selector(const details::column_list_impl<4>& col_list,
  19457. T0& t0, T1& t1, T2& t2, T3& t3)
  19458. {
  19459. return
  19460. details::column_selector_impl
  19461. <T0,T1,T2,T3>
  19462. (col_list,t0,t1,t2,t3);
  19463. }
  19464. template <typename T0, typename T1, typename T2>
  19465. inline typename details::column_selector_impl<T0,T1,T2>
  19466. column_selector(const details::column_list_impl<3>& col_list,
  19467. T0& t0, T1& t1, T2& t2)
  19468. {
  19469. return
  19470. details::column_selector_impl
  19471. <T0,T1,T2>
  19472. (col_list,t0,t1,t2);
  19473. }
  19474. template <typename T0, typename T1>
  19475. inline typename details::column_selector_impl<T0,T1>
  19476. column_selector(const details::column_list_impl<2>& col_list,
  19477. T0& t0, T1& t1)
  19478. {
  19479. return
  19480. details::column_selector_impl
  19481. <T0,T1>
  19482. (col_list,t0,t1);
  19483. }
  19484. template <typename T0>
  19485. inline typename details::column_selector_impl<T0>
  19486. column_selector(const details::column_list_impl<1>& col_list, T0& t0)
  19487. {
  19488. return
  19489. details::column_selector_impl
  19490. <T0>
  19491. (col_list,t0);
  19492. }
  19493. namespace details
  19494. {
  19495. template <typename Iterator>
  19496. inline Iterator inc(Iterator itr, const std::size_t& n)
  19497. {
  19498. std::advance(itr,n);
  19499. return itr;
  19500. }
  19501. //Single type column selectors
  19502. template <typename T, std::size_t N>
  19503. struct compose_st_selector_impl
  19504. {};
  19505. template <typename T>
  19506. struct compose_st_selector_impl <T,1>
  19507. {
  19508. typedef column_selector_impl<T> type;
  19509. typedef column_list_impl<1> column_list_t;
  19510. template <typename Allocator,
  19511. template <typename,typename> class Sequence>
  19512. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19513. {
  19514. return type(col_list,seq[0]);
  19515. }
  19516. template <typename Allocator>
  19517. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19518. {
  19519. typename std::list<T,Allocator>::iterator b = list.begin();
  19520. return type(col_list,*(b));
  19521. }
  19522. };
  19523. template <typename T>
  19524. struct compose_st_selector_impl <T,2>
  19525. {
  19526. typedef column_selector_impl<T,T> type;
  19527. typedef column_list_impl<2> column_list_t;
  19528. template <typename Allocator,
  19529. template <typename,typename> class Sequence>
  19530. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19531. {
  19532. return type(col_list,seq[0],seq[1]);
  19533. }
  19534. template <typename Allocator>
  19535. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19536. {
  19537. typename std::list<T,Allocator>::iterator b = list.begin();
  19538. return type(col_list,*(b),*inc(b,1));
  19539. }
  19540. };
  19541. template <typename T>
  19542. struct compose_st_selector_impl <T,3>
  19543. {
  19544. typedef column_selector_impl<T,T,T> type;
  19545. typedef column_list_impl<3> column_list_t;
  19546. template <typename Allocator,
  19547. template <typename,typename> class Sequence>
  19548. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19549. {
  19550. return type(col_list,seq[0],seq[1],seq[2]);
  19551. }
  19552. template <typename Allocator>
  19553. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19554. {
  19555. typename std::list<T,Allocator>::iterator b = list.begin();
  19556. return type(col_list,*(b),*inc(b,1),*inc(b,2));
  19557. }
  19558. };
  19559. template <typename T>
  19560. struct compose_st_selector_impl <T,4>
  19561. {
  19562. typedef column_selector_impl<T,T,T,T> type;
  19563. typedef column_list_impl<4> column_list_t;
  19564. template <typename Allocator,
  19565. template <typename,typename> class Sequence>
  19566. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19567. {
  19568. return type(col_list,seq[0],seq[1],seq[2],seq[3]);
  19569. }
  19570. template <typename Allocator>
  19571. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19572. {
  19573. typename std::list<T,Allocator>::iterator b = list.begin();
  19574. return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3));
  19575. }
  19576. };
  19577. template <typename T>
  19578. struct compose_st_selector_impl <T,5>
  19579. {
  19580. typedef column_selector_impl<T,T,T,T,T> type;
  19581. typedef column_list_impl<5> column_list_t;
  19582. template <typename Allocator,
  19583. template <typename,typename> class Sequence>
  19584. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19585. {
  19586. return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4]);
  19587. }
  19588. template <typename Allocator>
  19589. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19590. {
  19591. typename std::list<T,Allocator>::iterator b = list.begin();
  19592. return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4));
  19593. }
  19594. };
  19595. template <typename T>
  19596. struct compose_st_selector_impl <T,6>
  19597. {
  19598. typedef column_selector_impl<T,T,T,T,T,T> type;
  19599. typedef column_list_impl<6> column_list_t;
  19600. template <typename Allocator,
  19601. template <typename,typename> class Sequence>
  19602. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19603. {
  19604. return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5]);
  19605. }
  19606. template <typename Allocator>
  19607. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19608. {
  19609. typename std::list<T,Allocator>::iterator b = list.begin();
  19610. return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4),*inc(b,5));
  19611. }
  19612. };
  19613. template <typename T>
  19614. struct compose_st_selector_impl <T,7>
  19615. {
  19616. typedef column_selector_impl<T,T,T,T,T,T,T> type;
  19617. typedef column_list_impl<7> column_list_t;
  19618. template <typename Allocator,
  19619. template <typename,typename> class Sequence>
  19620. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19621. {
  19622. return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5],seq[6]);
  19623. }
  19624. template <typename Allocator>
  19625. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19626. {
  19627. typename std::list<T,Allocator>::iterator b = list.begin();
  19628. return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4),*inc(b,5),*inc(b,6));
  19629. }
  19630. };
  19631. template <typename T>
  19632. struct compose_st_selector_impl <T,8>
  19633. {
  19634. typedef column_selector_impl<T,T,T,T,T,T,T,T> type;
  19635. typedef column_list_impl<8> column_list_t;
  19636. template <typename Allocator,
  19637. template <typename,typename> class Sequence>
  19638. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19639. {
  19640. return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5],seq[6],seq[7]);
  19641. }
  19642. template <typename Allocator>
  19643. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19644. {
  19645. typename std::list<T,Allocator>::iterator b = list.begin();
  19646. 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));
  19647. }
  19648. };
  19649. template <typename T>
  19650. struct compose_st_selector_impl <T,9>
  19651. {
  19652. typedef column_selector_impl<T,T,T,T,T,T,T,T,T> type;
  19653. typedef column_list_impl<9> column_list_t;
  19654. template <typename Allocator,
  19655. template <typename,typename> class Sequence>
  19656. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19657. {
  19658. return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5],seq[6],seq[7],seq[8]);
  19659. }
  19660. template <typename Allocator>
  19661. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19662. {
  19663. typename std::list<T,Allocator>::iterator b = list.begin();
  19664. 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));
  19665. }
  19666. };
  19667. template <typename T>
  19668. struct compose_st_selector_impl <T,10>
  19669. {
  19670. typedef column_selector_impl<T,T,T,T,T,T,T,T,T,T> type;
  19671. typedef column_list_impl<10> column_list_t;
  19672. template <typename Allocator,
  19673. template <typename,typename> class Sequence>
  19674. static inline type create(const column_list_t& col_list, Sequence<T,Allocator>& seq)
  19675. {
  19676. return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5],seq[6],seq[7],seq[8],seq[9]);
  19677. }
  19678. template <typename Allocator>
  19679. static inline type create(const column_list_t& col_list, std::list<T,Allocator>& list)
  19680. {
  19681. typename std::list<T,Allocator>::iterator b = list.begin();
  19682. 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));
  19683. }
  19684. };
  19685. }
  19686. template <std::size_t N,
  19687. typename T,
  19688. typename Allocator,
  19689. template <typename,typename> class Sequence>
  19690. inline typename details::compose_st_selector_impl<T,N>::type
  19691. column_selector(const details::column_list_impl<N>& col_list, Sequence<T,Allocator>& seq)
  19692. {
  19693. if (seq.size() >= N)
  19694. {
  19695. typedef typename details::compose_st_selector_impl<T,N> composer_t;
  19696. return composer_t::create(col_list,seq);
  19697. }
  19698. else
  19699. throw std::invalid_argument("column_selector(sequence/list) - size < N!");
  19700. }
  19701. namespace details
  19702. {
  19703. template <typename InputIterator, std::size_t N>
  19704. class column_selector_iterator_impl
  19705. {
  19706. public:
  19707. typedef column_selector_iterator_impl<InputIterator,N> csii_t;
  19708. typedef details::column_list_impl<N> column_list_t;
  19709. typedef std::pair<InputIterator,InputIterator> iterator_type;
  19710. typedef iterator_type* iterator_type_ptr;
  19711. column_selector_iterator_impl(const details::column_list_impl<N>& column_list,iterator_type (&token_list)[N])
  19712. : column_list_(column_list),
  19713. token_list_(token_list),
  19714. current_index_(0),
  19715. target_index_(column_list_.index_list[0]),
  19716. col_list_index_(0)
  19717. {}
  19718. inline csii_t& operator*()
  19719. {
  19720. return (*this);
  19721. }
  19722. inline csii_t& operator++()
  19723. {
  19724. return (*this);
  19725. }
  19726. inline csii_t operator++(int)
  19727. {
  19728. return (*this);
  19729. }
  19730. template <typename Iterator>
  19731. inline csii_t& operator=(const std::pair<Iterator,Iterator>& r)
  19732. {
  19733. if (current_index_ == target_index_)
  19734. {
  19735. token_list_[col_list_index_] = r;
  19736. ++col_list_index_;
  19737. if (col_list_index_ < column_list_t::size)
  19738. target_index_ = column_list_.index_list[col_list_index_];
  19739. else
  19740. target_index_ = std::numeric_limits<std::size_t>::max();
  19741. }
  19742. ++current_index_;
  19743. return (*this);
  19744. }
  19745. private:
  19746. csii_t& operator=(const csii_t& csb);
  19747. const column_list_t& column_list_;
  19748. iterator_type_ptr token_list_;
  19749. std::size_t current_index_;
  19750. std::size_t target_index_;
  19751. std::size_t col_list_index_;
  19752. };
  19753. }
  19754. #define strtk_parse_col_token(Index) \
  19755. if (!string_to_type_converter(token_list[Index].first,token_list[Index].second,t##Index)) return false;
  19756. #define strtk_parse_col_token_seq(Index) \
  19757. if (!string_to_type_converter(token_list[Index].first,token_list[Index].second,seq[Index])) return false;
  19758. #define strtk_parse_columns_impl(NN) \
  19759. static const std::size_t N = NN; \
  19760. typedef typename details::is_valid_iterator<InputIterator>::type itr_type; \
  19761. typedef std::pair<InputIterator,InputIterator> iterator_type; \
  19762. typedef details::column_selector_iterator_impl<InputIterator,N> csii_t; \
  19763. const std::size_t token_count = (column_list.index_list[N - 1] + 1); \
  19764. details::convert_type_assert<itr_type>(); \
  19765. iterator_type token_list[N]; \
  19766. csii_t csii(column_list,token_list); \
  19767. const std::size_t parsed_token_count = split_n<InputIterator,csii_t&> \
  19768. (delimiters,begin,end,token_count,csii,split_options::compress_delimiters);\
  19769. if (token_count > parsed_token_count) return false; \
  19770. #define strk_parse_col_seq \
  19771. return parse_columns(data.data(),data.data() + data.size(),delimiters,column_list,seq);
  19772. template <typename InputIterator,
  19773. typename T0, typename T1, typename T2, typename T3, typename T4,
  19774. typename T5, typename T6, typename T7, typename T8, typename T9,
  19775. typename T10, typename T11>
  19776. inline bool parse_columns(const InputIterator begin,
  19777. const InputIterator end,
  19778. const std::string& delimiters,
  19779. const details::column_list_impl<12>& column_list,
  19780. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19781. T6& t6, T7& t7, T8& t8, T9& t9, T10& t10, T11& t11)
  19782. {
  19783. strtk_parse_columns_impl(12)
  19784. strtk_parse_col_token( 0) strtk_parse_col_token( 1)
  19785. strtk_parse_col_token( 2) strtk_parse_col_token( 3)
  19786. strtk_parse_col_token( 4) strtk_parse_col_token( 5)
  19787. strtk_parse_col_token( 6) strtk_parse_col_token( 7)
  19788. strtk_parse_col_token( 8) strtk_parse_col_token( 9)
  19789. strtk_parse_col_token(10) strtk_parse_col_token(11)
  19790. return true;
  19791. }
  19792. template <typename InputIterator,
  19793. typename T0, typename T1, typename T2, typename T3, typename T4,
  19794. typename T5, typename T6, typename T7, typename T8, typename T9,
  19795. typename T10>
  19796. inline bool parse_columns(const InputIterator begin,
  19797. const InputIterator end,
  19798. const std::string& delimiters,
  19799. const details::column_list_impl<11>& column_list,
  19800. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19801. T6& t6, T7& t7, T8& t8, T9& t9, T10& t10)
  19802. {
  19803. strtk_parse_columns_impl(11)
  19804. strtk_parse_col_token( 0) strtk_parse_col_token(1)
  19805. strtk_parse_col_token( 2) strtk_parse_col_token(3)
  19806. strtk_parse_col_token( 4) strtk_parse_col_token(5)
  19807. strtk_parse_col_token( 6) strtk_parse_col_token(7)
  19808. strtk_parse_col_token( 8) strtk_parse_col_token(9)
  19809. strtk_parse_col_token(10)
  19810. return true;
  19811. }
  19812. template <typename InputIterator,
  19813. typename T0, typename T1, typename T2, typename T3, typename T4,
  19814. typename T5, typename T6, typename T7, typename T8, typename T9>
  19815. inline bool parse_columns(const InputIterator begin,
  19816. const InputIterator end,
  19817. const std::string& delimiters,
  19818. const details::column_list_impl<10>& column_list,
  19819. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  19820. T6& t6, T7& t7, T8& t8, T9& t9)
  19821. {
  19822. strtk_parse_columns_impl(10)
  19823. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19824. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19825. strtk_parse_col_token(4) strtk_parse_col_token(5)
  19826. strtk_parse_col_token(6) strtk_parse_col_token(7)
  19827. strtk_parse_col_token(8) strtk_parse_col_token(9)
  19828. return true;
  19829. }
  19830. template <typename InputIterator,
  19831. typename T0, typename T1, typename T2, typename T3, typename T4,
  19832. typename T5, typename T6, typename T7, typename T8>
  19833. inline bool parse_columns(const InputIterator begin,
  19834. const InputIterator end,
  19835. const std::string& delimiters,
  19836. const details::column_list_impl<9>& column_list,
  19837. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6,
  19838. T7& t7, T8& t8)
  19839. {
  19840. strtk_parse_columns_impl(9)
  19841. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19842. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19843. strtk_parse_col_token(4) strtk_parse_col_token(5)
  19844. strtk_parse_col_token(6) strtk_parse_col_token(7)
  19845. strtk_parse_col_token(8)
  19846. return true;
  19847. }
  19848. template <typename InputIterator,
  19849. typename T0, typename T1, typename T2, typename T3, typename T4,
  19850. typename T5, typename T6, typename T7>
  19851. inline bool parse_columns(const InputIterator begin,
  19852. const InputIterator end,
  19853. const std::string& delimiters,
  19854. const details::column_list_impl<8>& column_list,
  19855. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7)
  19856. {
  19857. strtk_parse_columns_impl(8)
  19858. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19859. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19860. strtk_parse_col_token(4) strtk_parse_col_token(5)
  19861. strtk_parse_col_token(6) strtk_parse_col_token(7)
  19862. return true;
  19863. }
  19864. template <typename InputIterator,
  19865. typename T0, typename T1, typename T2, typename T3, typename T4,
  19866. typename T5, typename T6>
  19867. inline bool parse_columns(const InputIterator begin,
  19868. const InputIterator end,
  19869. const std::string& delimiters,
  19870. const details::column_list_impl<7>& column_list,
  19871. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6)
  19872. {
  19873. strtk_parse_columns_impl(7)
  19874. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19875. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19876. strtk_parse_col_token(4) strtk_parse_col_token(5)
  19877. strtk_parse_col_token(6)
  19878. return true;
  19879. }
  19880. template <typename InputIterator,
  19881. typename T0, typename T1, typename T2, typename T3, typename T4,
  19882. typename T5>
  19883. inline bool parse_columns(const InputIterator begin,
  19884. const InputIterator end,
  19885. const std::string& delimiters,
  19886. const details::column_list_impl<6>& column_list,
  19887. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5)
  19888. {
  19889. strtk_parse_columns_impl(6)
  19890. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19891. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19892. strtk_parse_col_token(4) strtk_parse_col_token(5)
  19893. return true;
  19894. }
  19895. template <typename InputIterator,
  19896. typename T0, typename T1, typename T2, typename T3, typename T4>
  19897. inline bool parse_columns(const InputIterator begin,
  19898. const InputIterator end,
  19899. const std::string& delimiters,
  19900. const details::column_list_impl<5>& column_list,
  19901. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4)
  19902. {
  19903. strtk_parse_columns_impl(5)
  19904. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19905. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19906. strtk_parse_col_token(4)
  19907. return true;
  19908. }
  19909. template <typename InputIterator,
  19910. typename T0, typename T1, typename T2, typename T3>
  19911. inline bool parse_columns(const InputIterator begin,
  19912. const InputIterator end,
  19913. const std::string& delimiters,
  19914. const details::column_list_impl<4>& column_list,
  19915. T0& t0, T1& t1, T2& t2, T3& t3)
  19916. {
  19917. strtk_parse_columns_impl(4)
  19918. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19919. strtk_parse_col_token(2) strtk_parse_col_token(3)
  19920. return true;
  19921. }
  19922. template <typename InputIterator,
  19923. typename T0, typename T1, typename T2>
  19924. inline bool parse_columns(const InputIterator begin,
  19925. const InputIterator end,
  19926. const std::string& delimiters,
  19927. const details::column_list_impl<3>& column_list,
  19928. T0& t0, T1& t1, T2& t2)
  19929. {
  19930. strtk_parse_columns_impl(3)
  19931. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19932. strtk_parse_col_token(2)
  19933. return true;
  19934. }
  19935. template <typename InputIterator,
  19936. typename T0, typename T1>
  19937. inline bool parse_columns(const InputIterator begin,
  19938. const InputIterator end,
  19939. const std::string& delimiters,
  19940. const details::column_list_impl<2>& column_list,
  19941. T0& t0, T1& t1)
  19942. {
  19943. strtk_parse_columns_impl(2)
  19944. strtk_parse_col_token(0) strtk_parse_col_token(1)
  19945. return true;
  19946. }
  19947. template <typename InputIterator,
  19948. typename T0>
  19949. inline bool parse_columns(const InputIterator begin,
  19950. const InputIterator end,
  19951. const std::string& delimiters,
  19952. const details::column_list_impl<1>& column_list,
  19953. T0& t0)
  19954. {
  19955. strtk_parse_columns_impl(1)
  19956. strtk_parse_col_token(0)
  19957. return true;
  19958. }
  19959. template <typename InputIterator,
  19960. typename T,
  19961. typename Allocator,
  19962. template <typename,typename> class Sequence>
  19963. inline bool parse_columns(const InputIterator begin,
  19964. const InputIterator end,
  19965. const std::string& delimiters,
  19966. const details::column_list_impl<12>& column_list,
  19967. Sequence<T,Allocator>& seq)
  19968. {
  19969. strtk_parse_columns_impl(12)
  19970. strtk_parse_col_token_seq( 0) strtk_parse_col_token_seq( 1)
  19971. strtk_parse_col_token_seq( 2) strtk_parse_col_token_seq( 3)
  19972. strtk_parse_col_token_seq( 4) strtk_parse_col_token_seq( 5)
  19973. strtk_parse_col_token_seq( 6) strtk_parse_col_token_seq( 7)
  19974. strtk_parse_col_token_seq( 8) strtk_parse_col_token_seq( 9)
  19975. strtk_parse_col_token_seq(10) strtk_parse_col_token_seq(11)
  19976. return true;
  19977. }
  19978. template <typename InputIterator,
  19979. typename T,
  19980. typename Allocator,
  19981. template <typename,typename> class Sequence>
  19982. inline bool parse_columns(const InputIterator begin,
  19983. const InputIterator end,
  19984. const std::string& delimiters,
  19985. const details::column_list_impl<11>& column_list,
  19986. Sequence<T,Allocator>& seq)
  19987. {
  19988. strtk_parse_columns_impl(11)
  19989. strtk_parse_col_token_seq( 0) strtk_parse_col_token_seq(1)
  19990. strtk_parse_col_token_seq( 2) strtk_parse_col_token_seq(3)
  19991. strtk_parse_col_token_seq( 4) strtk_parse_col_token_seq(5)
  19992. strtk_parse_col_token_seq( 6) strtk_parse_col_token_seq(7)
  19993. strtk_parse_col_token_seq( 8) strtk_parse_col_token_seq(9)
  19994. strtk_parse_col_token_seq(10)
  19995. return true;
  19996. }
  19997. template <typename InputIterator,
  19998. typename T,
  19999. typename Allocator,
  20000. template <typename,typename> class Sequence>
  20001. inline bool parse_columns(const InputIterator begin,
  20002. const InputIterator end,
  20003. const std::string& delimiters,
  20004. const details::column_list_impl<10>& column_list,
  20005. Sequence<T,Allocator>& seq)
  20006. {
  20007. strtk_parse_columns_impl(10)
  20008. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  20009. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  20010. strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5)
  20011. strtk_parse_col_token_seq(6) strtk_parse_col_token_seq(7)
  20012. strtk_parse_col_token_seq(8) strtk_parse_col_token_seq(9)
  20013. return true;
  20014. }
  20015. template <typename InputIterator,
  20016. typename T,
  20017. typename Allocator,
  20018. template <typename,typename> class Sequence>
  20019. inline bool parse_columns(const InputIterator begin,
  20020. const InputIterator end,
  20021. const std::string& delimiters,
  20022. const details::column_list_impl<9>& column_list,
  20023. Sequence<T,Allocator>& seq)
  20024. {
  20025. strtk_parse_columns_impl(9)
  20026. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  20027. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  20028. strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5)
  20029. strtk_parse_col_token_seq(6) strtk_parse_col_token_seq(7)
  20030. strtk_parse_col_token_seq(8)
  20031. return true;
  20032. }
  20033. template <typename InputIterator,
  20034. typename T,
  20035. typename Allocator,
  20036. template <typename,typename> class Sequence>
  20037. inline bool parse_columns(const InputIterator begin,
  20038. const InputIterator end,
  20039. const std::string& delimiters,
  20040. const details::column_list_impl<8>& column_list,
  20041. Sequence<T,Allocator>& seq)
  20042. {
  20043. strtk_parse_columns_impl(8)
  20044. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  20045. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  20046. strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5)
  20047. strtk_parse_col_token_seq(6) strtk_parse_col_token_seq(7)
  20048. return true;
  20049. }
  20050. template <typename InputIterator,
  20051. typename T,
  20052. typename Allocator,
  20053. template <typename,typename> class Sequence>
  20054. inline bool parse_columns(const InputIterator begin,
  20055. const InputIterator end,
  20056. const std::string& delimiters,
  20057. const details::column_list_impl<7>& column_list,
  20058. Sequence<T,Allocator>& seq)
  20059. {
  20060. strtk_parse_columns_impl(7)
  20061. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  20062. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  20063. strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5)
  20064. strtk_parse_col_token_seq(6)
  20065. return true;
  20066. }
  20067. template <typename InputIterator,
  20068. typename T,
  20069. typename Allocator,
  20070. template <typename,typename> class Sequence>
  20071. inline bool parse_columns(const InputIterator begin,
  20072. const InputIterator end,
  20073. const std::string& delimiters,
  20074. const details::column_list_impl<6>& column_list,
  20075. Sequence<T,Allocator>& seq)
  20076. {
  20077. strtk_parse_columns_impl(6)
  20078. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  20079. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  20080. strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5)
  20081. return true;
  20082. }
  20083. template <typename InputIterator,
  20084. typename T,
  20085. typename Allocator,
  20086. template <typename,typename> class Sequence>
  20087. inline bool parse_columns(const InputIterator begin,
  20088. const InputIterator end,
  20089. const std::string& delimiters,
  20090. const details::column_list_impl<5>& column_list,
  20091. Sequence<T,Allocator>& seq)
  20092. {
  20093. strtk_parse_columns_impl(5)
  20094. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  20095. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  20096. strtk_parse_col_token_seq(4)
  20097. return true;
  20098. }
  20099. template <typename InputIterator,
  20100. typename T,
  20101. typename Allocator,
  20102. template <typename,typename> class Sequence>
  20103. inline bool parse_columns(const InputIterator begin,
  20104. const InputIterator end,
  20105. const std::string& delimiters,
  20106. const details::column_list_impl<4>& column_list,
  20107. Sequence<T,Allocator>& seq)
  20108. {
  20109. strtk_parse_columns_impl(4)
  20110. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  20111. strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3)
  20112. return true;
  20113. }
  20114. template <typename InputIterator,
  20115. typename T,
  20116. typename Allocator,
  20117. template <typename,typename> class Sequence>
  20118. inline bool parse_columns(const InputIterator begin,
  20119. const InputIterator end,
  20120. const std::string& delimiters,
  20121. const details::column_list_impl<3>& column_list,
  20122. Sequence<T,Allocator>& seq)
  20123. {
  20124. strtk_parse_columns_impl(3)
  20125. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  20126. strtk_parse_col_token_seq(2)
  20127. return true;
  20128. }
  20129. template <typename InputIterator,
  20130. typename T,
  20131. typename Allocator,
  20132. template <typename,typename> class Sequence>
  20133. inline bool parse_columns(const InputIterator begin,
  20134. const InputIterator end,
  20135. const std::string& delimiters,
  20136. const details::column_list_impl<2>& column_list,
  20137. Sequence<T,Allocator>& seq)
  20138. {
  20139. strtk_parse_columns_impl(2)
  20140. strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1)
  20141. return true;
  20142. }
  20143. template <typename InputIterator,
  20144. typename T,
  20145. typename Allocator,
  20146. template <typename,typename> class Sequence>
  20147. inline bool parse_columns(const InputIterator begin,
  20148. const InputIterator end,
  20149. const std::string& delimiters,
  20150. const details::column_list_impl<1>& column_list,
  20151. Sequence<T,Allocator>& seq)
  20152. {
  20153. strtk_parse_columns_impl(1)
  20154. strtk_parse_col_token_seq(0)
  20155. return true;
  20156. }
  20157. #undef strtk_parse_col_token
  20158. #undef strtk_parse_col_token_seq
  20159. #undef strtk_parse_columns_impl
  20160. #define strtk_parse_col_begin() \
  20161. return parse_columns(data.data(), \
  20162. data.data() + data.size(),delimiters,\
  20163. column_list, \
  20164. #define strtk_parse_col_end() );
  20165. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  20166. typename T5, typename T6, typename T7, typename T8, typename T9,
  20167. typename T10, typename T11>
  20168. inline bool parse_columns(const std::string& data,
  20169. const std::string& delimiters,
  20170. const details::column_list_impl<12>& column_list,
  20171. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  20172. T5& t5, T6& t6, T7& t7, T8& t8, T9& t9,
  20173. T10& t10, T11& t11)
  20174. {
  20175. strtk_parse_col_begin()
  20176. t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11
  20177. strtk_parse_col_end()
  20178. }
  20179. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  20180. typename T5, typename T6, typename T7, typename T8, typename T9,
  20181. typename T10>
  20182. inline bool parse_columns(const std::string& data,
  20183. const std::string& delimiters,
  20184. const details::column_list_impl<11>& column_list,
  20185. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  20186. T5& t5, T6& t6, T7& t7, T8& t8, T9& t9,
  20187. T10& t10)
  20188. {
  20189. strtk_parse_col_begin()
  20190. t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10
  20191. strtk_parse_col_end()
  20192. }
  20193. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  20194. typename T5, typename T6, typename T7, typename T8, typename T9>
  20195. inline bool parse_columns(const std::string& data,
  20196. const std::string& delimiters,
  20197. const details::column_list_impl<10>& column_list,
  20198. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  20199. T5& t5, T6& t6, T7& t7, T8& t8,
  20200. T9& t9)
  20201. {
  20202. strtk_parse_col_begin()
  20203. t0,t1,t2,t3,t4,t5,t6,t7,t8,t9
  20204. strtk_parse_col_end()
  20205. }
  20206. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  20207. typename T5, typename T6, typename T7, typename T8>
  20208. inline bool parse_columns(const std::string& data,
  20209. const std::string& delimiters,
  20210. const details::column_list_impl<9>& column_list,
  20211. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  20212. T5& t5, T6& t6, T7& t7, T8& t8)
  20213. {
  20214. strtk_parse_col_begin()
  20215. t0,t1,t2,t3,t4,t5,t6,t7,t8
  20216. strtk_parse_col_end()
  20217. }
  20218. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  20219. typename T5, typename T6, typename T7>
  20220. inline bool parse_columns(const std::string& data,
  20221. const std::string& delimiters,
  20222. const details::column_list_impl<8>& column_list,
  20223. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  20224. T5& t5, T6& t6, T7& t7)
  20225. {
  20226. strtk_parse_col_begin()
  20227. t0,t1,t2,t3,t4,t5,t6,t7
  20228. strtk_parse_col_end()
  20229. }
  20230. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  20231. typename T5, typename T6>
  20232. inline bool parse_columns(const std::string& data,
  20233. const std::string& delimiters,
  20234. const details::column_list_impl<7>& column_list,
  20235. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  20236. T5& t5, T6& t6)
  20237. {
  20238. strtk_parse_col_begin()
  20239. t0,t1,t2,t3,t4,t5,t6
  20240. strtk_parse_col_end()
  20241. }
  20242. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  20243. typename T5>
  20244. inline bool parse_columns(const std::string& data,
  20245. const std::string& delimiters,
  20246. const details::column_list_impl<6>& column_list,
  20247. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4,
  20248. T5& t5)
  20249. {
  20250. strtk_parse_col_begin()
  20251. t0,t1,t2,t3,t4,t5
  20252. strtk_parse_col_end()
  20253. }
  20254. template <typename T0, typename T1, typename T2, typename T3, typename T4>
  20255. inline bool parse_columns(const std::string& data,
  20256. const std::string& delimiters,
  20257. const details::column_list_impl<5>& column_list,
  20258. T0& t0, T1& t1, T2& t2, T3& t3, T4& t4)
  20259. {
  20260. strtk_parse_col_begin()
  20261. t0,t1,t2,t3,t4
  20262. strtk_parse_col_end()
  20263. }
  20264. template <typename T0, typename T1, typename T2, typename T3>
  20265. inline bool parse_columns(const std::string& data,
  20266. const std::string& delimiters,
  20267. const details::column_list_impl<4>& column_list,
  20268. T0& t0, T1& t1, T2& t2, T3& t3)
  20269. {
  20270. strtk_parse_col_begin()
  20271. t0,t1,t2,t3
  20272. strtk_parse_col_end();
  20273. }
  20274. template <typename T0, typename T1, typename T2>
  20275. inline bool parse_columns(const std::string& data,
  20276. const std::string& delimiters,
  20277. const details::column_list_impl<3>& column_list,
  20278. T0& t0, T1& t1, T2& t2)
  20279. {
  20280. strtk_parse_col_begin()
  20281. t0,t1,t2
  20282. strtk_parse_col_end()
  20283. }
  20284. template <typename T0, typename T1>
  20285. inline bool parse_columns(const std::string& data,
  20286. const std::string& delimiters,
  20287. const details::column_list_impl<2>& column_list,
  20288. T0& t0, T1& t1)
  20289. {
  20290. strtk_parse_col_begin()
  20291. t0,t1
  20292. strtk_parse_col_end()
  20293. }
  20294. template <typename T>
  20295. inline bool parse_columns(const std::string& data,
  20296. const std::string& delimiters,
  20297. const details::column_list_impl<1>& column_list,
  20298. T& t)
  20299. {
  20300. strtk_parse_col_begin()
  20301. t
  20302. strtk_parse_col_end()
  20303. }
  20304. #undef strtk_parse_col_begin
  20305. #undef strtk_parse_col_end
  20306. template <typename T,
  20307. typename Allocator,
  20308. template <typename,typename> class Sequence>
  20309. inline bool parse_columns(const std::string& data,
  20310. const std::string& delimiters,
  20311. const details::column_list_impl<12>& column_list,
  20312. Sequence<T,Allocator>& seq)
  20313. {
  20314. strk_parse_col_seq
  20315. }
  20316. template <typename T,
  20317. typename Allocator,
  20318. template <typename,typename> class Sequence>
  20319. inline bool parse_columns(const std::string& data,
  20320. const std::string& delimiters,
  20321. const details::column_list_impl<11>& column_list,
  20322. Sequence<T,Allocator>& seq)
  20323. {
  20324. strk_parse_col_seq
  20325. }
  20326. template <typename T,
  20327. typename Allocator,
  20328. template <typename,typename> class Sequence>
  20329. inline bool parse_columns(const std::string& data,
  20330. const std::string& delimiters,
  20331. const details::column_list_impl<10>& column_list,
  20332. Sequence<T,Allocator>& seq)
  20333. {
  20334. strk_parse_col_seq
  20335. }
  20336. template <typename T,
  20337. typename Allocator,
  20338. template <typename,typename> class Sequence>
  20339. inline bool parse_columns(const std::string& data,
  20340. const std::string& delimiters,
  20341. const details::column_list_impl<9>& column_list,
  20342. Sequence<T,Allocator>& seq)
  20343. {
  20344. strk_parse_col_seq
  20345. }
  20346. template <typename T,
  20347. typename Allocator,
  20348. template <typename,typename> class Sequence>
  20349. inline bool parse_columns(const std::string& data,
  20350. const std::string& delimiters,
  20351. const details::column_list_impl<8>& column_list,
  20352. Sequence<T,Allocator>& seq)
  20353. {
  20354. strk_parse_col_seq
  20355. }
  20356. template <typename T,
  20357. typename Allocator,
  20358. template <typename,typename> class Sequence>
  20359. inline bool parse_columns(const std::string& data,
  20360. const std::string& delimiters,
  20361. const details::column_list_impl<7>& column_list,
  20362. Sequence<T,Allocator>& seq)
  20363. {
  20364. strk_parse_col_seq
  20365. }
  20366. template <typename T,
  20367. typename Allocator,
  20368. template <typename,typename> class Sequence>
  20369. inline bool parse_columns(const std::string& data,
  20370. const std::string& delimiters,
  20371. const details::column_list_impl<6>& column_list,
  20372. Sequence<T,Allocator>& seq)
  20373. {
  20374. strk_parse_col_seq
  20375. }
  20376. template <typename T,
  20377. typename Allocator,
  20378. template <typename,typename> class Sequence>
  20379. inline bool parse_columns(const std::string& data,
  20380. const std::string& delimiters,
  20381. const details::column_list_impl<5>& column_list,
  20382. Sequence<T,Allocator>& seq)
  20383. {
  20384. strk_parse_col_seq
  20385. }
  20386. template <typename T,
  20387. typename Allocator,
  20388. template <typename,typename> class Sequence>
  20389. inline bool parse_columns(const std::string& data,
  20390. const std::string& delimiters,
  20391. const details::column_list_impl<4>& column_list,
  20392. Sequence<T,Allocator>& seq)
  20393. {
  20394. strk_parse_col_seq
  20395. }
  20396. template <typename T,
  20397. typename Allocator,
  20398. template <typename,typename> class Sequence>
  20399. inline bool parse_columns(const std::string& data,
  20400. const std::string& delimiters,
  20401. const details::column_list_impl<3>& column_list,
  20402. Sequence<T,Allocator>& seq)
  20403. {
  20404. strk_parse_col_seq
  20405. }
  20406. template <typename T,
  20407. typename Allocator,
  20408. template <typename,typename> class Sequence>
  20409. inline bool parse_columns(const std::string& data,
  20410. const std::string& delimiters,
  20411. const details::column_list_impl<2>& column_list,
  20412. Sequence<T,Allocator>& seq)
  20413. {
  20414. strk_parse_col_seq
  20415. }
  20416. template <typename T,
  20417. typename Allocator,
  20418. template <typename,typename> class Sequence>
  20419. inline bool parse_columns(const std::string& data,
  20420. const std::string& delimiters,
  20421. const details::column_list_impl<1>& column_list,
  20422. Sequence<T,Allocator>& seq)
  20423. {
  20424. strk_parse_col_seq
  20425. }
  20426. #undef strk_parse_col_seq
  20427. namespace details
  20428. {
  20429. typedef const unsigned char* ptr;
  20430. template <typename T>
  20431. bool cmpimpl(ptr c1, ptr c2) { return (*reinterpret_cast<T>(c1)) == (*reinterpret_cast<T>(c2)); }
  20432. template <std::size_t K>
  20433. struct size_impl { static inline bool cmp(ptr,ptr) { return true; } };
  20434. template <>
  20435. struct size_impl<8> { static inline bool cmp(ptr c1, ptr c2) { return cmpimpl<const unsigned long long*>(c1,c2); } };
  20436. template <>
  20437. struct size_impl<4> { static inline bool cmp(ptr c1, ptr c2) { return cmpimpl<const unsigned int*>(c1,c2); } };
  20438. template <>
  20439. struct size_impl<2> { static inline bool cmp(ptr c1, ptr c2) { return cmpimpl<const unsigned short*>(c1,c2); } };
  20440. template <>
  20441. struct size_impl<1> { static inline bool cmp(ptr c1, ptr c2) { return cmpimpl<const unsigned char*>(c1,c2); } };
  20442. template <std::size_t N>
  20443. struct next_size { enum { size = (N >= 8) ? 8 : ((N >= 4) ? 4 : ((N >= 2) ? 2 : 1)) }; };
  20444. template <std::size_t N>
  20445. struct memcmp_n_impl
  20446. {
  20447. static inline bool process(details::ptr c1, details::ptr c2)
  20448. {
  20449. static const std::size_t size = details::next_size<N>::size;
  20450. return details::size_impl<size>::cmp(c1,c2) && memcmp_n_impl<N - size>::process(c1 + size, c2 + size);
  20451. }
  20452. static inline bool process(const char* c1, const char* c2)
  20453. {
  20454. return memcmp_n_impl<N>::process(reinterpret_cast<details::ptr>(c1),reinterpret_cast<details::ptr>(c2));
  20455. }
  20456. template <std::size_t K1, std::size_t K2>
  20457. static inline bool process(const unsigned char (&c1)[K1], const unsigned char (&c2)[K2])
  20458. {
  20459. return memcmp_n_impl<N>::process(static_cast<ptr>(c1),static_cast<ptr>(c2));
  20460. }
  20461. };
  20462. template<> struct memcmp_n_impl<0> { static inline bool process(ptr,ptr) { return true; } };
  20463. }
  20464. template <std::size_t N>
  20465. inline bool memcmp_n(details::ptr c1, details::ptr c2)
  20466. {
  20467. return details::memcmp_n_impl<N>::process(c1,c2);
  20468. }
  20469. template <std::size_t N>
  20470. inline bool memcmp_n(const char* c1, const char* c2)
  20471. {
  20472. return details::memcmp_n_impl<N>::process(c1,c2);
  20473. }
  20474. template <std::size_t N,std::size_t K1, std::size_t K2>
  20475. inline bool memcmp_n(const unsigned char (&c1)[K1], const unsigned char (&c2)[K2])
  20476. {
  20477. return details::memcmp_n_impl<N>::process(c1,c2);
  20478. }
  20479. namespace details
  20480. {
  20481. inline bool type_to_string_converter_impl(const strtk::util::value& v, std::string& result, value_type_tag)
  20482. {
  20483. return v.to_string(result);
  20484. }
  20485. }
  20486. template <typename Iterator>
  20487. inline std::size_t distance(const std::pair<Iterator,Iterator>& p)
  20488. {
  20489. return std::distance(p.first,p.second);
  20490. }
  20491. template <typename Iterator1, typename Iterator2>
  20492. inline std::pair<Iterator1,Iterator2> make_pair(const std::string& s)
  20493. {
  20494. return std::make_pair<Iterator1,Iterator2>(
  20495. reinterpret_cast<Iterator1>(const_cast<char*>(s.data())),
  20496. reinterpret_cast<Iterator2>(const_cast<char*>(s.data() + s.size())));
  20497. }
  20498. template <typename Iterator1, typename Iterator2>
  20499. inline std::pair<Iterator1,Iterator2> make_pair(const std::pair<const char*, const char*> p)
  20500. {
  20501. return std::make_pair<Iterator1,Iterator2>(
  20502. reinterpret_cast<Iterator1>(const_cast<char*>(p.first)),
  20503. reinterpret_cast<Iterator2>(const_cast<char*>(p.second)));
  20504. }
  20505. template <typename Iterator>
  20506. inline std::pair<Iterator,Iterator> make_pair(const std::string& s)
  20507. {
  20508. return make_pair<Iterator,Iterator>(s);
  20509. }
  20510. template <typename Iterator>
  20511. inline std::pair<Iterator,Iterator> make_pair(const std::pair<const char*, const char*>& p)
  20512. {
  20513. return make_pair<Iterator,Iterator>(p);
  20514. }
  20515. template <typename Iterator1, typename Iterator2>
  20516. inline std::pair<Iterator1,Iterator2> make_pair(const strtk::range::string& range)
  20517. {
  20518. return std::make_pair<Iterator1,Iterator2>(
  20519. reinterpret_cast<Iterator1>(const_cast<char*>(range.begin())),
  20520. reinterpret_cast<Iterator2>(const_cast<char*>(range.end())));
  20521. }
  20522. template <std::size_t N>
  20523. inline std::string make_string(const unsigned char (&s)[N], const std::size_t& length = N)
  20524. {
  20525. static const std::string null_string;
  20526. if (N < length)
  20527. return null_string;
  20528. else
  20529. return std::string(&s[0],&s[0] + length);
  20530. }
  20531. template <std::size_t N>
  20532. inline std::string make_string(const char (&s)[N], const std::size_t& length = N)
  20533. {
  20534. static const std::string null_string;
  20535. if (N < length)
  20536. return null_string;
  20537. else
  20538. return std::string(&s[0],&s[0] + length);
  20539. }
  20540. inline std::string make_string(const std::pair<const char*,const char*>& range)
  20541. {
  20542. return std::string(range.first,range.second);
  20543. }
  20544. template <typename T, std::size_t N>
  20545. inline bool clear_array(T (&a)[N], const T& t, const std::size_t& length = N)
  20546. {
  20547. if (N < length)
  20548. return false;
  20549. else
  20550. std::fill_n(&a[0],length,t);
  20551. return true;
  20552. }
  20553. template <std::size_t N>
  20554. inline bool set_array(unsigned char (&a)[N],
  20555. const std::string& s,
  20556. const bool pad = false,
  20557. const unsigned char padding = '0')
  20558. {
  20559. if (N < s.size())
  20560. return false;
  20561. std::copy(s.data(),s.data() + s.size(), &a[0]);
  20562. if ((s.size() < N) && pad)
  20563. std::fill_n(&a[s.size()],N - s.size(),padding);
  20564. return true;
  20565. }
  20566. template <std::size_t N, std::size_t M>
  20567. inline bool set_array(unsigned char (&dest)[N],
  20568. unsigned char (&src)[M],
  20569. const bool pad = false,
  20570. const unsigned char padding = '0')
  20571. {
  20572. if (N < M)
  20573. return false;
  20574. std::copy(src,src + N, &dest[0]);
  20575. if ((M < N) && pad)
  20576. std::fill_n(&dest[M],N - M,padding);
  20577. return true;
  20578. }
  20579. inline void reverse(const std_string::iterator_type& range)
  20580. {
  20581. char* begin = const_cast<char*>(range.first);
  20582. char* end = const_cast<char*>(range.second);
  20583. std::reverse(begin,end);
  20584. }
  20585. template <typename T>
  20586. inline void reverse(const range::adapter<T>& r)
  20587. {
  20588. T* begin = const_cast<T*>(r.begin());
  20589. T* end = const_cast<T*>(r.end());
  20590. std::reverse(begin,end);
  20591. }
  20592. template <typename T>
  20593. inline void reverse(const range::adapter<const T>& r)
  20594. {
  20595. T* begin = const_cast<T*>(r.begin());
  20596. T* end = const_cast<T*>(r.end());
  20597. std::reverse(begin,end);
  20598. }
  20599. inline void reverse(std::string& s)
  20600. {
  20601. std::reverse(s.begin(),s.end());
  20602. }
  20603. inline void fill(std::string& s, const std::string::value_type v)
  20604. {
  20605. std::fill(const_cast<char*>(s.data()),const_cast<char*>(s.data() + s.size()), v);
  20606. }
  20607. inline void fill(const std::pair<const char*,const char*>& range, char v)
  20608. {
  20609. char* begin = const_cast<char*>(range.first);
  20610. char* end = const_cast<char*>(range.second);
  20611. std::fill(begin,end,v);
  20612. }
  20613. template <typename T>
  20614. inline void fill(const range::adapter<const T>& r, const typename range::adapter<const T>::value_type& v)
  20615. {
  20616. char* begin = const_cast<char*>(r.begin());
  20617. char* end = const_cast<char*>(r.end());
  20618. std::fill(begin,end,v);
  20619. }
  20620. inline void fill(const std_string::iterator_type& range, const std::string::value_type& v)
  20621. {
  20622. char* begin = const_cast<char*>(range.first);
  20623. char* end = const_cast<char*>(range.second);
  20624. std::fill(begin,end,v);
  20625. }
  20626. template <typename T,
  20627. typename Allocator,
  20628. template <typename,typename> class Sequence>
  20629. inline void fill(Sequence<T,Allocator>& seq, const T& t)
  20630. {
  20631. if (seq.empty())
  20632. return;
  20633. std::fill_n(seq.begin(),seq.size(),t);
  20634. }
  20635. namespace keyvalue
  20636. {
  20637. template <typename CharType>
  20638. struct options
  20639. {
  20640. typedef CharType char_type;
  20641. options()
  20642. : pair_block_delimiter(0),
  20643. pair_delimiter(0)
  20644. {}
  20645. char_type pair_block_delimiter;
  20646. char_type pair_delimiter;
  20647. };
  20648. template <typename KeyValueMap>
  20649. class parser
  20650. {
  20651. public:
  20652. typedef unsigned char char_type;
  20653. typedef std::pair<char_type*,char_type*> range_type;
  20654. template <typename Options>
  20655. parser(const Options& opts)
  20656. : options_(opts),
  20657. parse_failures_(0),
  20658. kv_map_(opts),
  20659. pair_block_sdp_(options_.pair_block_delimiter),
  20660. pair_delimiter_sdp_(options_.pair_delimiter)
  20661. {
  20662. const std::size_t pair_list_default_size = 32;
  20663. pair_list_.reserve(pair_list_default_size);
  20664. }
  20665. template <typename T>
  20666. inline bool register_keyvalue(const typename KeyValueMap::key_type& key, T& t)
  20667. {
  20668. return kv_map_.register_keyvalue(key,t);
  20669. }
  20670. inline bool operator()(const range_type& data, const bool ignore_failures = false)
  20671. {
  20672. if (!ignore_failures)
  20673. {
  20674. pair_list_.clear();
  20675. const std::size_t pair_count = split(pair_block_sdp_,
  20676. data.first,
  20677. data.second,
  20678. std::back_inserter(pair_list_));
  20679. if (0 == pair_count)
  20680. return false;
  20681. range_type key_range;
  20682. range_type value_range;
  20683. for (std::size_t i = 0; i < pair_count; ++i)
  20684. {
  20685. const range_type& r = pair_list_[i];
  20686. if (0 == std::distance(r.first,r.second))
  20687. continue;
  20688. else if (!split_pair(r.first,r.second,
  20689. pair_delimiter_sdp_,
  20690. key_range,value_range))
  20691. return false;
  20692. else if (!kv_map_(key_range,value_range))
  20693. return false;
  20694. }
  20695. return true;
  20696. }
  20697. else
  20698. {
  20699. parse_failures_ = 0;
  20700. pair_token_processor processor(*this);
  20701. split(pair_block_sdp_,
  20702. data.first,
  20703. data.second,
  20704. strtk::functional_inserter(processor));
  20705. return true;
  20706. }
  20707. }
  20708. inline bool operator()(const std::string& s, const bool ignore_failures = false)
  20709. {
  20710. return operator()(strtk::make_pair<range_type::first_type>(s),ignore_failures);
  20711. }
  20712. inline std::size_t failure_count() const
  20713. {
  20714. return parse_failures_;
  20715. }
  20716. private:
  20717. class pair_token_processor
  20718. {
  20719. public:
  20720. pair_token_processor(parser<KeyValueMap>& p)
  20721. : parser_(p)
  20722. {}
  20723. inline void operator()(const range_type& r)
  20724. {
  20725. if (r.first == r.second)
  20726. return;
  20727. if (split_pair(r.first,r.second,
  20728. parser_.pair_delimiter_sdp_,
  20729. key_range,
  20730. value_range))
  20731. {
  20732. if (parser_.kv_map_(key_range,value_range))
  20733. return;
  20734. }
  20735. ++parser_.parse_failures_;
  20736. }
  20737. private:
  20738. pair_token_processor operator=(const pair_token_processor&);
  20739. parser<KeyValueMap>& parser_;
  20740. range_type key_range;
  20741. range_type value_range;
  20742. };
  20743. options<char_type> options_;
  20744. std::size_t parse_failures_;
  20745. KeyValueMap kv_map_;
  20746. single_delimiter_predicate<char_type> pair_block_sdp_;
  20747. single_delimiter_predicate<char_type> pair_delimiter_sdp_;
  20748. std::vector<range_type> pair_list_;
  20749. };
  20750. class uintkey_map
  20751. {
  20752. private:
  20753. typedef unsigned char char_type;
  20754. typedef strtk::keyvalue::options<char_type> general_options;
  20755. public:
  20756. typedef unsigned int key_type;
  20757. struct options : public general_options
  20758. {
  20759. options()
  20760. : general_options(),
  20761. key_count(0)
  20762. {}
  20763. std::size_t key_count;
  20764. };
  20765. template <typename Options>
  20766. uintkey_map(const Options& options)
  20767. {
  20768. value_lut_.resize(options.key_count,strtk::util::value());
  20769. }
  20770. virtual ~uintkey_map()
  20771. {}
  20772. template <typename Range>
  20773. inline bool operator()(const Range& key_range, const Range& value_range)
  20774. {
  20775. std::size_t key = 0;
  20776. if (!fast::numeric_convert(distance(key_range),key_range.first,key,true))
  20777. return false;
  20778. if (key >= value_lut_.size())
  20779. return false;
  20780. const strtk::util::value& v = value_lut_[key];
  20781. if (!v)
  20782. return false;
  20783. else
  20784. return v(value_range);
  20785. }
  20786. template <typename T>
  20787. inline bool register_keyvalue(const key_type& key, T& t)
  20788. {
  20789. if (key < value_lut_.size())
  20790. {
  20791. strtk::util::value& v = value_lut_[key];
  20792. if (!v)
  20793. v = strtk::util::value(t);
  20794. else
  20795. v.assign(t);
  20796. return true;
  20797. }
  20798. else
  20799. return false;
  20800. }
  20801. private:
  20802. std::vector<strtk::util::value> value_lut_;
  20803. };
  20804. namespace details
  20805. {
  20806. template <typename Range,typename KType>
  20807. struct keygen
  20808. {
  20809. static inline KType transform(const Range&)
  20810. {
  20811. return KType();
  20812. }
  20813. };
  20814. template <typename Range>
  20815. struct keygen<Range,std::string>
  20816. {
  20817. static inline std::string transform(const Range& key_range)
  20818. {
  20819. return std::string(key_range.first,key_range.second);
  20820. }
  20821. };
  20822. template <typename Range>
  20823. struct keygen<Range,unsigned int>
  20824. {
  20825. static inline unsigned int transform(const Range& key_range)
  20826. {
  20827. unsigned int result = 0;
  20828. if (strtk::fast::numeric_convert(std::distance(key_range.first,key_range.second),key_range.first,result,true))
  20829. return result;
  20830. else
  20831. return std::numeric_limits<unsigned int>::max();
  20832. }
  20833. };
  20834. struct no_op_validator
  20835. {
  20836. template <typename Range>
  20837. inline bool operator()(const Range&)
  20838. {
  20839. return true;
  20840. }
  20841. };
  20842. }
  20843. template <typename KeyType,
  20844. typename MapType = std::map<KeyType,strtk::util::value>,
  20845. typename KeyValidator = details::no_op_validator,
  20846. typename ValueValidator = details::no_op_validator>
  20847. class key_map
  20848. {
  20849. public:
  20850. typedef KeyType key_type;
  20851. typedef MapType map_type;
  20852. typedef KeyValidator key_validator_type;
  20853. typedef ValueValidator value_validator_type;
  20854. template <typename Options>
  20855. key_map(const Options&)
  20856. {}
  20857. virtual ~key_map()
  20858. {}
  20859. template <typename Range>
  20860. inline bool operator()(const Range& key_range, const Range& value_range)
  20861. {
  20862. if (!key_validator_(key_range))
  20863. return false;
  20864. if (!val_validator_(value_range))
  20865. return false;
  20866. typename map_type::iterator itr = value_map_.find(details::keygen<Range,key_type>::transform(key_range));
  20867. if (value_map_.end() == itr)
  20868. return false;
  20869. const util::value& v = (*itr).second;
  20870. if (!v)
  20871. return false;
  20872. else
  20873. return v(value_range);
  20874. }
  20875. template <typename T>
  20876. inline bool register_keyvalue(const key_type& key, T& t)
  20877. {
  20878. strtk::util::value& v = value_map_[key];
  20879. if (!v)
  20880. v = strtk::util::value(t);
  20881. else
  20882. v.assign(t);
  20883. return true;
  20884. }
  20885. private:
  20886. map_type value_map_;
  20887. key_validator_type key_validator_;
  20888. value_validator_type val_validator_;
  20889. };
  20890. typedef key_map<std::string> stringkey_map;
  20891. }
  20892. } // namespace strtk
  20893. namespace
  20894. {
  20895. static inline std::ostream& operator<<(std::ostream& os,
  20896. const strtk::std_string::tokenizer<strtk::single_delimiter_predicate<char> >::type::iterator& range)
  20897. {
  20898. os << std::string((*range).first,(*range).second);
  20899. return os;
  20900. }
  20901. static inline std::ostream& operator<<(std::ostream& os,
  20902. const strtk::std_string::tokenizer<strtk::single_delimiter_predicate<unsigned char> >::type::iterator& range)
  20903. {
  20904. os << std::string((*range).first,(*range).second);
  20905. return os;
  20906. }
  20907. static inline std::ostream& operator<<(std::ostream& os,
  20908. const strtk::std_string::tokenizer<strtk::multiple_char_delimiter_predicate>::type::iterator& range)
  20909. {
  20910. os << std::string((*range).first,(*range).second);
  20911. return os;
  20912. }
  20913. #define strtk_register_pair_to_ostream(Iterator) \
  20914. static inline std::ostream& operator<<(std::ostream& os, const std::pair<Iterator,Iterator>& range)\
  20915. { os << std::string(range.first,range.second); return os; } \
  20916. static inline std::ostream& operator<<(std::ostream& os, std::pair<Iterator,Iterator>& range) \
  20917. { os << std::string(range.first,range.second); return os; } \
  20918. strtk_register_pair_to_ostream(char*)
  20919. strtk_register_pair_to_ostream(unsigned char*)
  20920. strtk_register_pair_to_ostream(const char*)
  20921. strtk_register_pair_to_ostream(const unsigned char*)
  20922. strtk_register_pair_to_ostream(std::string::iterator)
  20923. strtk_register_pair_to_ostream(std::string::const_iterator)
  20924. strtk_register_pair_to_ostream(const std::string::iterator)
  20925. strtk_register_pair_to_ostream(const std::string::const_iterator)
  20926. #undef strtk_register_pair_to_ostream
  20927. } // namespace anonymous
  20928. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  20929. #ifndef NOMINMAX
  20930. #define NOMINMAX
  20931. #endif
  20932. #ifndef WIN32_LEAN_AND_MEAN
  20933. #define WIN32_LEAN_AND_MEAN
  20934. #endif
  20935. #include <windows.h>
  20936. #else
  20937. #include <sys/time.h>
  20938. #include <sys/types.h>
  20939. #endif
  20940. namespace strtk
  20941. {
  20942. namespace util
  20943. {
  20944. class timer
  20945. {
  20946. public:
  20947. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  20948. timer()
  20949. : in_use_(false)
  20950. {
  20951. QueryPerformanceFrequency(&clock_frequency_);
  20952. }
  20953. inline void start()
  20954. {
  20955. in_use_ = true;
  20956. QueryPerformanceCounter(&start_time_);
  20957. }
  20958. inline void stop()
  20959. {
  20960. QueryPerformanceCounter(&stop_time_);
  20961. in_use_ = false;
  20962. }
  20963. inline double time() const
  20964. {
  20965. return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart);
  20966. }
  20967. #else
  20968. timer()
  20969. : in_use_(false)
  20970. {
  20971. start_time_.tv_sec = 0;
  20972. start_time_.tv_usec = 0;
  20973. stop_time_.tv_sec = 0;
  20974. stop_time_.tv_usec = 0;
  20975. }
  20976. inline void start()
  20977. {
  20978. in_use_ = true;
  20979. gettimeofday(&start_time_,0);
  20980. }
  20981. inline void stop()
  20982. {
  20983. gettimeofday(&stop_time_, 0);
  20984. in_use_ = false;
  20985. }
  20986. inline unsigned long long int usec_time() const
  20987. {
  20988. if (!in_use_)
  20989. {
  20990. if (stop_time_.tv_sec >= start_time_.tv_sec)
  20991. {
  20992. return 1000000 * (stop_time_.tv_sec - start_time_.tv_sec ) +
  20993. (stop_time_.tv_usec - start_time_.tv_usec);
  20994. }
  20995. else
  20996. return std::numeric_limits<unsigned long long int>::max();
  20997. }
  20998. else
  20999. return std::numeric_limits<unsigned long long int>::max();
  21000. }
  21001. inline double time() const
  21002. {
  21003. return usec_time() * 0.000001;
  21004. }
  21005. #endif
  21006. inline bool in_use() const
  21007. {
  21008. return in_use_;
  21009. }
  21010. private:
  21011. bool in_use_;
  21012. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  21013. LARGE_INTEGER start_time_;
  21014. LARGE_INTEGER stop_time_;
  21015. LARGE_INTEGER clock_frequency_;
  21016. #else
  21017. struct timeval start_time_;
  21018. struct timeval stop_time_;
  21019. #endif
  21020. };
  21021. class scoped_timer
  21022. {
  21023. public:
  21024. scoped_timer(double& time_value)
  21025. : time_value_(time_value)
  21026. {
  21027. t_.start();
  21028. }
  21029. ~scoped_timer()
  21030. {
  21031. t_.stop();
  21032. time_value_ = t_.time();
  21033. }
  21034. private:
  21035. scoped_timer(const scoped_timer&);
  21036. scoped_timer& operator=(const scoped_timer&);
  21037. double& time_value_;
  21038. timer t_;
  21039. };
  21040. } // namespace util
  21041. namespace information
  21042. {
  21043. static const char* library = "String Toolkit";
  21044. static const char* version = "2.718281828459045235360287471352662497757247093699959574966";
  21045. static const char* date = "20140810";
  21046. static inline std::string data()
  21047. {
  21048. static const std::string info_str = std::string(library) +
  21049. std::string(" v") + std::string(version) +
  21050. std::string(" (") + date + std::string(")");
  21051. return info_str;
  21052. }
  21053. } // namespace information
  21054. } // namespace strtk
  21055. #endif