Chris@16: // Copyright 2005 Daniel Wallin. Chris@16: // Copyright 2005 Joel de Guzman. Chris@16: // Copyright 2005 Dan Marsden. Chris@16: // Copyright 2008 Hartmut Kaiser. Chris@16: // Chris@16: // Use, modification and distribution is subject to the Boost Software Chris@16: // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // Modeled after range_ex, Copyright 2004 Eric Niebler Chris@16: Chris@16: #ifndef BOOST_PHOENIX_ALGORITHM_QUERYING_HPP Chris@16: #define BOOST_PHOENIX_ALGORITHM_QUERYING_HPP Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace phoenix { Chris@16: namespace impl Chris@16: { Chris@16: struct find Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: execute(R& r, T const& x, mpl::true_) const Chris@16: { Chris@16: return r.find(x); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: execute(R& r, T const& x, mpl::false_) const Chris@16: { Chris@16: return std::find(detail::begin_(r), detail::end_(r), x); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, T const& x) const Chris@16: { Chris@16: return execute(r, x, has_find()); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct find_if Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, P p) const Chris@16: { Chris@16: return std::find_if(detail::begin_(r), detail::end_(r), p); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct find_end Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, R2& r2) const Chris@16: { Chris@16: return std::find_end( Chris@16: detail::begin_(r) Chris@16: , detail::end_(r) Chris@16: , detail::begin_(r2) Chris@16: , detail::end_(r2) Chris@16: ); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, R2& r2, P p) const Chris@16: { Chris@16: return std::find_end( Chris@16: detail::begin_(r) Chris@16: , detail::end_(r) Chris@16: , detail::begin_(r2) Chris@16: , detail::end_(r2) Chris@16: , p Chris@16: ); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct find_first_of Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, R2& r2) const Chris@16: { Chris@16: return std::find_first_of( Chris@16: detail::begin_(r) Chris@16: , detail::end_(r) Chris@16: , detail::begin_(r2) Chris@16: , detail::end_(r2) Chris@16: ); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, R2& r2, P p) const Chris@16: { Chris@16: return std::find_first_of( Chris@16: detail::begin_(r) Chris@16: , detail::end_(r) Chris@16: , detail::begin_(r2) Chris@16: , detail::end_(r2) Chris@16: , p Chris@16: ); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct adjacent_find Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r) const Chris@16: { Chris@16: return std::adjacent_find(detail::begin_(r), detail::end_(r)); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, P p) const Chris@16: { Chris@16: return std::adjacent_find(detail::begin_(r), detail::end_(r), p); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct count Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_difference Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename range_difference::type Chris@16: operator()(R& r, T const& x) const Chris@16: { Chris@16: return std::count(detail::begin_(r), detail::end_(r), x); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct count_if Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_difference Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename range_difference::type Chris@16: operator()(R& r, P p) const Chris@16: { Chris@16: return std::count_if(detail::begin_(r), detail::end_(r), p); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct distance Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_difference Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename range_difference::type Chris@16: operator()(R& r) const Chris@16: { Chris@16: return std::distance(detail::begin_(r), detail::end_(r)); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct equal Chris@16: { Chris@16: typedef bool result_type; Chris@16: Chris@16: template Chris@16: bool operator()(R& r, I i) const Chris@16: { Chris@16: return std::equal(detail::begin_(r), detail::end_(r), i); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator()(R& r, I i, P p) const Chris@16: { Chris@16: return std::equal(detail::begin_(r), detail::end_(r), i, p); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct search Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, R2& r2) const Chris@16: { Chris@16: return std::search( Chris@16: detail::begin_(r) Chris@16: , detail::end_(r) Chris@16: , detail::begin_(r2) Chris@16: , detail::end_(r2) Chris@16: ); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, R2& r2, P p) const Chris@16: { Chris@16: return std::search( Chris@16: detail::begin_(r) Chris@16: , detail::end_(r) Chris@16: , detail::begin_(r2) Chris@16: , detail::end_(r2) Chris@16: , p Chris@16: ); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct lower_bound Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: execute(R& r, T const& val, mpl::true_) const Chris@16: { Chris@16: return r.lower_bound(val); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: execute(R& r, T const& val, mpl::false_) const Chris@16: { Chris@16: return std::lower_bound(detail::begin_(r), detail::end_(r), val); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, T const& val) const Chris@16: { Chris@16: return execute(r, val, has_lower_bound()); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, T const& val, C c) const Chris@16: { Chris@16: return std::lower_bound(detail::begin_(r), detail::end_(r), val, c); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct upper_bound Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: execute(R& r, T const& val, mpl::true_) const Chris@16: { Chris@16: return r.upper_bound(val); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: execute(R& r, T const& val, mpl::false_) const Chris@16: { Chris@16: return std::upper_bound(detail::begin_(r), detail::end_(r), val); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, T const& val) const Chris@16: { Chris@16: return execute(r, val, has_upper_bound()); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, T const& val, C c) const Chris@16: { Chris@16: return std::upper_bound(detail::begin_(r), detail::end_(r), val, c); Chris@16: } Chris@16: }; Chris@16: Chris@16: namespace result_of Chris@16: { Chris@16: template Chris@16: struct equal_range Chris@16: { Chris@16: typedef std::pair< Chris@16: typename range_result_iterator::type Chris@16: , typename range_result_iterator::type Chris@16: > type; Chris@16: }; Chris@16: } Chris@16: Chris@16: struct equal_range Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : result_of::equal_range Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : result_of::equal_range Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename result_of::equal_range::type Chris@16: execute(R& r, T const& val, mpl::true_) const Chris@16: { Chris@16: return r.equal_range(val); Chris@16: } Chris@16: Chris@16: template Chris@16: typename result_of::equal_range::type Chris@16: execute(R& r, T const& val, mpl::false_) const Chris@16: { Chris@16: return std::equal_range(detail::begin_(r), detail::end_(r), val); Chris@16: } Chris@16: Chris@16: template Chris@16: typename result_of::equal_range::type Chris@16: operator()(R& r, T const& val) const Chris@16: { Chris@16: return execute(r, val, has_equal_range()); Chris@16: } Chris@16: Chris@16: template Chris@16: typename result_of::equal_range::type Chris@16: operator()(R& r, T const& val, C c) const Chris@16: { Chris@16: return std::equal_range(detail::begin_(r), detail::end_(r), val, c); Chris@16: } Chris@16: }; Chris@16: Chris@16: namespace result_of Chris@16: { Chris@16: template Chris@16: struct mismatch Chris@16: { Chris@16: typedef std::pair< Chris@16: typename range_result_iterator::type Chris@16: , typename detail::decay_array::type Chris@16: > type; Chris@16: }; Chris@16: } Chris@16: Chris@16: struct mismatch Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : result_of::mismatch Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : result_of::mismatch Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename result_of::mismatch::type Chris@16: operator()(R& r, I i) const Chris@16: { Chris@16: return std::mismatch(detail::begin_(r), detail::end_(r), i); Chris@16: } Chris@16: Chris@16: template Chris@16: typename result_of::mismatch::type Chris@16: operator()(R& r, I i, P p) const Chris@16: { Chris@16: return std::mismatch(detail::begin_(r), detail::end_(r), i, p); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct binary_search Chris@16: { Chris@16: typedef bool result_type; Chris@16: Chris@16: template Chris@16: bool operator()(R& r, T const& val) const Chris@16: { Chris@16: return std::binary_search(detail::begin_(r), detail::end_(r), val); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator()(R& r, T const& val, C c) const Chris@16: { Chris@16: return std::binary_search(detail::begin_(r), detail::end_(r), val, c); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct includes Chris@16: { Chris@16: typedef bool result_type; Chris@16: Chris@16: template Chris@16: bool operator()(R1& r1, R2& r2) const Chris@16: { Chris@16: return std::includes( Chris@16: detail::begin_(r1), detail::end_(r1) Chris@16: , detail::begin_(r2), detail::end_(r2) Chris@16: ); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator()(R1& r1, R2& r2, C c) const Chris@16: { Chris@16: return std::includes( Chris@16: detail::begin_(r1), detail::end_(r1) Chris@16: , detail::begin_(r2), detail::end_(r2) Chris@16: , c Chris@16: ); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct min_element Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r) const Chris@16: { Chris@16: return std::min_element(detail::begin_(r), detail::end_(r)); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, P p) const Chris@16: { Chris@16: return std::min_element(detail::begin_(r), detail::end_(r), p); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct max_element Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : range_result_iterator Chris@16: {}; Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r) const Chris@16: { Chris@16: return std::max_element(detail::begin_(r), detail::end_(r)); Chris@16: } Chris@16: Chris@16: template Chris@16: typename range_result_iterator::type Chris@16: operator()(R& r, P p) const Chris@16: { Chris@16: return std::max_element(detail::begin_(r), detail::end_(r), p); Chris@16: } Chris@16: }; Chris@16: Chris@16: struct lexicographical_compare Chris@16: { Chris@16: typedef bool result_type; Chris@16: Chris@16: template Chris@16: bool operator()(R1& r1, R2& r2) const Chris@16: { Chris@16: return std::lexicographical_compare( Chris@16: detail::begin_(r1), detail::end_(r1) Chris@16: , detail::begin_(r2), detail::end_(r2) Chris@16: ); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator()(R1& r1, R2& r2, P p) const Chris@16: { Chris@16: return std::lexicographical_compare( Chris@16: detail::begin_(r1), detail::end_(r1) Chris@16: , detail::begin_(r2), detail::end_(r2) Chris@16: , p Chris@16: ); Chris@16: } Chris@16: }; Chris@16: Chris@16: } Chris@16: Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(find, impl::find, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(find_if, impl::find_if, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(find_end, impl::find_end, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(find_end, impl::find_end, 3) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(find_first_of, impl::find_first_of, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(find_first_of, impl::find_first_of, 3) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(adjacent_find, impl::adjacent_find, 1) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(adjacent_find, impl::adjacent_find, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(count, impl::count, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(count_if, impl::count_if, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(distance, impl::distance, 1) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(equal, impl::equal, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(equal, impl::equal, 3) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(search, impl::search, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(search, impl::search, 3) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(lower_bound, impl::lower_bound, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(lower_bound, impl::lower_bound, 3) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(upper_bound, impl::upper_bound, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(upper_bound, impl::upper_bound, 3) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(equal_range, impl::equal_range, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(equal_range, impl::equal_range, 3) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(mismatch, impl::mismatch, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(mismatch, impl::mismatch, 3) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(binary_search, impl::binary_search, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(binary_search, impl::binary_search, 3) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(includes, impl::includes, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(includes, impl::includes, 3) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(min_element, impl::min_element, 1) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(min_element, impl::min_element, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(max_element, impl::max_element, 1) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(max_element, impl::max_element, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(lexicographical_compare, impl::lexicographical_compare, 2) Chris@16: BOOST_PHOENIX_ADAPT_CALLABLE(lexicographical_compare, impl::lexicographical_compare, 3) Chris@16: Chris@16: }} Chris@16: Chris@16: #endif