1 ////////////////////////////////////////////////////////////////////////////
4 // Build lazy operations for Phoenix equivalents for FC++
6 // These are equivalents of the Boost FC++ functoids in operator.hpp
11 // plus minus multiplies divides modulus
12 // negate equal not_equal greater less
13 // greater_equal less_equal positive
14 // logical_and logical_or
15 // logical_not min max inc dec
17 // These are not from the FC++ operator.hpp but were made for testing purposes.
19 // identity (renamed id)
22 // These are now being modified to use boost::phoenix::function
23 // so that they are available for use as arguments.
24 // Types are being defined in capitals e.g. Id id;
25 ////////////////////////////////////////////////////////////////////////////
26 /*=============================================================================
27 Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis
28 Copyright (c) 2001-2007 Joel de Guzman
29 Copyright (c) 2015 John Fletcher
31 Distributed under the Boost Software License, Version 1.0. (See accompanying
32 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
33 ==============================================================================*/
36 #ifndef BOOST_PHOENIX_FUNCTION_LAZY_OPERATOR
37 #define BOOST_PHOENIX_FUNCTION_LAZY_OPERATOR
41 #include <boost/phoenix/core.hpp>
42 #include <boost/phoenix/function.hpp>
43 #include <boost/function.hpp>
49 //////////////////////////////////////////////////////////////////////
50 // a_unique_type_for_nil
51 //////////////////////////////////////////////////////////////////////
53 // This may need to be moved elsewhere to define reuser.
54 struct a_unique_type_for_nil {
55 bool operator==( a_unique_type_for_nil ) const { return true; }
56 bool operator< ( a_unique_type_for_nil ) const { return false; }
57 typedef a_unique_type_for_nil value_type;
59 // This maybe put into a namespace.
60 a_unique_type_for_nil NIL;
62 //////////////////////////////////////////////////////////////////////
63 // lazy_exception - renamed from fcpp_exception.
64 //////////////////////////////////////////////////////////////////////
66 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
67 struct lazy_exception : public std::exception {
69 lazy_exception( const char* ss ) : s(ss) {}
70 const char* what() const throw() { return s; }
74 //////////////////////////////////////////////////////////////////////
76 // in ref_count.hpp in BoostFC++
77 typedef unsigned int RefCountType;
81 // Implemented early, moved from lazy_signature.hpp
85 typedef typename boost::remove_reference<T>::type TT;
86 typedef typename boost::remove_const<TT>::type type;
91 template <typename Sig>
94 template <typename This, typename A0>
95 struct result<This(A0)>
96 : boost::remove_reference<A0>
99 template <typename A0>
100 A0 operator()(A0 const & a0) const
110 typedef boost::phoenix::function<impl::XId> Id;
113 #ifdef BOOST_RESULT_OF_USE_TR1
114 // Experiment following examples in
115 // phoenix/stl/container/container.hpp
117 namespace result_of {
126 typedef typename impl::remove_RC<Arg1>::type Arg1Type;
127 typedef typename impl::remove_RC<Arg2>::type Arg2Type;
128 typedef std::pair<Arg1Type,Arg2Type> type;
129 typedef std::pair<Arg1Type,Arg2Type> result_type;
140 #ifdef BOOST_RESULT_OF_USE_TR1
141 template <typename Sig>
143 // This fails with -O2 unless refs are removed from A1 and A2.
144 template <typename This, typename A0, typename A1>
145 struct result<This(A0, A1)>
147 typedef typename result_of::make_pair<A0,A1>::type type;
150 template <typename Sig>
153 template <typename This, typename A0, typename A1>
154 struct result<This(A0, A1)>
155 : boost::remove_reference<std::pair<A0, A1> >
161 template <typename A0, typename A1>
162 #ifdef BOOST_RESULT_OF_USE_TR1
163 typename result<XMake_pair(A0,A1)>::type
167 operator()(A0 const & a0, A1 const & a1) const
169 return std::make_pair(a0,a1);
175 typedef boost::phoenix::function<impl::XMake_pair> Make_pair;
181 // For now I will leave the return type deduction as it is.
182 // I want to look at bringing in the sort of type deduction for
183 // mixed types which I have in FC++.
184 // Also I could look at the case where one of the arguments is
185 // another functor or a Phoenix placeholder.
188 template <typename Sig>
191 template <typename This, typename A0, typename A1>
192 struct result<This(A0, A1)>
193 : boost::remove_reference<A0>
196 template <typename This, typename A0, typename A1, typename A2>
197 struct result<This(A0, A1, A2)>
198 : boost::remove_reference<A0>
201 template <typename A0, typename A1>
202 A0 operator()(A0 const & a0, A1 const & a1) const
209 template <typename A0, typename A1, typename A2>
210 A0 operator()(A0 const & a0, A1 const & a1, A2 const & a2) const
218 template <typename Sig>
221 template <typename This, typename A0, typename A1>
222 struct result<This(A0, A1)>
223 : boost::remove_reference<A0>
226 template <typename A0, typename A1>
227 A0 operator()(A0 const & a0, A1 const & a1) const
236 template <typename Sig>
239 template <typename This, typename A0, typename A1>
240 struct result<This(A0, A1)>
241 : boost::remove_reference<A0>
244 template <typename A0, typename A1>
245 A0 operator()(A0 const & a0, A1 const & a1) const
254 template <typename Sig>
257 template <typename This, typename A0, typename A1>
258 struct result<This(A0, A1)>
259 : boost::remove_reference<A0>
262 template <typename A0, typename A1>
263 A0 operator()(A0 const & a0, A1 const & a1) const
272 template <typename Sig>
275 template <typename This, typename A0, typename A1>
276 struct result<This(A0, A1)>
277 : boost::remove_reference<A0>
280 template <typename A0, typename A1>
281 A0 operator()(A0 const & a0, A1 const & a1) const
290 template <typename Sig>
293 template <typename This, typename A0>
294 struct result<This(A0)>
295 : boost::remove_reference<A0>
298 template <typename A0>
299 A0 operator()(A0 const & a0) const
307 template <typename Sig>
310 template <typename This, typename A0, typename A1>
311 struct result<This(A0,A1)>
316 template <typename A0, typename A1>
317 bool operator()(A0 const & a0, A1 const & a1) const
325 template <typename Sig>
328 template <typename This, typename A0, typename A1>
329 struct result<This(A0,A1)>
334 template <typename A0, typename A1>
335 bool operator()(A0 const & a0, A1 const & a1) const
343 template <typename Sig>
346 template <typename This, typename A0, typename A1>
347 struct result<This(A0,A1)>
352 template <typename A0, typename A1>
353 bool operator()(A0 const & a0, A1 const & a1) const
361 template <typename Sig>
364 template <typename This, typename A0, typename A1>
365 struct result<This(A0,A1)>
370 template <typename A0, typename A1>
371 bool operator()(A0 const & a0, A1 const & a1) const
377 struct XGreater_equal
379 template <typename Sig>
382 template <typename This, typename A0, typename A1>
383 struct result<This(A0,A1)>
388 template <typename A0, typename A1>
389 bool operator()(A0 const & a0, A1 const & a1) const
397 template <typename Sig>
400 template <typename This, typename A0, typename A1>
401 struct result<This(A0,A1)>
406 template <typename A0, typename A1>
407 bool operator()(A0 const & a0, A1 const & a1) const
415 template <typename Sig>
418 template <typename This, typename A0>
419 struct result<This(A0)>
424 template <typename A0>
425 bool operator()(A0 const & a0) const
433 template <typename Sig>
436 template <typename This, typename A0, typename A1>
437 struct result<This(A0,A1)>
442 template <typename A0, typename A1>
443 bool operator()(A0 const & a0, A1 const & a1) const
451 template <typename Sig>
454 template <typename This, typename A0, typename A1>
455 struct result<This(A0,A1)>
460 template <typename A0, typename A1>
461 bool operator()(A0 const & a0, A1 const & a1) const
469 template <typename Sig>
472 template <typename This, typename A0>
473 struct result<This(A0)>
478 template <typename A0>
479 bool operator()(A0 const & a0) const
487 template <typename Sig>
490 template <typename This, typename A0, typename A1>
491 struct result<This(A0, A1)>
492 : boost::remove_reference<A0>
495 template <typename A0, typename A1>
496 A0 operator()(A0 const & a0, A1 const & a1) const
498 if ( a0 < a1 ) return a0; else return a1;
505 template <typename Sig>
508 template <typename This, typename A0, typename A1>
509 struct result<This(A0, A1)>
510 : boost::remove_reference<A0>
513 template <typename A0, typename A1>
514 A0 operator()(A0 const & a0, A1 const & a1) const
516 if ( a0 < a1 ) return a1; else return a0;
523 template <typename Sig>
526 template <typename This, typename A0>
527 struct result<This(A0)>
528 : boost::remove_reference<A0>
531 template <typename A0>
532 A0 operator()(A0 const & a0) const
541 template <typename Sig>
544 template <typename This, typename A0>
545 struct result<This(A0)>
546 : boost::remove_reference<A0>
549 template <typename A0>
550 A0 operator()(A0 const & a0) const
559 template <typename Sig>
562 template <typename This, typename A0>
563 struct result<This(A0)>
564 : boost::remove_reference<A0>
567 template <typename A0>
568 A0 operator()(A0 const & a0) const
575 // Example of templated struct.
576 // How do I make it callable?
577 template <typename Result>
580 typedef Result result_type;
582 Result operator()(Result const & r) const
586 // what is not complete - error.
587 //static boost::function1<Result,Result> res = what<Result>();
590 template <typename Result>
593 typedef Result result_type;
595 Result operator()() const
603 template <class Result, class F>
604 class MonomorphicWrapper0 /* : public c_fun_type<Res> */
608 typedef Result result_type;
609 MonomorphicWrapper0( const F& g ) : f(g) {}
610 Result operator()() const {
616 /////////////////////////////////////////////////////////
617 // Look at this. How to use Phoenix with a templated
618 // struct. First adapt with boost::function and then
619 // convert that to Phoenix!!
620 // I have not found out how to do it directly.
621 /////////////////////////////////////////////////////////
622 boost::function1<int, int > what_int = impl::what<int>();
623 typedef boost::function1<int,int> fun1_int_int;
624 typedef boost::function0<int> fun0_int;
625 boost::function0<int> what0_int = impl::what0<int>();
626 BOOST_PHOENIX_ADAPT_FUNCTION(int,what,what_int,1)
627 BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY(int,what0,what0_int)
628 // And this shows how to make them into argument callable functions.
629 typedef boost::phoenix::function<fun1_int_int> What_arg;
630 typedef boost::phoenix::function<fun0_int> What0_arg;
631 What_arg what_arg(what_int);
632 What0_arg what0_arg(what0_int);
635 // To use these as arguments they have to be defined like this.
636 typedef boost::phoenix::function<impl::XPlus> Plus;
637 typedef boost::phoenix::function<impl::XMinus> Minus;
638 typedef boost::phoenix::function<impl::XMultiplies> Multiplies;
639 typedef boost::phoenix::function<impl::XDivides> Divides;
640 typedef boost::phoenix::function<impl::XModulus> Modulus;
641 typedef boost::phoenix::function<impl::XNegate> Negate;
642 typedef boost::phoenix::function<impl::XEqual> Equal;
643 typedef boost::phoenix::function<impl::XNot_equal> Not_equal;
644 typedef boost::phoenix::function<impl::XGreater> Greater;
645 typedef boost::phoenix::function<impl::XLess> Less;
646 typedef boost::phoenix::function<impl::XGreater_equal> Greater_equal;
647 typedef boost::phoenix::function<impl::XLess_equal> Less_equal;
648 typedef boost::phoenix::function<impl::XPositive> Positive;
649 typedef boost::phoenix::function<impl::XLogical_and> Logical_and;
650 typedef boost::phoenix::function<impl::XLogical_or> Logical_or;
651 typedef boost::phoenix::function<impl::XLogical_not> Logical_not;
652 typedef boost::phoenix::function<impl::XMax> Max;
653 typedef boost::phoenix::function<impl::XMin> Min;
654 typedef boost::phoenix::function<impl::XInc> Inc;
655 typedef boost::phoenix::function<impl::XDec> Dec;
656 typedef boost::phoenix::function<impl::XSin> Sin;
659 Multiplies multiplies;
667 Greater_equal greater_equal;
668 Less_equal less_equal;
670 Logical_and logical_and;
671 Logical_or logical_or;
672 Logical_not logical_not;