123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- /*==============================================================================
- Copyright (c) 2005-2010 Joel de Guzman
- Copyright (c) 2010 Thomas Heller
- Distributed under 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)
- ==============================================================================*/
- #ifndef BOOST_PHOENIX_CORE_FUNCTION_EQUAL_HPP
- #define BOOST_PHOENIX_CORE_FUNCTION_EQUAL_HPP
- #include <boost/phoenix/core/limits.hpp>
- #include <boost/is_placeholder.hpp>
- #include <boost/mpl/int.hpp>
- #include <boost/phoenix/core/terminal.hpp>
- #include <boost/proto/matches.hpp>
- #ifndef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EQUAL
- # include <boost/phoenix/core/detail/index_sequence.hpp>
- #endif
- namespace boost
- {
- template <typename> class weak_ptr;
- }
- namespace boost { namespace phoenix
- {
- template <typename>
- struct actor;
- namespace detail
- {
- struct compare
- : proto::callable
- {
- typedef bool result_type;
- template <typename A0, typename A1>
- result_type operator()(A0 const & a0, A1 const & a1) const
- {
- return a0 == a1;
- }
- // hard wiring reference_wrapper and weak_ptr here ...
- // **TODO** find out why boost bind does this ...
- template <typename A0, typename A1>
- result_type
- operator()(
- reference_wrapper<A0> const & a0
- , reference_wrapper<A1> const & a1
- ) const
- {
- return a0.get_pointer() == a1.get_pointer();
- }
- template <typename A0, typename A1>
- result_type
- operator()(weak_ptr<A0> const & a0, weak_ptr<A1> const & a1) const
- {
- return !(a0 < a1) && !(a1 < a0);
- }
- };
- struct function_equal_otherwise;
- struct function_equal_
- : proto::when<
- proto::if_<
- proto::matches<proto::_, proto::_state>()
- , proto::or_<
- proto::when<
- proto::terminal<proto::_>
- , compare(
- proto::_value
- , proto::call<
- proto::_value(proto::_state)
- >
- )
- >
- , proto::otherwise<function_equal_otherwise(proto::_, proto::_state)>
- >
- , proto::call<function_equal_otherwise()>
- >
- >
- {};
- struct function_equal_otherwise
- : proto::callable
- {
- typedef bool result_type;
- result_type operator()() const
- {
- return false;
- }
- #ifdef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EQUAL
- template <typename Expr1>
- result_type operator()(Expr1 const& e1, Expr1 const& e2) const
- {
- return
- this->evaluate(
- e1
- , e2
- , mpl::int_<proto::arity_of<Expr1>::value - 1>()
- );
- }
- private:
- template <typename Expr1>
- static BOOST_FORCEINLINE result_type
- evaluate(Expr1 const& e1, Expr1 const& e2, mpl::int_<0>)
- {
- return
- function_equal_()(
- proto::child_c<0>(e1)
- , proto::child_c<0>(e2)
- );
- }
- template <typename Expr1, int N>
- static BOOST_FORCEINLINE result_type
- evaluate(Expr1 const& e1, Expr1 const& e2, mpl::int_<N>)
- {
- return
- evaluate(
- e1
- , e2
- , mpl::int_<N - 1>()
- ) && function_equal_()(
- proto::child_c<N>(e1)
- , proto::child_c<N>(e2)
- );
- }
- #else
- template <typename Expr1>
- result_type operator()(Expr1 const& e1, Expr1 const& e2) const
- {
- return
- this->evaluate(
- e1
- , e2
- , typename make_index_sequence<proto::arity_of<Expr1>::value>::type()
- );
- }
- private:
- template <typename Expr1, std::size_t... I>
- static BOOST_FORCEINLINE result_type
- evaluate(Expr1 const& e1, Expr1 const& e2, index_sequence<I...>)
- {
- bool result = true;
- int dummy[] = { (result && (
- result = function_equal_()(proto::child_c<I>(e1), proto::child_c<I>(e2))
- ))... };
- (void)dummy;
- return result;
- }
- #endif
- };
- }
- template <typename Expr1, typename Expr2>
- inline bool function_equal_impl(actor<Expr1> const& a1, actor<Expr2> const& a2)
- {
- return detail::function_equal_()(a1, a2);
- }
- template <typename Expr1, typename Expr2>
- inline bool function_equal(actor<Expr1> const& a1, actor<Expr2> const& a2)
- {
- return function_equal_impl(a1, a2);
- }
- }}
- #endif
|