162 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
/*==============================================================================
 | 
						|
    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/bool.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
 | 
						|
                      , typename proto::arity_of<Expr1>::type()
 | 
						|
                    );
 | 
						|
            }
 | 
						|
 | 
						|
            private:
 | 
						|
            #include <boost/phoenix/core/detail/cpp03/function_equal.hpp>
 | 
						|
#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>
 | 
						|
            result_type
 | 
						|
            evaluate(Expr1 const& /*e1*/, Expr1 const& /*e2*/, index_sequence<>) const
 | 
						|
            {
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
            template <typename Expr1, std::size_t Head, std::size_t... Tail>
 | 
						|
            result_type
 | 
						|
            evaluate(Expr1 const& e1, Expr1 const& e2, index_sequence<Head, Tail...>) const
 | 
						|
            {
 | 
						|
                return
 | 
						|
                  function_equal_()(proto::child_c<Head>(e1), proto::child_c<Head>(e2)) &&
 | 
						|
                  this->evaluate(
 | 
						|
                      e1
 | 
						|
                    , e2
 | 
						|
                    , index_sequence<Tail...>()
 | 
						|
                  );
 | 
						|
            }
 | 
						|
#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
 | 
						|
 |