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 13 #ifndef BOOST_PHOENIX_ALGORITHM_QUERYING_HPP 14 #define BOOST_PHOENIX_ALGORITHM_QUERYING_HPP 15 16 #include <algorithm> 17 18 #include <boost/phoenix/core/limits.hpp> 19 #include <boost/phoenix/stl/algorithm/detail/has_find.hpp> 20 #include <boost/phoenix/stl/algorithm/detail/has_lower_bound.hpp> 21 #include <boost/phoenix/stl/algorithm/detail/has_upper_bound.hpp> 22 #include <boost/phoenix/stl/algorithm/detail/has_equal_range.hpp> 23 24 #include <boost/phoenix/stl/algorithm/detail/begin.hpp> 25 #include <boost/phoenix/stl/algorithm/detail/end.hpp> 26 #include <boost/phoenix/stl/algorithm/detail/decay_array.hpp> 27 28 #include <boost/phoenix/function/adapt_callable.hpp> 29 30 //#include <boost/range/result_iterator.hpp> is deprecated 31 #include <boost/range/iterator.hpp> 32 #include <boost/range/difference_type.hpp> 33 34 namespace boost { namespace phoenix { 35 namespace impl 36 { 37 struct find 38 { 39 template <typename Sig> 40 struct result; 41 42 template <typename This, class R, class T> 43 struct result<This(R&, T&)> 44 : range_iterator<R> 45 {}; 46 47 template<class R, class T> 48 typename range_iterator<R>::type executeboost::phoenix::impl::find49 execute(R& r, T const& x, mpl::true_) const 50 { 51 return r.find(x); 52 } 53 54 template<class R, class T> 55 typename range_iterator<R>::type executeboost::phoenix::impl::find56 execute(R& r, T const& x, mpl::false_) const 57 { 58 return std::find(detail::begin_(r), detail::end_(r), x); 59 } 60 61 template<class R, class T> 62 typename range_iterator<R>::type operator ()boost::phoenix::impl::find63 operator()(R& r, T const& x) const 64 { 65 return execute(r, x, has_find<R>()); 66 } 67 }; 68 69 struct find_if 70 { 71 template <typename Sig> 72 struct result; 73 74 template <typename This, class R, class P> 75 struct result<This(R&, P)> 76 : range_iterator<R> 77 {}; 78 79 template<class R, class P> 80 typename range_iterator<R>::type operator ()boost::phoenix::impl::find_if81 operator()(R& r, P p) const 82 { 83 return std::find_if(detail::begin_(r), detail::end_(r), p); 84 } 85 }; 86 87 struct find_end 88 { 89 template <typename Sig> 90 struct result; 91 92 template<typename This, class R, class R2> 93 struct result<This(R&, R2&)> 94 : range_iterator<R> 95 {}; 96 97 template<typename This, class R, class R2, class P> 98 struct result<This(R&, R2&, P)> 99 : range_iterator<R> 100 {}; 101 102 template<class R, class R2> 103 typename range_iterator<R>::type operator ()boost::phoenix::impl::find_end104 operator()(R& r, R2& r2) const 105 { 106 return std::find_end( 107 detail::begin_(r) 108 , detail::end_(r) 109 , detail::begin_(r2) 110 , detail::end_(r2) 111 ); 112 } 113 114 template<class R, class R2, class P> 115 typename range_iterator<R>::type operator ()boost::phoenix::impl::find_end116 operator()(R& r, R2& r2, P p) const 117 { 118 return std::find_end( 119 detail::begin_(r) 120 , detail::end_(r) 121 , detail::begin_(r2) 122 , detail::end_(r2) 123 , p 124 ); 125 } 126 }; 127 128 struct find_first_of 129 { 130 template <typename Sig> 131 struct result; 132 133 template<typename This, class R, class R2> 134 struct result<This(R&, R2&)> 135 : range_iterator<R> 136 {}; 137 138 template<typename This, class R, class R2, class P> 139 struct result<This(R&, R2&, P)> 140 : range_iterator<R> 141 {}; 142 143 template<class R, class R2> 144 typename range_iterator<R>::type operator ()boost::phoenix::impl::find_first_of145 operator()(R& r, R2& r2) const 146 { 147 return std::find_first_of( 148 detail::begin_(r) 149 , detail::end_(r) 150 , detail::begin_(r2) 151 , detail::end_(r2) 152 ); 153 } 154 155 template<class R, class R2, class P> 156 typename range_iterator<R>::type operator ()boost::phoenix::impl::find_first_of157 operator()(R& r, R2& r2, P p) const 158 { 159 return std::find_first_of( 160 detail::begin_(r) 161 , detail::end_(r) 162 , detail::begin_(r2) 163 , detail::end_(r2) 164 , p 165 ); 166 } 167 }; 168 169 struct adjacent_find 170 { 171 template <typename Sig> 172 struct result; 173 174 template <typename This, class R> 175 struct result<This(R&)> 176 : range_iterator<R> 177 {}; 178 179 template <typename This, class R, class P> 180 struct result<This(R&, P)> 181 : range_iterator<R> 182 {}; 183 184 template<class R> 185 typename range_iterator<R>::type operator ()boost::phoenix::impl::adjacent_find186 operator()(R& r) const 187 { 188 return std::adjacent_find(detail::begin_(r), detail::end_(r)); 189 } 190 191 template<class R, class P> 192 typename range_iterator<R>::type operator ()boost::phoenix::impl::adjacent_find193 operator()(R& r, P p) const 194 { 195 return std::adjacent_find(detail::begin_(r), detail::end_(r), p); 196 } 197 }; 198 199 struct count 200 { 201 template <typename Sig> 202 struct result; 203 204 template <typename This, class R, class T> 205 struct result<This(R&, T&)> 206 : range_difference<R> 207 {}; 208 209 template<class R, class T> 210 typename range_difference<R>::type operator ()boost::phoenix::impl::count211 operator()(R& r, T const& x) const 212 { 213 return std::count(detail::begin_(r), detail::end_(r), x); 214 } 215 }; 216 217 struct count_if 218 { 219 template <typename Sig> 220 struct result; 221 222 template <typename This, class R, class P> 223 struct result<This(R&, P)> 224 : range_difference<R> 225 {}; 226 227 template<class R, class P> 228 typename range_difference<R>::type operator ()boost::phoenix::impl::count_if229 operator()(R& r, P p) const 230 { 231 return std::count_if(detail::begin_(r), detail::end_(r), p); 232 } 233 }; 234 235 struct distance 236 { 237 template <typename Sig> 238 struct result; 239 240 template <typename This, class R> 241 struct result<This(R&)> 242 : range_difference<R> 243 {}; 244 245 template<class R> 246 typename range_difference<R>::type operator ()boost::phoenix::impl::distance247 operator()(R& r) const 248 { 249 return std::distance(detail::begin_(r), detail::end_(r)); 250 } 251 }; 252 253 struct equal 254 { 255 typedef bool result_type; 256 257 template<class R, class I> operator ()boost::phoenix::impl::equal258 bool operator()(R& r, I i) const 259 { 260 return std::equal(detail::begin_(r), detail::end_(r), i); 261 } 262 263 template<class R, class I, class P> operator ()boost::phoenix::impl::equal264 bool operator()(R& r, I i, P p) const 265 { 266 return std::equal(detail::begin_(r), detail::end_(r), i, p); 267 } 268 }; 269 270 struct search 271 { 272 template <typename Sig> 273 struct result; 274 275 template <typename This, class R, typename R2> 276 struct result<This(R&, R2&)> 277 : range_iterator<R> 278 {}; 279 280 template <typename This, class R, typename R2, class P> 281 struct result<This(R&, R2&, P)> 282 : range_iterator<R> 283 {}; 284 285 template<class R, class R2> 286 typename range_iterator<R>::type operator ()boost::phoenix::impl::search287 operator()(R& r, R2& r2) const 288 { 289 return std::search( 290 detail::begin_(r) 291 , detail::end_(r) 292 , detail::begin_(r2) 293 , detail::end_(r2) 294 ); 295 } 296 297 template<class R, class R2, class P> 298 typename range_iterator<R>::type operator ()boost::phoenix::impl::search299 operator()(R& r, R2& r2, P p) const 300 { 301 return std::search( 302 detail::begin_(r) 303 , detail::end_(r) 304 , detail::begin_(r2) 305 , detail::end_(r2) 306 , p 307 ); 308 } 309 }; 310 311 struct lower_bound 312 { 313 template <typename Sig> 314 struct result; 315 316 template <typename This, class R, class T> 317 struct result<This(R&, T&)> 318 : range_iterator<R> 319 {}; 320 321 template <typename This, class R, class T, class C> 322 struct result<This(R&, T&, C)> 323 : range_iterator<R> 324 {}; 325 326 template<class R, class T> 327 typename range_iterator<R>::type executeboost::phoenix::impl::lower_bound328 execute(R& r, T const& val, mpl::true_) const 329 { 330 return r.lower_bound(val); 331 } 332 333 template<class R, class T> 334 typename range_iterator<R>::type executeboost::phoenix::impl::lower_bound335 execute(R& r, T const& val, mpl::false_) const 336 { 337 return std::lower_bound(detail::begin_(r), detail::end_(r), val); 338 } 339 340 template<class R, class T> 341 typename range_iterator<R>::type operator ()boost::phoenix::impl::lower_bound342 operator()(R& r, T const& val) const 343 { 344 return execute(r, val, has_lower_bound<R>()); 345 } 346 347 template<class R, class T, class C> 348 typename range_iterator<R>::type operator ()boost::phoenix::impl::lower_bound349 operator()(R& r, T const& val, C c) const 350 { 351 return std::lower_bound(detail::begin_(r), detail::end_(r), val, c); 352 } 353 }; 354 355 struct upper_bound 356 { 357 template <typename Sig> 358 struct result; 359 360 template <typename This, class R, class T> 361 struct result<This(R&, T&)> 362 : range_iterator<R> 363 {}; 364 365 template <typename This, class R, class T, class C> 366 struct result<This(R&, T&, C)> 367 : range_iterator<R> 368 {}; 369 370 template<class R, class T> 371 typename range_iterator<R>::type executeboost::phoenix::impl::upper_bound372 execute(R& r, T const& val, mpl::true_) const 373 { 374 return r.upper_bound(val); 375 } 376 377 template<class R, class T> 378 typename range_iterator<R>::type executeboost::phoenix::impl::upper_bound379 execute(R& r, T const& val, mpl::false_) const 380 { 381 return std::upper_bound(detail::begin_(r), detail::end_(r), val); 382 } 383 384 template<class R, class T> 385 typename range_iterator<R>::type operator ()boost::phoenix::impl::upper_bound386 operator()(R& r, T const& val) const 387 { 388 return execute(r, val, has_upper_bound<R>()); 389 } 390 391 template<class R, class T, class C> 392 typename range_iterator<R>::type operator ()boost::phoenix::impl::upper_bound393 operator()(R& r, T const& val, C c) const 394 { 395 return std::upper_bound(detail::begin_(r), detail::end_(r), val, c); 396 } 397 }; 398 399 namespace result_of 400 { 401 template <typename R, typename T, typename C = void> 402 struct equal_range 403 { 404 typedef std::pair< 405 typename range_iterator<R>::type 406 , typename range_iterator<R>::type 407 > type; 408 }; 409 } 410 411 struct equal_range 412 { 413 template <typename Sig> 414 struct result; 415 416 template <typename This, class R, class T> 417 struct result<This(R&, T&)> 418 : result_of::equal_range<R,T> 419 {}; 420 421 template <typename This, class R, class T, class C> 422 struct result<This(R&, T&, C)> 423 : result_of::equal_range<R,T, C> 424 {}; 425 426 template<class R, class T> 427 typename result_of::equal_range<R, T>::type executeboost::phoenix::impl::equal_range428 execute(R& r, T const& val, mpl::true_) const 429 { 430 return r.equal_range(val); 431 } 432 433 template<class R, class T> 434 typename result_of::equal_range<R, T>::type executeboost::phoenix::impl::equal_range435 execute(R& r, T const& val, mpl::false_) const 436 { 437 return std::equal_range(detail::begin_(r), detail::end_(r), val); 438 } 439 440 template<class R, class T> 441 typename result_of::equal_range<R, T>::type operator ()boost::phoenix::impl::equal_range442 operator()(R& r, T const& val) const 443 { 444 return execute(r, val, has_equal_range<R>()); 445 } 446 447 template<class R, class T, class C> 448 typename result_of::equal_range<R, T, C>::type operator ()boost::phoenix::impl::equal_range449 operator()(R& r, T const& val, C c) const 450 { 451 return std::equal_range(detail::begin_(r), detail::end_(r), val, c); 452 } 453 }; 454 455 namespace result_of 456 { 457 template <typename R, typename I, typename P = void> 458 struct mismatch 459 { 460 typedef std::pair< 461 typename range_iterator<R>::type 462 , typename detail::decay_array<I>::type 463 > type; 464 }; 465 } 466 467 struct mismatch 468 { 469 template <typename Sig> 470 struct result; 471 472 template<typename This, class R, class I> 473 struct result<This(R&, I)> 474 : result_of::mismatch<R, I> 475 {}; 476 477 template<typename This, class R, class I, class P> 478 struct result<This(R&, I, P)> 479 : result_of::mismatch<R, I, P> 480 {}; 481 482 template<class R, class I> 483 typename result_of::mismatch<R, I>::type operator ()boost::phoenix::impl::mismatch484 operator()(R& r, I i) const 485 { 486 return std::mismatch(detail::begin_(r), detail::end_(r), i); 487 } 488 489 template<class R, class I, class P> 490 typename result_of::mismatch<R, I, P>::type operator ()boost::phoenix::impl::mismatch491 operator()(R& r, I i, P p) const 492 { 493 return std::mismatch(detail::begin_(r), detail::end_(r), i, p); 494 } 495 }; 496 497 struct binary_search 498 { 499 typedef bool result_type; 500 501 template<class R, class T> operator ()boost::phoenix::impl::binary_search502 bool operator()(R& r, T const& val) const 503 { 504 return std::binary_search(detail::begin_(r), detail::end_(r), val); 505 } 506 507 template<class R, class T, class C> operator ()boost::phoenix::impl::binary_search508 bool operator()(R& r, T const& val, C c) const 509 { 510 return std::binary_search(detail::begin_(r), detail::end_(r), val, c); 511 } 512 }; 513 514 struct includes 515 { 516 typedef bool result_type; 517 518 template<class R1, class R2> operator ()boost::phoenix::impl::includes519 bool operator()(R1& r1, R2& r2) const 520 { 521 return std::includes( 522 detail::begin_(r1), detail::end_(r1) 523 , detail::begin_(r2), detail::end_(r2) 524 ); 525 } 526 527 template<class R1, class R2, class C> operator ()boost::phoenix::impl::includes528 bool operator()(R1& r1, R2& r2, C c) const 529 { 530 return std::includes( 531 detail::begin_(r1), detail::end_(r1) 532 , detail::begin_(r2), detail::end_(r2) 533 , c 534 ); 535 } 536 }; 537 538 struct min_element 539 { 540 template <typename Sig> 541 struct result; 542 543 template <typename This, class R> 544 struct result<This(R&)> 545 : range_iterator<R> 546 {}; 547 548 template <typename This, class R, class P> 549 struct result<This(R&, P)> 550 : range_iterator<R> 551 {}; 552 553 template<class R> 554 typename range_iterator<R>::type operator ()boost::phoenix::impl::min_element555 operator()(R& r) const 556 { 557 return std::min_element(detail::begin_(r), detail::end_(r)); 558 } 559 560 template<class R, class P> 561 typename range_iterator<R>::type operator ()boost::phoenix::impl::min_element562 operator()(R& r, P p) const 563 { 564 return std::min_element(detail::begin_(r), detail::end_(r), p); 565 } 566 }; 567 568 struct max_element 569 { 570 template <typename Sig> 571 struct result; 572 573 template <typename This, class R> 574 struct result<This(R&)> 575 : range_iterator<R> 576 {}; 577 578 template <typename This, class R, class P> 579 struct result<This(R&, P)> 580 : range_iterator<R> 581 {}; 582 583 template<class R> 584 typename range_iterator<R>::type operator ()boost::phoenix::impl::max_element585 operator()(R& r) const 586 { 587 return std::max_element(detail::begin_(r), detail::end_(r)); 588 } 589 590 template<class R, class P> 591 typename range_iterator<R>::type operator ()boost::phoenix::impl::max_element592 operator()(R& r, P p) const 593 { 594 return std::max_element(detail::begin_(r), detail::end_(r), p); 595 } 596 }; 597 598 struct lexicographical_compare 599 { 600 typedef bool result_type; 601 602 template<class R1, class R2> operator ()boost::phoenix::impl::lexicographical_compare603 bool operator()(R1& r1, R2& r2) const 604 { 605 return std::lexicographical_compare( 606 detail::begin_(r1), detail::end_(r1) 607 , detail::begin_(r2), detail::end_(r2) 608 ); 609 } 610 611 template<class R1, class R2, class P> operator ()boost::phoenix::impl::lexicographical_compare612 bool operator()(R1& r1, R2& r2, P p) const 613 { 614 return std::lexicographical_compare( 615 detail::begin_(r1), detail::end_(r1) 616 , detail::begin_(r2), detail::end_(r2) 617 , p 618 ); 619 } 620 }; 621 622 } 623 624 BOOST_PHOENIX_ADAPT_CALLABLE(find, impl::find, 2) 625 BOOST_PHOENIX_ADAPT_CALLABLE(find_if, impl::find_if, 2) 626 BOOST_PHOENIX_ADAPT_CALLABLE(find_end, impl::find_end, 2) 627 BOOST_PHOENIX_ADAPT_CALLABLE(find_end, impl::find_end, 3) 628 BOOST_PHOENIX_ADAPT_CALLABLE(find_first_of, impl::find_first_of, 2) 629 BOOST_PHOENIX_ADAPT_CALLABLE(find_first_of, impl::find_first_of, 3) 630 BOOST_PHOENIX_ADAPT_CALLABLE(adjacent_find, impl::adjacent_find, 1) 631 BOOST_PHOENIX_ADAPT_CALLABLE(adjacent_find, impl::adjacent_find, 2) 632 BOOST_PHOENIX_ADAPT_CALLABLE(count, impl::count, 2) 633 BOOST_PHOENIX_ADAPT_CALLABLE(count_if, impl::count_if, 2) 634 BOOST_PHOENIX_ADAPT_CALLABLE(distance, impl::distance, 1) 635 BOOST_PHOENIX_ADAPT_CALLABLE(equal, impl::equal, 2) 636 BOOST_PHOENIX_ADAPT_CALLABLE(equal, impl::equal, 3) 637 BOOST_PHOENIX_ADAPT_CALLABLE(search, impl::search, 2) 638 BOOST_PHOENIX_ADAPT_CALLABLE(search, impl::search, 3) 639 BOOST_PHOENIX_ADAPT_CALLABLE(lower_bound, impl::lower_bound, 2) 640 BOOST_PHOENIX_ADAPT_CALLABLE(lower_bound, impl::lower_bound, 3) 641 BOOST_PHOENIX_ADAPT_CALLABLE(upper_bound, impl::upper_bound, 2) 642 BOOST_PHOENIX_ADAPT_CALLABLE(upper_bound, impl::upper_bound, 3) 643 BOOST_PHOENIX_ADAPT_CALLABLE(equal_range, impl::equal_range, 2) 644 BOOST_PHOENIX_ADAPT_CALLABLE(equal_range, impl::equal_range, 3) 645 BOOST_PHOENIX_ADAPT_CALLABLE(mismatch, impl::mismatch, 2) 646 BOOST_PHOENIX_ADAPT_CALLABLE(mismatch, impl::mismatch, 3) 647 BOOST_PHOENIX_ADAPT_CALLABLE(binary_search, impl::binary_search, 2) 648 BOOST_PHOENIX_ADAPT_CALLABLE(binary_search, impl::binary_search, 3) 649 BOOST_PHOENIX_ADAPT_CALLABLE(includes, impl::includes, 2) 650 BOOST_PHOENIX_ADAPT_CALLABLE(includes, impl::includes, 3) 651 BOOST_PHOENIX_ADAPT_CALLABLE(min_element, impl::min_element, 1) 652 BOOST_PHOENIX_ADAPT_CALLABLE(min_element, impl::min_element, 2) 653 BOOST_PHOENIX_ADAPT_CALLABLE(max_element, impl::max_element, 1) 654 BOOST_PHOENIX_ADAPT_CALLABLE(max_element, impl::max_element, 2) 655 BOOST_PHOENIX_ADAPT_CALLABLE(lexicographical_compare, impl::lexicographical_compare, 2) 656 BOOST_PHOENIX_ADAPT_CALLABLE(lexicographical_compare, impl::lexicographical_compare, 3) 657 658 }} 659 660 #endif 661