querying.hpp 21 KB

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