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 | ||
|  | 
 |