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