querying.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. // Copyright 2005 Daniel Wallin.
  2. // Copyright 2005 Joel de Guzman.
  3. // Copyright 2005 Dan Marsden.
  4. // Copyright 2008 Hartmut Kaiser.
  5. // Copyright 2015 John Fletcher.
  6. //
  7. // Use, modification and distribution is subject to the Boost Software
  8. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Modeled after range_ex, Copyright 2004 Eric Niebler
  12. #ifndef BOOST_PHOENIX_ALGORITHM_QUERYING_HPP
  13. #define BOOST_PHOENIX_ALGORITHM_QUERYING_HPP
  14. #include <algorithm>
  15. #include <boost/phoenix/core/limits.hpp>
  16. #include <boost/phoenix/stl/algorithm/detail/has_find.hpp>
  17. #include <boost/phoenix/stl/algorithm/detail/has_lower_bound.hpp>
  18. #include <boost/phoenix/stl/algorithm/detail/has_upper_bound.hpp>
  19. #include <boost/phoenix/stl/algorithm/detail/has_equal_range.hpp>
  20. #include <boost/phoenix/stl/algorithm/detail/begin.hpp>
  21. #include <boost/phoenix/stl/algorithm/detail/end.hpp>
  22. #include <boost/phoenix/stl/algorithm/detail/decay_array.hpp>
  23. #include <boost/phoenix/function/adapt_callable.hpp>
  24. //#include <boost/range/result_iterator.hpp> is deprecated
  25. #include <boost/range/iterator.hpp>
  26. #include <boost/range/difference_type.hpp>
  27. namespace boost { namespace phoenix {
  28. namespace impl
  29. {
  30. struct find
  31. {
  32. template <typename Sig>
  33. struct result;
  34. template <typename This, class R, class T>
  35. struct result<This(R&, T&)>
  36. : range_iterator<R>
  37. {};
  38. template<class R, class T>
  39. typename range_iterator<R>::type
  40. execute(R& r, T const& x, mpl::true_) const
  41. {
  42. return r.find(x);
  43. }
  44. template<class R, class T>
  45. typename range_iterator<R>::type
  46. execute(R& r, T const& x, mpl::false_) const
  47. {
  48. return std::find(detail::begin_(r), detail::end_(r), x);
  49. }
  50. template<class R, class T>
  51. typename range_iterator<R>::type
  52. operator()(R& r, T const& x) const
  53. {
  54. return execute(r, x, has_find<R>());
  55. }
  56. };
  57. struct find_if
  58. {
  59. template <typename Sig>
  60. struct result;
  61. template <typename This, class R, class P>
  62. struct result<This(R&, P)>
  63. : range_iterator<R>
  64. {};
  65. template<class R, class P>
  66. typename range_iterator<R>::type
  67. operator()(R& r, P p) const
  68. {
  69. return std::find_if(detail::begin_(r), detail::end_(r), p);
  70. }
  71. };
  72. struct find_end
  73. {
  74. template <typename Sig>
  75. struct result;
  76. template<typename This, class R, class R2>
  77. struct result<This(R&, R2&)>
  78. : range_iterator<R>
  79. {};
  80. template<typename This, class R, class R2, class P>
  81. struct result<This(R&, R2&, P)>
  82. : range_iterator<R>
  83. {};
  84. template<class R, class R2>
  85. typename range_iterator<R>::type
  86. operator()(R& r, R2& r2) const
  87. {
  88. return std::find_end(
  89. detail::begin_(r)
  90. , detail::end_(r)
  91. , detail::begin_(r2)
  92. , detail::end_(r2)
  93. );
  94. }
  95. template<class R, class R2, class P>
  96. typename range_iterator<R>::type
  97. operator()(R& r, R2& r2, P p) const
  98. {
  99. return std::find_end(
  100. detail::begin_(r)
  101. , detail::end_(r)
  102. , detail::begin_(r2)
  103. , detail::end_(r2)
  104. , p
  105. );
  106. }
  107. };
  108. struct find_first_of
  109. {
  110. template <typename Sig>
  111. struct result;
  112. template<typename This, class R, class R2>
  113. struct result<This(R&, R2&)>
  114. : range_iterator<R>
  115. {};
  116. template<typename This, class R, class R2, class P>
  117. struct result<This(R&, R2&, P)>
  118. : range_iterator<R>
  119. {};
  120. template<class R, class R2>
  121. typename range_iterator<R>::type
  122. operator()(R& r, R2& r2) const
  123. {
  124. return std::find_first_of(
  125. detail::begin_(r)
  126. , detail::end_(r)
  127. , detail::begin_(r2)
  128. , detail::end_(r2)
  129. );
  130. }
  131. template<class R, class R2, class P>
  132. typename range_iterator<R>::type
  133. operator()(R& r, R2& r2, P p) const
  134. {
  135. return std::find_first_of(
  136. detail::begin_(r)
  137. , detail::end_(r)
  138. , detail::begin_(r2)
  139. , detail::end_(r2)
  140. , p
  141. );
  142. }
  143. };
  144. struct adjacent_find
  145. {
  146. template <typename Sig>
  147. struct result;
  148. template <typename This, class R>
  149. struct result<This(R&)>
  150. : range_iterator<R>
  151. {};
  152. template <typename This, class R, class P>
  153. struct result<This(R&, P)>
  154. : range_iterator<R>
  155. {};
  156. template<class R>
  157. typename range_iterator<R>::type
  158. operator()(R& r) const
  159. {
  160. return std::adjacent_find(detail::begin_(r), detail::end_(r));
  161. }
  162. template<class R, class P>
  163. typename range_iterator<R>::type
  164. operator()(R& r, P p) const
  165. {
  166. return std::adjacent_find(detail::begin_(r), detail::end_(r), p);
  167. }
  168. };
  169. struct count
  170. {
  171. template <typename Sig>
  172. struct result;
  173. template <typename This, class R, class T>
  174. struct result<This(R&, T&)>
  175. : range_difference<R>
  176. {};
  177. template<class R, class T>
  178. typename range_difference<R>::type
  179. operator()(R& r, T const& x) const
  180. {
  181. return std::count(detail::begin_(r), detail::end_(r), x);
  182. }
  183. };
  184. struct count_if
  185. {
  186. template <typename Sig>
  187. struct result;
  188. template <typename This, class R, class P>
  189. struct result<This(R&, P)>
  190. : range_difference<R>
  191. {};
  192. template<class R, class P>
  193. typename range_difference<R>::type
  194. operator()(R& r, P p) const
  195. {
  196. return std::count_if(detail::begin_(r), detail::end_(r), p);
  197. }
  198. };
  199. struct distance
  200. {
  201. template <typename Sig>
  202. struct result;
  203. template <typename This, class R>
  204. struct result<This(R&)>
  205. : range_difference<R>
  206. {};
  207. template<class R>
  208. typename range_difference<R>::type
  209. operator()(R& r) const
  210. {
  211. return std::distance(detail::begin_(r), detail::end_(r));
  212. }
  213. };
  214. struct equal
  215. {
  216. typedef bool result_type;
  217. template<class R, class I>
  218. bool operator()(R& r, I i) const
  219. {
  220. return std::equal(detail::begin_(r), detail::end_(r), i);
  221. }
  222. template<class R, class I, class P>
  223. bool operator()(R& r, I i, P p) const
  224. {
  225. return std::equal(detail::begin_(r), detail::end_(r), i, p);
  226. }
  227. };
  228. struct search
  229. {
  230. template <typename Sig>
  231. struct result;
  232. template <typename This, class R, typename R2>
  233. struct result<This(R&, R2&)>
  234. : range_iterator<R>
  235. {};
  236. template <typename This, class R, typename R2, class P>
  237. struct result<This(R&, R2&, P)>
  238. : range_iterator<R>
  239. {};
  240. template<class R, class R2>
  241. typename range_iterator<R>::type
  242. operator()(R& r, R2& r2) const
  243. {
  244. return std::search(
  245. detail::begin_(r)
  246. , detail::end_(r)
  247. , detail::begin_(r2)
  248. , detail::end_(r2)
  249. );
  250. }
  251. template<class R, class R2, class P>
  252. typename range_iterator<R>::type
  253. operator()(R& r, R2& r2, P p) const
  254. {
  255. return std::search(
  256. detail::begin_(r)
  257. , detail::end_(r)
  258. , detail::begin_(r2)
  259. , detail::end_(r2)
  260. , p
  261. );
  262. }
  263. };
  264. struct lower_bound
  265. {
  266. template <typename Sig>
  267. struct result;
  268. template <typename This, class R, class T>
  269. struct result<This(R&, T&)>
  270. : range_iterator<R>
  271. {};
  272. template <typename This, class R, class T, class C>
  273. struct result<This(R&, T&, C)>
  274. : range_iterator<R>
  275. {};
  276. template<class R, class T>
  277. typename range_iterator<R>::type
  278. execute(R& r, T const& val, mpl::true_) const
  279. {
  280. return r.lower_bound(val);
  281. }
  282. template<class R, class T>
  283. typename range_iterator<R>::type
  284. execute(R& r, T const& val, mpl::false_) const
  285. {
  286. return std::lower_bound(detail::begin_(r), detail::end_(r), val);
  287. }
  288. template<class R, class T>
  289. typename range_iterator<R>::type
  290. operator()(R& r, T const& val) const
  291. {
  292. return execute(r, val, has_lower_bound<R>());
  293. }
  294. template<class R, class T, class C>
  295. typename range_iterator<R>::type
  296. operator()(R& r, T const& val, C c) const
  297. {
  298. return std::lower_bound(detail::begin_(r), detail::end_(r), val, c);
  299. }
  300. };
  301. struct upper_bound
  302. {
  303. template <typename Sig>
  304. struct result;
  305. template <typename This, class R, class T>
  306. struct result<This(R&, T&)>
  307. : range_iterator<R>
  308. {};
  309. template <typename This, class R, class T, class C>
  310. struct result<This(R&, T&, C)>
  311. : range_iterator<R>
  312. {};
  313. template<class R, class T>
  314. typename range_iterator<R>::type
  315. execute(R& r, T const& val, mpl::true_) const
  316. {
  317. return r.upper_bound(val);
  318. }
  319. template<class R, class T>
  320. typename range_iterator<R>::type
  321. execute(R& r, T const& val, mpl::false_) const
  322. {
  323. return std::upper_bound(detail::begin_(r), detail::end_(r), val);
  324. }
  325. template<class R, class T>
  326. typename range_iterator<R>::type
  327. operator()(R& r, T const& val) const
  328. {
  329. return execute(r, val, has_upper_bound<R>());
  330. }
  331. template<class R, class T, class C>
  332. typename range_iterator<R>::type
  333. operator()(R& r, T const& val, C c) const
  334. {
  335. return std::upper_bound(detail::begin_(r), detail::end_(r), val, c);
  336. }
  337. };
  338. namespace result_of
  339. {
  340. template <typename R, typename T, typename C = void>
  341. struct equal_range
  342. {
  343. typedef std::pair<
  344. typename range_iterator<R>::type
  345. , typename range_iterator<R>::type
  346. > type;
  347. };
  348. }
  349. struct equal_range
  350. {
  351. template <typename Sig>
  352. struct result;
  353. template <typename This, class R, class T>
  354. struct result<This(R&, T&)>
  355. : result_of::equal_range<R,T>
  356. {};
  357. template <typename This, class R, class T, class C>
  358. struct result<This(R&, T&, C)>
  359. : result_of::equal_range<R,T, C>
  360. {};
  361. template<class R, class T>
  362. typename result_of::equal_range<R, T>::type
  363. execute(R& r, T const& val, mpl::true_) const
  364. {
  365. return r.equal_range(val);
  366. }
  367. template<class R, class T>
  368. typename result_of::equal_range<R, T>::type
  369. execute(R& r, T const& val, mpl::false_) const
  370. {
  371. return std::equal_range(detail::begin_(r), detail::end_(r), val);
  372. }
  373. template<class R, class T>
  374. typename result_of::equal_range<R, T>::type
  375. operator()(R& r, T const& val) const
  376. {
  377. return execute(r, val, has_equal_range<R>());
  378. }
  379. template<class R, class T, class C>
  380. typename result_of::equal_range<R, T, C>::type
  381. operator()(R& r, T const& val, C c) const
  382. {
  383. return std::equal_range(detail::begin_(r), detail::end_(r), val, c);
  384. }
  385. };
  386. namespace result_of
  387. {
  388. template <typename R, typename I, typename P = void>
  389. struct mismatch
  390. {
  391. typedef std::pair<
  392. typename range_iterator<R>::type
  393. , typename detail::decay_array<I>::type
  394. > type;
  395. };
  396. }
  397. struct mismatch
  398. {
  399. template <typename Sig>
  400. struct result;
  401. template<typename This, class R, class I>
  402. struct result<This(R&, I)>
  403. : result_of::mismatch<R, I>
  404. {};
  405. template<typename This, class R, class I, class P>
  406. struct result<This(R&, I, P)>
  407. : result_of::mismatch<R, I, P>
  408. {};
  409. template<class R, class I>
  410. typename result_of::mismatch<R, I>::type
  411. operator()(R& r, I i) const
  412. {
  413. return std::mismatch(detail::begin_(r), detail::end_(r), i);
  414. }
  415. template<class R, class I, class P>
  416. typename result_of::mismatch<R, I, P>::type
  417. operator()(R& r, I i, P p) const
  418. {
  419. return std::mismatch(detail::begin_(r), detail::end_(r), i, p);
  420. }
  421. };
  422. struct binary_search
  423. {
  424. typedef bool result_type;
  425. template<class R, class T>
  426. bool operator()(R& r, T const& val) const
  427. {
  428. return std::binary_search(detail::begin_(r), detail::end_(r), val);
  429. }
  430. template<class R, class T, class C>
  431. bool operator()(R& r, T const& val, C c) const
  432. {
  433. return std::binary_search(detail::begin_(r), detail::end_(r), val, c);
  434. }
  435. };
  436. struct includes
  437. {
  438. typedef bool result_type;
  439. template<class R1, class R2>
  440. bool operator()(R1& r1, R2& r2) const
  441. {
  442. return std::includes(
  443. detail::begin_(r1), detail::end_(r1)
  444. , detail::begin_(r2), detail::end_(r2)
  445. );
  446. }
  447. template<class R1, class R2, class C>
  448. bool operator()(R1& r1, R2& r2, C c) const
  449. {
  450. return std::includes(
  451. detail::begin_(r1), detail::end_(r1)
  452. , detail::begin_(r2), detail::end_(r2)
  453. , c
  454. );
  455. }
  456. };
  457. struct min_element
  458. {
  459. template <typename Sig>
  460. struct result;
  461. template <typename This, class R>
  462. struct result<This(R&)>
  463. : range_iterator<R>
  464. {};
  465. template <typename This, class R, class P>
  466. struct result<This(R&, P)>
  467. : range_iterator<R>
  468. {};
  469. template<class R>
  470. typename range_iterator<R>::type
  471. operator()(R& r) const
  472. {
  473. return std::min_element(detail::begin_(r), detail::end_(r));
  474. }
  475. template<class R, class P>
  476. typename range_iterator<R>::type
  477. operator()(R& r, P p) const
  478. {
  479. return std::min_element(detail::begin_(r), detail::end_(r), p);
  480. }
  481. };
  482. struct max_element
  483. {
  484. template <typename Sig>
  485. struct result;
  486. template <typename This, class R>
  487. struct result<This(R&)>
  488. : range_iterator<R>
  489. {};
  490. template <typename This, class R, class P>
  491. struct result<This(R&, P)>
  492. : range_iterator<R>
  493. {};
  494. template<class R>
  495. typename range_iterator<R>::type
  496. operator()(R& r) const
  497. {
  498. return std::max_element(detail::begin_(r), detail::end_(r));
  499. }
  500. template<class R, class P>
  501. typename range_iterator<R>::type
  502. operator()(R& r, P p) const
  503. {
  504. return std::max_element(detail::begin_(r), detail::end_(r), p);
  505. }
  506. };
  507. struct lexicographical_compare
  508. {
  509. typedef bool result_type;
  510. template<class R1, class R2>
  511. bool operator()(R1& r1, R2& r2) const
  512. {
  513. return std::lexicographical_compare(
  514. detail::begin_(r1), detail::end_(r1)
  515. , detail::begin_(r2), detail::end_(r2)
  516. );
  517. }
  518. template<class R1, class R2, class P>
  519. bool operator()(R1& r1, R2& r2, P p) const
  520. {
  521. return std::lexicographical_compare(
  522. detail::begin_(r1), detail::end_(r1)
  523. , detail::begin_(r2), detail::end_(r2)
  524. , p
  525. );
  526. }
  527. };
  528. }
  529. BOOST_PHOENIX_ADAPT_CALLABLE(find, impl::find, 2)
  530. BOOST_PHOENIX_ADAPT_CALLABLE(find_if, impl::find_if, 2)
  531. BOOST_PHOENIX_ADAPT_CALLABLE(find_end, impl::find_end, 2)
  532. BOOST_PHOENIX_ADAPT_CALLABLE(find_end, impl::find_end, 3)
  533. BOOST_PHOENIX_ADAPT_CALLABLE(find_first_of, impl::find_first_of, 2)
  534. BOOST_PHOENIX_ADAPT_CALLABLE(find_first_of, impl::find_first_of, 3)
  535. BOOST_PHOENIX_ADAPT_CALLABLE(adjacent_find, impl::adjacent_find, 1)
  536. BOOST_PHOENIX_ADAPT_CALLABLE(adjacent_find, impl::adjacent_find, 2)
  537. BOOST_PHOENIX_ADAPT_CALLABLE(count, impl::count, 2)
  538. BOOST_PHOENIX_ADAPT_CALLABLE(count_if, impl::count_if, 2)
  539. BOOST_PHOENIX_ADAPT_CALLABLE(distance, impl::distance, 1)
  540. BOOST_PHOENIX_ADAPT_CALLABLE(equal, impl::equal, 2)
  541. BOOST_PHOENIX_ADAPT_CALLABLE(equal, impl::equal, 3)
  542. BOOST_PHOENIX_ADAPT_CALLABLE(search, impl::search, 2)
  543. BOOST_PHOENIX_ADAPT_CALLABLE(search, impl::search, 3)
  544. BOOST_PHOENIX_ADAPT_CALLABLE(lower_bound, impl::lower_bound, 2)
  545. BOOST_PHOENIX_ADAPT_CALLABLE(lower_bound, impl::lower_bound, 3)
  546. BOOST_PHOENIX_ADAPT_CALLABLE(upper_bound, impl::upper_bound, 2)
  547. BOOST_PHOENIX_ADAPT_CALLABLE(upper_bound, impl::upper_bound, 3)
  548. BOOST_PHOENIX_ADAPT_CALLABLE(equal_range, impl::equal_range, 2)
  549. BOOST_PHOENIX_ADAPT_CALLABLE(equal_range, impl::equal_range, 3)
  550. BOOST_PHOENIX_ADAPT_CALLABLE(mismatch, impl::mismatch, 2)
  551. BOOST_PHOENIX_ADAPT_CALLABLE(mismatch, impl::mismatch, 3)
  552. BOOST_PHOENIX_ADAPT_CALLABLE(binary_search, impl::binary_search, 2)
  553. BOOST_PHOENIX_ADAPT_CALLABLE(binary_search, impl::binary_search, 3)
  554. BOOST_PHOENIX_ADAPT_CALLABLE(includes, impl::includes, 2)
  555. BOOST_PHOENIX_ADAPT_CALLABLE(includes, impl::includes, 3)
  556. BOOST_PHOENIX_ADAPT_CALLABLE(min_element, impl::min_element, 1)
  557. BOOST_PHOENIX_ADAPT_CALLABLE(min_element, impl::min_element, 2)
  558. BOOST_PHOENIX_ADAPT_CALLABLE(max_element, impl::max_element, 1)
  559. BOOST_PHOENIX_ADAPT_CALLABLE(max_element, impl::max_element, 2)
  560. BOOST_PHOENIX_ADAPT_CALLABLE(lexicographical_compare, impl::lexicographical_compare, 2)
  561. BOOST_PHOENIX_ADAPT_CALLABLE(lexicographical_compare, impl::lexicographical_compare, 3)
  562. }}
  563. #endif