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