Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:45:07

0001 /*==============================================================================
0002     Copyright (c) 2005-2010 Joel de Guzman
0003     Copyright (c) 2010 Thomas Heller
0004 
0005     Distributed under the Boost Software License, Version 1.0. (See accompanying
0006     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 ==============================================================================*/
0008 #ifndef BOOST_PHOENIX_CORE_FUNCTION_EQUAL_HPP
0009 #define BOOST_PHOENIX_CORE_FUNCTION_EQUAL_HPP
0010 
0011 #include <boost/phoenix/core/limits.hpp>
0012 #include <boost/is_placeholder.hpp>
0013 #include <boost/mpl/int.hpp>
0014 #include <boost/phoenix/core/terminal.hpp>
0015 #include <boost/proto/matches.hpp>
0016 
0017 #ifndef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EQUAL
0018 #   include <boost/phoenix/core/detail/index_sequence.hpp>
0019 #endif
0020 
0021 namespace boost
0022 {
0023     template <typename> class weak_ptr;
0024 }
0025 
0026 namespace boost { namespace phoenix
0027 {
0028     template <typename>
0029     struct actor;
0030 
0031     namespace detail
0032     {
0033         struct compare
0034             : proto::callable
0035         {
0036             typedef bool result_type;
0037 
0038             template <typename A0, typename A1>
0039             result_type operator()(A0 const & a0, A1 const & a1) const
0040             {
0041                 return a0 == a1;
0042             }
0043 
0044             // hard wiring reference_wrapper and weak_ptr here ...
0045             // **TODO** find out why boost bind does this ...
0046             template <typename A0, typename A1>
0047             result_type
0048             operator()(
0049                 reference_wrapper<A0> const & a0
0050               , reference_wrapper<A1> const & a1
0051             ) const
0052             {
0053                 return a0.get_pointer() == a1.get_pointer();
0054             }
0055 
0056             template <typename A0, typename A1>
0057             result_type
0058             operator()(weak_ptr<A0> const & a0, weak_ptr<A1> const & a1) const
0059             {
0060                 return !(a0 < a1) && !(a1 < a0);
0061             }
0062         };
0063 
0064         struct function_equal_otherwise;
0065 
0066         struct function_equal_
0067             : proto::when<
0068                 proto::if_<
0069                     proto::matches<proto::_, proto::_state>()
0070                   , proto::or_<
0071                         proto::when<
0072                             proto::terminal<proto::_>
0073                           , compare(
0074                                 proto::_value
0075                               , proto::call<
0076                                     proto::_value(proto::_state)
0077                                 >
0078                             )
0079                         >
0080                       , proto::otherwise<function_equal_otherwise(proto::_, proto::_state)>
0081                     >
0082                   , proto::call<function_equal_otherwise()>
0083                 >
0084             >
0085         {};
0086 
0087         struct function_equal_otherwise
0088             : proto::callable
0089         {
0090             typedef bool result_type;
0091 
0092             result_type operator()() const
0093             {
0094                 return false;
0095             }
0096 
0097 #ifdef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EQUAL
0098             template <typename Expr1>
0099             result_type operator()(Expr1 const& e1, Expr1 const& e2) const
0100             {
0101                 return
0102                     this->evaluate(
0103                         e1
0104                       , e2
0105                       , mpl::int_<proto::arity_of<Expr1>::value - 1>()
0106                     );
0107             }
0108 
0109         private:
0110             template <typename Expr1>
0111             static BOOST_FORCEINLINE result_type
0112             evaluate(Expr1 const& e1, Expr1 const& e2, mpl::int_<0>)
0113             {
0114                 return
0115                     function_equal_()(
0116                         proto::child_c<0>(e1)
0117                       , proto::child_c<0>(e2)
0118                     );
0119             }
0120 
0121             template <typename Expr1, int N>
0122             static BOOST_FORCEINLINE result_type
0123             evaluate(Expr1 const& e1, Expr1 const& e2, mpl::int_<N>)
0124             {
0125                 return
0126                     evaluate(
0127                         e1
0128                       , e2
0129                       , mpl::int_<N - 1>()
0130                     ) && function_equal_()(
0131                         proto::child_c<N>(e1)
0132                       , proto::child_c<N>(e2)
0133                     );
0134             }
0135 #else
0136             template <typename Expr1>
0137             result_type operator()(Expr1 const& e1, Expr1 const& e2) const
0138             {
0139                 return
0140                     this->evaluate(
0141                         e1
0142                       , e2
0143                       , typename make_index_sequence<proto::arity_of<Expr1>::value>::type()
0144                     );
0145             }
0146 
0147         private:
0148             template <typename Expr1, std::size_t... I>
0149             static BOOST_FORCEINLINE result_type
0150             evaluate(Expr1 const& e1, Expr1 const& e2, index_sequence<I...>)
0151             {
0152                 bool result = true;
0153                 int dummy[] = { (result && (
0154                         result = function_equal_()(proto::child_c<I>(e1), proto::child_c<I>(e2))
0155                     ))... };
0156                 (void)dummy;
0157                 return result;
0158             }
0159 #endif
0160         };
0161     }
0162 
0163     template <typename Expr1, typename Expr2>
0164     inline bool function_equal_impl(actor<Expr1> const& a1, actor<Expr2> const& a2)
0165     {
0166         return detail::function_equal_()(a1, a2);
0167     }
0168 
0169     template <typename Expr1, typename Expr2>
0170     inline bool function_equal(actor<Expr1> const& a1, actor<Expr2> const& a2)
0171     {
0172         return function_equal_impl(a1, a2);
0173     }
0174 
0175 }}
0176 
0177 #endif
0178