Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/phoenix/function/lazy_operator.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 ////////////////////////////////////////////////////////////////////////////
0002 // lazy operator.hpp
0003 //
0004 // Build lazy operations for Phoenix equivalents for FC++
0005 //
0006 // These are equivalents of the Boost FC++ functoids in operator.hpp
0007 //
0008 // Implemented so far:
0009 //
0010 // make_pair
0011 // plus minus multiplies divides modulus
0012 // negate equal not_equal greater less
0013 // greater_equal less_equal positive
0014 // logical_and logical_or
0015 // logical_not min max inc dec
0016 //
0017 // These are not from the FC++ operator.hpp but were made for testing purposes.
0018 //
0019 // identity (renamed id)
0020 // sin
0021 //
0022 // These are now being modified to use boost::phoenix::function
0023 // so that they are available for use as arguments.
0024 // Types are being defined in capitals e.g. Id id;
0025 ////////////////////////////////////////////////////////////////////////////
0026 /*=============================================================================
0027     Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis
0028     Copyright (c) 2001-2007 Joel de Guzman
0029     Copyright (c) 2015 John Fletcher
0030 
0031     Distributed under the Boost Software License, Version 1.0. (See accompanying
0032     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0033 ==============================================================================*/
0034 
0035 
0036 #ifndef BOOST_PHOENIX_FUNCTION_LAZY_OPERATOR
0037 #define BOOST_PHOENIX_FUNCTION_LAZY_OPERATOR
0038 
0039 #include <cmath>
0040 #include <cstdlib>
0041 #include <boost/phoenix/core.hpp>
0042 #include <boost/phoenix/function.hpp>
0043 #include <boost/function.hpp>
0044 
0045 namespace boost {
0046 
0047   namespace phoenix {
0048 
0049 //////////////////////////////////////////////////////////////////////
0050 // a_unique_type_for_nil
0051 //////////////////////////////////////////////////////////////////////
0052 
0053 // This may need to be moved elsewhere to define reuser.
0054    struct a_unique_type_for_nil {
0055      bool operator==( a_unique_type_for_nil ) const { return true; }
0056      bool operator< ( a_unique_type_for_nil ) const { return false; }
0057      typedef a_unique_type_for_nil value_type;
0058    };
0059     // This maybe put into a namespace.
0060    a_unique_type_for_nil NIL;
0061 
0062 //////////////////////////////////////////////////////////////////////
0063 // lazy_exception - renamed from fcpp_exception.
0064 //////////////////////////////////////////////////////////////////////
0065 
0066 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
0067    struct lazy_exception : public std::exception {
0068        const char* s;
0069        lazy_exception( const char* ss ) : s(ss) {}
0070        const char* what() const throw() { return s; }
0071    };
0072 #endif
0073 
0074 //////////////////////////////////////////////////////////////////////
0075 
0076    // in ref_count.hpp in BoostFC++
0077    typedef unsigned int RefCountType;
0078 
0079     namespace impl {
0080 
0081       // Implemented early, moved from lazy_signature.hpp
0082       template <class T>
0083       struct remove_RC
0084       {
0085           typedef typename boost::remove_reference<T>::type TT;
0086           typedef typename boost::remove_const<TT>::type type;
0087       };
0088 
0089       struct XId
0090       {
0091         template <typename Sig>
0092         struct result;
0093 
0094         template <typename This, typename A0>
0095         struct result<This(A0)>
0096            : boost::remove_reference<A0>
0097         {};
0098 
0099         template <typename A0>
0100         A0 operator()(A0 const & a0) const
0101         {
0102             return a0;
0103         }
0104 
0105       };
0106 
0107 
0108     }
0109 
0110     typedef boost::phoenix::function<impl::XId> Id;
0111     Id id;
0112 
0113 #ifdef BOOST_RESULT_OF_USE_TR1
0114     // Experiment following examples in
0115     // phoenix/stl/container/container.hpp
0116 
0117     namespace result_of {
0118 
0119       template <
0120           typename Arg1
0121         , typename Arg2
0122       >
0123       class make_pair
0124       {
0125       public:
0126         typedef typename impl::remove_RC<Arg1>::type Arg1Type;
0127         typedef typename impl::remove_RC<Arg2>::type Arg2Type;
0128         typedef std::pair<Arg1Type,Arg2Type> type;
0129         typedef std::pair<Arg1Type,Arg2Type> result_type;
0130       };
0131     }
0132 #endif
0133 
0134   namespace impl
0135   {
0136 
0137     struct XMake_pair {
0138 
0139 
0140 #ifdef BOOST_RESULT_OF_USE_TR1
0141        template <typename Sig>
0142        struct result;
0143        // This fails with -O2 unless refs are removed from A1 and A2.
0144        template <typename This, typename A0, typename A1>
0145        struct result<This(A0, A1)>
0146        {
0147          typedef typename result_of::make_pair<A0,A1>::type type;
0148        };
0149 #else
0150        template <typename Sig>
0151        struct result;
0152 
0153        template <typename This, typename A0, typename A1>
0154        struct result<This(A0, A1)>
0155          : boost::remove_reference<std::pair<A0, A1> >
0156        {};
0157       
0158 #endif
0159 
0160 
0161        template <typename A0, typename A1>
0162 #ifdef BOOST_RESULT_OF_USE_TR1
0163        typename result<XMake_pair(A0,A1)>::type
0164 #else
0165        std::pair<A0, A1>
0166 #endif
0167        operator()(A0 const & a0, A1 const & a1) const
0168        {
0169           return std::make_pair(a0,a1);
0170        }
0171 
0172     };
0173   }
0174 
0175   typedef boost::phoenix::function<impl::XMake_pair> Make_pair;
0176   Make_pair make_pair;
0177 
0178   namespace impl
0179   {
0180 
0181     // For now I will leave the return type deduction as it is.
0182     // I want to look at bringing in the sort of type deduction for
0183     // mixed types which I have in FC++.
0184     // Also I could look at the case where one of the arguments is
0185     // another functor or a Phoenix placeholder.
0186     struct XPlus
0187     {
0188         template <typename Sig>
0189         struct result;
0190 
0191         template <typename This, typename A0, typename A1>
0192         struct result<This(A0, A1)>
0193              : boost::remove_reference<A0>
0194         {};
0195 
0196         template <typename This, typename A0, typename A1, typename A2>
0197         struct result<This(A0, A1, A2)>
0198              : boost::remove_reference<A0>
0199         {};
0200 
0201         template <typename A0, typename A1>
0202         A0 operator()(A0 const & a0, A1 const & a1) const
0203         {
0204           //A0 res = a0 + a1;
0205           //return res;
0206           return a0 + a1;
0207         }
0208 
0209         template <typename A0, typename A1, typename A2>
0210         A0 operator()(A0 const & a0, A1 const & a1, A2 const & a2) const
0211         {
0212             return a0 + a1 + a2;
0213         }
0214     };
0215 
0216     struct XMinus
0217     {
0218         template <typename Sig>
0219         struct result;
0220 
0221         template <typename This, typename A0, typename A1>
0222         struct result<This(A0, A1)>
0223            : boost::remove_reference<A0>
0224         {};
0225 
0226         template <typename A0, typename A1>
0227         A0 operator()(A0 const & a0, A1 const & a1) const
0228         {
0229             return a0 - a1;
0230         }
0231 
0232     };
0233 
0234     struct XMultiplies
0235     {
0236         template <typename Sig>
0237         struct result;
0238 
0239         template <typename This, typename A0, typename A1>
0240         struct result<This(A0, A1)>
0241            : boost::remove_reference<A0>
0242         {};
0243 
0244         template <typename A0, typename A1>
0245         A0 operator()(A0 const & a0, A1 const & a1) const
0246         {
0247             return a0 * a1;
0248         }
0249 
0250     };
0251 
0252     struct XDivides
0253     {
0254         template <typename Sig>
0255         struct result;
0256 
0257         template <typename This, typename A0, typename A1>
0258         struct result<This(A0, A1)>
0259            : boost::remove_reference<A0>
0260         {};
0261 
0262         template <typename A0, typename A1>
0263         A0 operator()(A0 const & a0, A1 const & a1) const
0264         {
0265             return a0 / a1;
0266         }
0267 
0268     };
0269 
0270     struct XModulus
0271     {
0272         template <typename Sig>
0273         struct result;
0274 
0275         template <typename This, typename A0, typename A1>
0276         struct result<This(A0, A1)>
0277           : boost::remove_reference<A0>
0278         {};
0279 
0280         template <typename A0, typename A1>
0281         A0 operator()(A0 const & a0, A1 const & a1) const
0282         {
0283             return a0 % a1;
0284         }
0285 
0286     };
0287 
0288     struct XNegate
0289     {
0290         template <typename Sig>
0291         struct result;
0292 
0293         template <typename This, typename A0>
0294         struct result<This(A0)>
0295            : boost::remove_reference<A0>
0296         {};
0297 
0298         template <typename A0>
0299         A0 operator()(A0 const & a0) const
0300         {
0301             return -a0;
0302         }
0303     };
0304 
0305     struct XEqual
0306     {
0307         template <typename Sig>
0308         struct result;
0309 
0310         template <typename This, typename A0, typename A1>
0311         struct result<This(A0,A1)>
0312         {
0313             typedef bool type;
0314         };
0315 
0316         template <typename A0, typename A1>
0317         bool operator()(A0 const & a0, A1 const & a1) const
0318         {
0319             return a0 == a1;
0320         }
0321     };
0322 
0323     struct XNot_equal
0324     {
0325         template <typename Sig>
0326         struct result;
0327 
0328         template <typename This, typename A0, typename A1>
0329         struct result<This(A0,A1)>
0330         {
0331             typedef bool type;
0332         };
0333 
0334         template <typename A0, typename A1>
0335         bool operator()(A0 const & a0, A1 const & a1) const
0336         {
0337             return a0 != a1;
0338         }
0339     };
0340 
0341     struct XGreater
0342     {
0343         template <typename Sig>
0344         struct result;
0345 
0346         template <typename This, typename A0, typename A1>
0347         struct result<This(A0,A1)>
0348         {
0349             typedef bool type;
0350         };
0351 
0352         template <typename A0, typename A1>
0353         bool operator()(A0 const & a0, A1 const & a1) const
0354         {
0355             return a0 > a1;
0356         }
0357     };
0358 
0359     struct XLess
0360     {
0361         template <typename Sig>
0362         struct result;
0363 
0364         template <typename This, typename A0, typename A1>
0365         struct result<This(A0,A1)>
0366         {
0367             typedef bool type;
0368         };
0369 
0370         template <typename A0, typename A1>
0371         bool operator()(A0 const & a0, A1 const & a1) const
0372         {
0373             return a0 < a1;
0374         }
0375     };
0376 
0377     struct XGreater_equal
0378     {
0379         template <typename Sig>
0380         struct result;
0381 
0382         template <typename This, typename A0, typename A1>
0383         struct result<This(A0,A1)>
0384         {
0385             typedef bool type;
0386         };
0387 
0388         template <typename A0, typename A1>
0389         bool operator()(A0 const & a0, A1 const & a1) const
0390         {
0391             return a0 >= a1;
0392         }
0393     };
0394 
0395     struct XLess_equal
0396     {
0397         template <typename Sig>
0398         struct result;
0399 
0400         template <typename This, typename A0, typename A1>
0401         struct result<This(A0,A1)>
0402         {
0403             typedef bool type;
0404         };
0405 
0406         template <typename A0, typename A1>
0407         bool operator()(A0 const & a0, A1 const & a1) const
0408         {
0409             return a0 <= a1;
0410         }
0411     };
0412 
0413     struct XPositive
0414     {
0415         template <typename Sig>
0416         struct result;
0417 
0418         template <typename This, typename A0>
0419         struct result<This(A0)>
0420         {
0421             typedef bool type;
0422         };
0423 
0424         template <typename A0>
0425         bool operator()(A0 const & a0) const
0426         {
0427           return a0 >= A0(0);
0428         }
0429     };
0430 
0431     struct XLogical_and
0432     {
0433         template <typename Sig>
0434         struct result;
0435 
0436         template <typename This, typename A0, typename A1>
0437         struct result<This(A0,A1)>
0438         {
0439             typedef bool type;
0440         };
0441 
0442         template <typename A0, typename A1>
0443         bool operator()(A0 const & a0, A1 const & a1) const
0444         {
0445             return a0 && a1;
0446         }
0447     };
0448 
0449     struct XLogical_or
0450     {
0451         template <typename Sig>
0452         struct result;
0453 
0454         template <typename This, typename A0, typename A1>
0455         struct result<This(A0,A1)>
0456         {
0457             typedef bool type;
0458         };
0459 
0460         template <typename A0, typename A1>
0461         bool operator()(A0 const & a0, A1 const & a1) const
0462         {
0463             return a0 || a1;
0464         }
0465     };
0466 
0467     struct XLogical_not
0468     {
0469         template <typename Sig>
0470         struct result;
0471 
0472         template <typename This, typename A0>
0473         struct result<This(A0)>
0474         {
0475              typedef bool type;
0476         };
0477 
0478         template <typename A0>
0479         bool operator()(A0 const & a0) const
0480         {
0481             return !a0;
0482         }
0483     };
0484 
0485     struct XMin
0486     {
0487         template <typename Sig>
0488         struct result;
0489 
0490         template <typename This, typename A0, typename A1>
0491         struct result<This(A0, A1)>
0492           : boost::remove_reference<A0>
0493         {};
0494 
0495         template <typename A0, typename A1>
0496         A0 operator()(A0 const & a0, A1 const & a1) const
0497         {
0498            if ( a0 < a1 ) return a0; else return a1;
0499         }
0500 
0501     };
0502 
0503     struct XMax
0504     {
0505         template <typename Sig>
0506         struct result;
0507 
0508         template <typename This, typename A0, typename A1>
0509         struct result<This(A0, A1)>
0510           : boost::remove_reference<A0>
0511         {};
0512 
0513         template <typename A0, typename A1>
0514         A0 operator()(A0 const & a0, A1 const & a1) const
0515         {
0516            if ( a0 < a1 ) return a1; else return a0;
0517         }
0518 
0519     };
0520 
0521     struct XInc
0522     {
0523         template <typename Sig>
0524         struct result;
0525 
0526         template <typename This, typename A0>
0527         struct result<This(A0)>
0528            : boost::remove_reference<A0>
0529         {};
0530 
0531         template <typename A0>
0532         A0 operator()(A0 const & a0) const
0533         {
0534             return a0 + 1;
0535         }
0536 
0537     };
0538 
0539     struct XDec
0540     {
0541         template <typename Sig>
0542         struct result;
0543 
0544         template <typename This, typename A0>
0545         struct result<This(A0)>
0546            : boost::remove_reference<A0>
0547         {};
0548 
0549         template <typename A0>
0550         A0 operator()(A0 const & a0) const
0551         {
0552             return a0 - 1;
0553         }
0554 
0555     };
0556 
0557     struct XSin
0558     {
0559         template <typename Sig>
0560         struct result;
0561 
0562         template <typename This, typename A0>
0563         struct result<This(A0)>
0564            : boost::remove_reference<A0>
0565         {};
0566 
0567         template <typename A0>
0568         A0 operator()(A0 const & a0) const
0569         {
0570           return std::sin(a0);
0571         }
0572 
0573     };
0574 
0575     // Example of templated struct.
0576     // How do I make it callable?
0577     template <typename Result>
0578     struct what {
0579 
0580       typedef Result result_type;
0581 
0582       Result operator()(Result const & r) const
0583       {
0584         return r;
0585       }
0586       // what is not complete - error.
0587       //static boost::function1<Result,Result> res = what<Result>();
0588     };
0589 
0590     template <typename Result>
0591     struct what0 {
0592 
0593       typedef Result result_type;
0594 
0595       Result operator()() const
0596       {
0597         return Result(100);
0598       }
0599 
0600     };
0601 
0602 
0603       template <class Result, class F>
0604       class MonomorphicWrapper0 /* : public c_fun_type<Res> */
0605       {
0606           F f;
0607       public:
0608           typedef Result result_type;
0609           MonomorphicWrapper0( const F& g ) : f(g) {}
0610              Result operator()() const {
0611              return f();
0612           }
0613       };
0614 
0615   }
0616     /////////////////////////////////////////////////////////
0617     // Look at this. How to use Phoenix with a templated
0618     // struct. First adapt with boost::function and then
0619     // convert that to Phoenix!!
0620     // I have not found out how to do it directly.
0621     /////////////////////////////////////////////////////////
0622 boost::function1<int, int > what_int = impl::what<int>();
0623 typedef boost::function1<int,int> fun1_int_int;
0624 typedef boost::function0<int> fun0_int;
0625 boost::function0<int> what0_int = impl::what0<int>();
0626 BOOST_PHOENIX_ADAPT_FUNCTION(int,what,what_int,1)
0627 BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY(int,what0,what0_int)
0628 // And this shows how to make them into argument callable functions.
0629 typedef boost::phoenix::function<fun1_int_int> What_arg;
0630 typedef boost::phoenix::function<fun0_int> What0_arg;
0631 What_arg what_arg(what_int);
0632 What0_arg what0_arg(what0_int);
0633 
0634 
0635 // To use these as arguments they have to be defined like this.
0636     typedef boost::phoenix::function<impl::XPlus> Plus;
0637     typedef boost::phoenix::function<impl::XMinus> Minus;
0638     typedef boost::phoenix::function<impl::XMultiplies> Multiplies;
0639     typedef boost::phoenix::function<impl::XDivides>   Divides;
0640     typedef boost::phoenix::function<impl::XModulus>   Modulus;
0641     typedef boost::phoenix::function<impl::XNegate>    Negate;
0642     typedef boost::phoenix::function<impl::XEqual>     Equal;
0643     typedef boost::phoenix::function<impl::XNot_equal> Not_equal;
0644     typedef boost::phoenix::function<impl::XGreater>   Greater;
0645     typedef boost::phoenix::function<impl::XLess>      Less;
0646     typedef boost::phoenix::function<impl::XGreater_equal> Greater_equal;
0647     typedef boost::phoenix::function<impl::XLess_equal>    Less_equal;
0648     typedef boost::phoenix::function<impl::XPositive>    Positive;
0649     typedef boost::phoenix::function<impl::XLogical_and> Logical_and;
0650     typedef boost::phoenix::function<impl::XLogical_or>  Logical_or;
0651     typedef boost::phoenix::function<impl::XLogical_not> Logical_not;
0652     typedef boost::phoenix::function<impl::XMax> Max;
0653     typedef boost::phoenix::function<impl::XMin> Min;
0654     typedef boost::phoenix::function<impl::XInc> Inc;
0655     typedef boost::phoenix::function<impl::XDec> Dec;
0656     typedef boost::phoenix::function<impl::XSin> Sin;
0657     Plus plus;
0658     Minus minus;
0659     Multiplies multiplies;
0660     Divides divides;
0661     Modulus modulus;
0662     Negate  negate;
0663     Equal   equal;
0664     Not_equal not_equal;
0665     Greater greater;
0666     Less    less;
0667     Greater_equal greater_equal;
0668     Less_equal    less_equal;
0669     Positive      positive;
0670     Logical_and   logical_and;
0671     Logical_or    logical_or;
0672     Logical_not   logical_not;
0673     Max max;
0674     Min min;
0675     Inc inc;
0676     Dec dec;
0677     Sin sin;
0678 }
0679 
0680 }
0681 
0682 
0683 #endif