PageRenderTime 62ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 2ms

/strtk.hpp

http://strtk.codeplex.com
C++ Header | 13496 lines | 12692 code | 752 blank | 52 comment | 847 complexity | 0a8accbcd9730aa9e8c7743f9e912017 MD5 | raw file

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

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

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