EVOLUTION-MANAGER
Edit File: lazy_operator.hpp
//////////////////////////////////////////////////////////////////////////// // lazy operator.hpp // // Build lazy operations for Phoenix equivalents for FC++ // // These are equivalents of the Boost FC++ functoids in operator.hpp // // Implemented so far: // // make_pair // plus minus multiplies divides modulus // negate equal not_equal greater less // greater_equal less_equal positive // logical_and logical_or // logical_not min max inc dec // // These are not from the FC++ operator.hpp but were made for testing purposes. // // identity (renamed id) // sin // // These are now being modified to use boost::phoenix::function // so that they are available for use as arguments. // Types are being defined in capitals e.g. Id id; //////////////////////////////////////////////////////////////////////////// /*============================================================================= Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis Copyright (c) 2001-2007 Joel de Guzman Copyright (c) 2015 John Fletcher 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_FUNCTION_LAZY_OPERATOR #define BOOST_PHOENIX_FUNCTION_LAZY_OPERATOR #include <cmath> #include <cstdlib> #include <boost/phoenix/core.hpp> #include <boost/phoenix/function.hpp> #include <boost/function.hpp> namespace boost { namespace phoenix { ////////////////////////////////////////////////////////////////////// // a_unique_type_for_nil ////////////////////////////////////////////////////////////////////// // This may need to be moved elsewhere to define reuser. struct a_unique_type_for_nil { bool operator==( a_unique_type_for_nil ) const { return true; } bool operator< ( a_unique_type_for_nil ) const { return false; } typedef a_unique_type_for_nil value_type; }; // This maybe put into a namespace. a_unique_type_for_nil NIL; ////////////////////////////////////////////////////////////////////// // lazy_exception - renamed from fcpp_exception. ////////////////////////////////////////////////////////////////////// #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS struct lazy_exception : public std::exception { const char* s; lazy_exception( const char* ss ) : s(ss) {} const char* what() const throw() { return s; } }; #endif ////////////////////////////////////////////////////////////////////// // in ref_count.hpp in BoostFC++ typedef unsigned int RefCountType; namespace impl { // Implemented early, moved from lazy_signature.hpp template <class T> struct remove_RC { typedef typename boost::remove_reference<T>::type TT; typedef typename boost::remove_const<TT>::type type; }; struct XId { template <typename Sig> struct result; template <typename This, typename A0> struct result<This(A0)> : boost::remove_reference<A0> {}; template <typename A0> A0 operator()(A0 const & a0) const { return a0; } }; } typedef boost::phoenix::function<impl::XId> Id; Id id; #ifdef BOOST_RESULT_OF_USE_TR1 // Experiment following examples in // phoenix/stl/container/container.hpp namespace result_of { template < typename Arg1 , typename Arg2 > class make_pair { public: typedef typename impl::remove_RC<Arg1>::type Arg1Type; typedef typename impl::remove_RC<Arg2>::type Arg2Type; typedef std::pair<Arg1Type,Arg2Type> type; typedef std::pair<Arg1Type,Arg2Type> result_type; }; } #endif namespace impl { struct XMake_pair { #ifdef BOOST_RESULT_OF_USE_TR1 template <typename Sig> struct result; // This fails with -O2 unless refs are removed from A1 and A2. template <typename This, typename A0, typename A1> struct result<This(A0, A1)> { typedef typename result_of::make_pair<A0,A1>::type type; }; #else template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0, A1)> : boost::remove_reference<std::pair<A0, A1> > {}; #endif template <typename A0, typename A1> #ifdef BOOST_RESULT_OF_USE_TR1 typename result<XMake_pair(A0,A1)>::type #else std::pair<A0, A1> #endif operator()(A0 const & a0, A1 const & a1) const { return std::make_pair(a0,a1); } }; } typedef boost::phoenix::function<impl::XMake_pair> Make_pair; Make_pair make_pair; namespace impl { // For now I will leave the return type deduction as it is. // I want to look at bringing in the sort of type deduction for // mixed types which I have in FC++. // Also I could look at the case where one of the arguments is // another functor or a Phoenix placeholder. struct XPlus { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0, A1)> : boost::remove_reference<A0> {}; template <typename This, typename A0, typename A1, typename A2> struct result<This(A0, A1, A2)> : boost::remove_reference<A0> {}; template <typename A0, typename A1> A0 operator()(A0 const & a0, A1 const & a1) const { //A0 res = a0 + a1; //return res; return a0 + a1; } template <typename A0, typename A1, typename A2> A0 operator()(A0 const & a0, A1 const & a1, A2 const & a2) const { return a0 + a1 + a2; } }; struct XMinus { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0, A1)> : boost::remove_reference<A0> {}; template <typename A0, typename A1> A0 operator()(A0 const & a0, A1 const & a1) const { return a0 - a1; } }; struct XMultiplies { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0, A1)> : boost::remove_reference<A0> {}; template <typename A0, typename A1> A0 operator()(A0 const & a0, A1 const & a1) const { return a0 * a1; } }; struct XDivides { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0, A1)> : boost::remove_reference<A0> {}; template <typename A0, typename A1> A0 operator()(A0 const & a0, A1 const & a1) const { return a0 / a1; } }; struct XModulus { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0, A1)> : boost::remove_reference<A0> {}; template <typename A0, typename A1> A0 operator()(A0 const & a0, A1 const & a1) const { return a0 % a1; } }; struct XNegate { template <typename Sig> struct result; template <typename This, typename A0> struct result<This(A0)> : boost::remove_reference<A0> {}; template <typename A0> A0 operator()(A0 const & a0) const { return -a0; } }; struct XEqual { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0,A1)> { typedef bool type; }; template <typename A0, typename A1> bool operator()(A0 const & a0, A1 const & a1) const { return a0 == a1; } }; struct XNot_equal { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0,A1)> { typedef bool type; }; template <typename A0, typename A1> bool operator()(A0 const & a0, A1 const & a1) const { return a0 != a1; } }; struct XGreater { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0,A1)> { typedef bool type; }; template <typename A0, typename A1> bool operator()(A0 const & a0, A1 const & a1) const { return a0 > a1; } }; struct XLess { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0,A1)> { typedef bool type; }; template <typename A0, typename A1> bool operator()(A0 const & a0, A1 const & a1) const { return a0 < a1; } }; struct XGreater_equal { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0,A1)> { typedef bool type; }; template <typename A0, typename A1> bool operator()(A0 const & a0, A1 const & a1) const { return a0 >= a1; } }; struct XLess_equal { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0,A1)> { typedef bool type; }; template <typename A0, typename A1> bool operator()(A0 const & a0, A1 const & a1) const { return a0 <= a1; } }; struct XPositive { template <typename Sig> struct result; template <typename This, typename A0> struct result<This(A0)> { typedef bool type; }; template <typename A0> bool operator()(A0 const & a0) const { return a0 >= A0(0); } }; struct XLogical_and { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0,A1)> { typedef bool type; }; template <typename A0, typename A1> bool operator()(A0 const & a0, A1 const & a1) const { return a0 && a1; } }; struct XLogical_or { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0,A1)> { typedef bool type; }; template <typename A0, typename A1> bool operator()(A0 const & a0, A1 const & a1) const { return a0 || a1; } }; struct XLogical_not { template <typename Sig> struct result; template <typename This, typename A0> struct result<This(A0)> { typedef bool type; }; template <typename A0> bool operator()(A0 const & a0) const { return !a0; } }; struct XMin { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0, A1)> : boost::remove_reference<A0> {}; template <typename A0, typename A1> A0 operator()(A0 const & a0, A1 const & a1) const { if ( a0 < a1 ) return a0; else return a1; } }; struct XMax { template <typename Sig> struct result; template <typename This, typename A0, typename A1> struct result<This(A0, A1)> : boost::remove_reference<A0> {}; template <typename A0, typename A1> A0 operator()(A0 const & a0, A1 const & a1) const { if ( a0 < a1 ) return a1; else return a0; } }; struct XInc { template <typename Sig> struct result; template <typename This, typename A0> struct result<This(A0)> : boost::remove_reference<A0> {}; template <typename A0> A0 operator()(A0 const & a0) const { return a0 + 1; } }; struct XDec { template <typename Sig> struct result; template <typename This, typename A0> struct result<This(A0)> : boost::remove_reference<A0> {}; template <typename A0> A0 operator()(A0 const & a0) const { return a0 - 1; } }; struct XSin { template <typename Sig> struct result; template <typename This, typename A0> struct result<This(A0)> : boost::remove_reference<A0> {}; template <typename A0> A0 operator()(A0 const & a0) const { return std::sin(a0); } }; // Example of templated struct. // How do I make it callable? template <typename Result> struct what { typedef Result result_type; Result operator()(Result const & r) const { return r; } // what is not complete - error. //static boost::function1<Result,Result> res = what<Result>(); }; template <typename Result> struct what0 { typedef Result result_type; Result operator()() const { return Result(100); } }; template <class Result, class F> class MonomorphicWrapper0 /* : public c_fun_type<Res> */ { F f; public: typedef Result result_type; MonomorphicWrapper0( const F& g ) : f(g) {} Result operator()() const { return f(); } }; } ///////////////////////////////////////////////////////// // Look at this. How to use Phoenix with a templated // struct. First adapt with boost::function and then // convert that to Phoenix!! // I have not found out how to do it directly. ///////////////////////////////////////////////////////// boost::function1<int, int > what_int = impl::what<int>(); typedef boost::function1<int,int> fun1_int_int; typedef boost::function0<int> fun0_int; boost::function0<int> what0_int = impl::what0<int>(); BOOST_PHOENIX_ADAPT_FUNCTION(int,what,what_int,1) BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY(int,what0,what0_int) // And this shows how to make them into argument callable functions. typedef boost::phoenix::function<fun1_int_int> What_arg; typedef boost::phoenix::function<fun0_int> What0_arg; What_arg what_arg(what_int); What0_arg what0_arg(what0_int); // To use these as arguments they have to be defined like this. typedef boost::phoenix::function<impl::XPlus> Plus; typedef boost::phoenix::function<impl::XMinus> Minus; typedef boost::phoenix::function<impl::XMultiplies> Multiplies; typedef boost::phoenix::function<impl::XDivides> Divides; typedef boost::phoenix::function<impl::XModulus> Modulus; typedef boost::phoenix::function<impl::XNegate> Negate; typedef boost::phoenix::function<impl::XEqual> Equal; typedef boost::phoenix::function<impl::XNot_equal> Not_equal; typedef boost::phoenix::function<impl::XGreater> Greater; typedef boost::phoenix::function<impl::XLess> Less; typedef boost::phoenix::function<impl::XGreater_equal> Greater_equal; typedef boost::phoenix::function<impl::XLess_equal> Less_equal; typedef boost::phoenix::function<impl::XPositive> Positive; typedef boost::phoenix::function<impl::XLogical_and> Logical_and; typedef boost::phoenix::function<impl::XLogical_or> Logical_or; typedef boost::phoenix::function<impl::XLogical_not> Logical_not; typedef boost::phoenix::function<impl::XMax> Max; typedef boost::phoenix::function<impl::XMin> Min; typedef boost::phoenix::function<impl::XInc> Inc; typedef boost::phoenix::function<impl::XDec> Dec; typedef boost::phoenix::function<impl::XSin> Sin; Plus plus; Minus minus; Multiplies multiplies; Divides divides; Modulus modulus; Negate negate; Equal equal; Not_equal not_equal; Greater greater; Less less; Greater_equal greater_equal; Less_equal less_equal; Positive positive; Logical_and logical_and; Logical_or logical_or; Logical_not logical_not; Max max; Min min; Inc inc; Dec dec; Sin sin; } } #endif