plll  1.0
rational-ops.hpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2011-2014 University of Zurich
3 
4  Permission is hereby granted, free of charge, to any person obtaining a copy
5  of this software and associated documentation files (the "Software"), to deal
6  in the Software without restriction, including without limitation the rights
7  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  copies of the Software, and to permit persons to whom the Software is
9  furnished to do so, subject to the following conditions:
10 
11  The above copyright notice and this permission notice shall be included in
12  all copies or substantial portions of the Software.
13 
14  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  THE SOFTWARE.
21 */
22 
23 #ifndef PLLL_INCLUDE_GUARD__RATIONAL_OPS_HPP
24 #define PLLL_INCLUDE_GUARD__RATIONAL_OPS_HPP
25 
32 namespace plll
33 {
34  namespace arithmetic
35  {
36  namespace expressions
37  {
38  // add
39  template<class D1, class D2, template<typename, typename> class O2, class E>
40  void do_assign(arithmetic::Rational & x,
41  const AddOp<RationalContext, std::pair<D1, Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context> > > &,
42  const std::pair<D1, Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context> > & data)
43  {
44  add_z(x, data.first.evaluate(), data.second.data().evaluate());
45  }
46 
47  template<class D1, class D2, template<typename, typename> class O2, class E>
48  void do_assign(arithmetic::Rational & x,
49  const AddOp<RationalContext, std::pair<Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context>, D1> > &,
50  const std::pair<Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context>, D1> & data)
51  {
52  add_z(x, data.second.evaluate(), data.first.data().evaluate());
53  }
54 
55  // subtract
56  template<class D1, class D2, template<typename, typename> class O2, class E>
57  void do_assign(arithmetic::Rational & x,
58  const SubOp<RationalContext, std::pair<D1, Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context> > > &,
59  const std::pair<D1, Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context> > & data)
60  {
61  sub_z(x, data.first.evaluate(), data.second.data().evaluate());
62  }
63 
64  template<class D1, class D2, template<typename, typename> class O2, class E>
65  void do_assign(arithmetic::Rational & x,
66  const SubOp<RationalContext, std::pair<Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context>, D1> > &,
67  const std::pair<Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context>, D1> & data)
68  {
69  z_sub(x, data.first.data().evaluate(), data.second.evaluate());
70  }
71 
72  // multiply
73  template<class D1, class D2, template<typename, typename> class O2, class E>
74  void do_assign(arithmetic::Rational & x,
75  const MulOp<RationalContext, std::pair<D1, Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context> > > &,
76  const std::pair<D1, Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context> > & data)
77  {
78  mul_z(x, data.first.evaluate(), data.second.data().evaluate());
79  }
80 
81  template<class D1, class D2, template<typename, typename> class O2, class E>
82  void do_assign(arithmetic::Rational & x,
83  const MulOp<RationalContext, std::pair<Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context>, D1> > &,
84  const std::pair<Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context>, D1> & data)
85  {
86  mul_z(x, data.second.evaluate(), data.first.data().evaluate());
87  }
88 
89  // divide
90  template<class D1, class D2, template<typename, typename> class O2, class E>
91  void do_assign(arithmetic::Rational & x,
92  const DivOp<RationalContext, std::pair<D1, Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context> > > &,
93  const std::pair<D1, Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context> > & data)
94  {
95  div_z(x, data.first.evaluate(), data.second.data().evaluate());
96  }
97 
98  template<class D1, class D2, template<typename, typename> class O2, class E>
99  void do_assign(arithmetic::Rational & x,
100  const DivOp<RationalContext, std::pair<Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context>, D1> > &,
101  const std::pair<Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context>, D1> & data)
102  {
103  z_div(x, data.first.data().evaluate(), data.second.evaluate());
104  }
105 
106  // modulo
107  template<class D1, class D2, template<typename, typename> class O2, class E>
108  void do_assign(arithmetic::Rational & x,
109  const ModOp<RationalContext, std::pair<D1, Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context> > > &,
110  const std::pair<D1, Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context> > & data)
111  {
112  mod_z(x, data.first.evaluate(), data.second.data().evaluate());
113  }
114 
115  template<class D1, class D2, template<typename, typename> class O2, class E>
116  void do_assign(arithmetic::Rational & x,
117  const ModOp<RationalContext, std::pair<Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context>, D1> > &,
118  const std::pair<Expression<RationalContext, Expression<IntegerContext, D2, O2>, ConvertOp_Context>, D1> & data)
119  {
120  z_mod(x, data.first.data().evaluate(), data.second.evaluate());
121  }
122 
123  // shift
124  template<class D, template<typename, typename> class O, class E>
125  void do_assign(arithmetic::Rational & x,
126  const ShiftCOp<RationalContext, Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> > & op,
127  Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> & data)
128  {
129  shl_z(x, data.data().evaluate(), op.shift());
130  }
131 
132  // negation, absolute value, square
133  template<class D, template<typename, typename> class O>
134  void do_assign(arithmetic::Rational & x,
135  const NegOp<RationalContext, Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> > & op,
136  Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> & data)
137  {
138  neg_z(x, data.op().value());
139  }
140 
141  template<class D, template<typename, typename> class O>
142  void do_assign(arithmetic::Rational & x,
143  const AbsOp<RationalContext, Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> > & op,
144  Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> & data)
145  {
146  abs_z(x, data.op().value());
147  }
148 
149  template<class D, template<typename, typename> class O>
150  void do_assign(arithmetic::Rational & x,
151  const AbsOp_Context<RationalContext, Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> > & op,
152  Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> & data)
153  {
154  abs_z(x, data.op().value());
155  }
156 
157  template<class D, template<typename, typename> class O>
158  void do_assign(arithmetic::Rational & x,
159  const SquareOp<RationalContext, Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> > & op,
160  Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> & data)
161  {
162  square_z(x, data.op().value());
163  }
164 
165  template<class D, template<typename, typename> class O>
166  void do_assign(arithmetic::Rational & x,
167  const SquareOp_Context<RationalContext, Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> > & op,
168  Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> & data)
169  {
170  square_z(x, data.op().value());
171  }
172 
173  // power
174  template<class D, template<typename, typename> class O>
175  void do_assign(arithmetic::Rational & x,
176  const PowerCOp<signed long>::impl<RationalContext, Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> > & op,
177  Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> & data)
178  {
179  power_z(x, data.op().value(), op.value());
180  }
181 
182  template<class D, template<typename, typename> class O>
183  void do_assign(arithmetic::Rational & x,
184  const PowerCOp<unsigned long>::impl<RationalContext, Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> > & op,
185  Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context> & data)
186  {
187  power_z(x, data.op().value(), op.value());
188  }
189 
190  template<class D, template<typename, typename> class O, template<typename, typename> class IO, typename ID>
191  void do_assign(arithmetic::Rational & x,
192  const PowerOp<RationalContext, std::pair<Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context>, Expression<IntegerContext, ID, IO> > > & op,
193  std::pair<Expression<RationalContext, Expression<IntegerContext, D, O>, ConvertOp_Context>, Expression<IntegerContext, ID, IO> > & data)
194  {
195  power_z(x, data.first.op().value(), data.second.evaluate());
196  }
197  }
198 
210  inline Rational & operator -= (Rational & cur, const Rational & r)
211  {
212  sub(cur, cur, r);
213  return cur;
214  }
215 
226  template<class D>
228  {
229  submul(cur, E.data().first.evaluate(), E.data().second.evaluate());
230  return cur;
231  }
232 
240  inline Rational & operator += (Rational & cur, const Rational & r)
241  {
242  add(cur, cur, r);
243  return cur;
244  }
245 
256  template<class D>
258  {
259  addmul(cur, E.data().first.evaluate(), E.data().second.evaluate());
260  return cur;
261  }
262 
270  inline Rational & operator *= (Rational & cur, const Rational & r)
271  {
272  mul(cur, cur, r);
273  return cur;
274  }
275 
283  inline Rational & operator /= (Rational & cur, const Rational & r)
284  {
285  div(cur, cur, r);
286  return cur;
287  }
288 
297  inline Rational & operator %= (Rational & cur, const Rational & r)
298  {
299  mod(cur, cur, r);
300  return cur;
301  }
302 
310  inline Rational & operator <<= (Rational & cur, long r)
311  {
312  shl(cur, cur, r);
313  return cur;
314  }
315 
323  inline Rational & operator >>= (Rational & cur, long r)
324  {
325  shr(cur, cur, r);
326  return cur;
327  }
329 
330  template<class D, typename D2, template<typename, typename> class O2>
331  inline Rational & operator -= (Rational & cur,
332  const expressions::Expression<RationalContext,
333  std::pair<D, expressions::Expression<RationalContext,
334  expressions::Expression<IntegerContext, D2, O2>,
335  expressions::ConvertOp_Context> >,
336  expressions::MulOp> & E)
337  {
338  submul_z(cur, E.data().first.evaluate(), E.data().second.data().evaluate());
339  return cur;
340  }
341 
342  template<class D, typename D2, template<typename, typename> class O2>
343  inline Rational & operator -= (Rational & cur,
344  const expressions::Expression<RationalContext,
345  std::pair<expressions::Expression<RationalContext,
346  expressions::Expression<IntegerContext, D2, O2>,
347  expressions::ConvertOp_Context>, D>,
348  expressions::MulOp> & E)
349  {
350  submul_z(cur, E.data().second.evaluate(), E.data().first.data().evaluate());
351  return cur;
352  }
353 
354  template<class D, typename D2, template<typename, typename> class O2>
355  inline Rational & operator += (Rational & cur,
356  const expressions::Expression<RationalContext,
357  std::pair<D, expressions::Expression<RationalContext,
358  expressions::Expression<IntegerContext, D2, O2>,
359  expressions::ConvertOp_Context> >,
360  expressions::MulOp> & E)
361  {
362  addmul_z(cur, E.data().first.evaluate(), E.data().second.data().evaluate());
363  return cur;
364  }
365 
366  template<class D, typename D2, template<typename, typename> class O2>
367  inline Rational & operator += (Rational & cur,
368  const expressions::Expression<RationalContext,
369  std::pair<expressions::Expression<RationalContext,
370  expressions::Expression<IntegerContext, D2, O2>,
371  expressions::ConvertOp_Context>, D>,
372  expressions::MulOp> & E)
373  {
374  addmul_z(cur, E.data().second.evaluate(), E.data().first.data().evaluate());
375  return cur;
376  }
377 
388  inline Rational operator ++ (Rational & cur, int)
389  {
390  Rational r(cur);
391  increment(cur, cur);
392  return r;
393  }
394 
401  inline Rational operator -- (Rational & cur, int)
402  {
403  Rational r(cur);
404  decrement(cur, cur);
405  return r;
406  }
407 
415  {
416  increment(cur, cur);
417  return cur;
418  }
419 
427  {
428  decrement(cur, cur);
429  return cur;
430  }
431 
433 
445  inline bool operator == (const Rational & a, const Rational & b)
446  {
447  return compare(a, b) == 0;
448  }
449 
457  inline bool operator != (const Rational & a, const Rational & b)
458  {
459  return compare(a, b) != 0;
460  }
461 
469  inline bool operator <= (const Rational & a, const Rational & b)
470  {
471  return compare(a, b) <= 0;
472  }
473 
481  inline bool operator >= (const Rational & a, const Rational & b)
482  {
483  return compare(a, b) >= 0;
484  }
485 
493  inline bool operator < (const Rational & a, const Rational & b)
494  {
495  return compare(a, b) < 0;
496  }
497 
505  inline bool operator > (const Rational & a, const Rational & b)
506  {
507  return compare(a, b) > 0;
508  }
509 
511 
512  // Comparsions with second operand expression: make the first operand also an expression
513  template<class A2, template<typename, typename> class O2>
514  inline bool operator == (const Rational & a, const expressions::Expression<RationalContext, A2, O2> & b)
515  {
516  return expressions::make_expression<RationalContext>(a) == b;
517  }
518 
519  template<class A2, template<typename, typename> class O2>
520  inline bool operator != (const Rational & a, const expressions::Expression<RationalContext, A2, O2> & b)
521  {
522  return expressions::make_expression<RationalContext>(a) != b;
523  }
524 
525  template<class A2, template<typename, typename> class O2>
526  inline bool operator <= (const Rational & a, const expressions::Expression<RationalContext, A2, O2> & b)
527  {
528  return expressions::make_expression<RationalContext>(a) <= b;
529  }
530 
531  template<class A2, template<typename, typename> class O2>
532  inline bool operator >= (const Rational & a, const expressions::Expression<RationalContext, A2, O2> & b)
533  {
534  return expressions::make_expression<RationalContext>(a) >= b;
535  }
536 
537  template<class A2, template<typename, typename> class O2>
538  inline bool operator < (const Rational & a, const expressions::Expression<RationalContext, A2, O2> & b)
539  {
540  return expressions::make_expression<RationalContext>(a) < b;
541  }
542 
543  template<class A2, template<typename, typename> class O2>
544  inline bool operator > (const Rational & a, const expressions::Expression<RationalContext, A2, O2> & b)
545  {
546  return expressions::make_expression<RationalContext>(a) > b;
547  }
548 
549  namespace expressions
550  {
551  // Comparsions with first operand expression: make the second operand also an expression
552  template<class A1, template<typename, typename> class O1>
553  inline bool operator == (const expressions::Expression<RationalContext, A1, O1> & a, const arithmetic::Rational & b)
554  {
555  return a == expressions::make_expression<RationalContext>(b);
556  }
557 
558  template<class A1, template<typename, typename> class O1>
559  inline bool operator != (const expressions::Expression<RationalContext, A1, O1> & a, const arithmetic::Rational & b)
560  {
561  return a != expressions::make_expression<RationalContext>(b);
562  }
563 
564  template<class A1, template<typename, typename> class O1>
565  inline bool operator <= (const expressions::Expression<RationalContext, A1, O1> & a, const arithmetic::Rational & b)
566  {
567  return a <= expressions::make_expression<RationalContext>(b);
568  }
569 
570  template<class A1, template<typename, typename> class O1>
571  inline bool operator >= (const expressions::Expression<RationalContext, A1, O1> & a, const arithmetic::Rational & b)
572  {
573  return a >= expressions::make_expression<RationalContext>(b);
574  }
575 
576  template<class A1, template<typename, typename> class O1>
577  inline bool operator < (const expressions::Expression<RationalContext, A1, O1> & a, const arithmetic::Rational & b)
578  {
579  return a < expressions::make_expression<RationalContext>(b);
580  }
581 
582  template<class A1, template<typename, typename> class O1>
583  inline bool operator > (const expressions::Expression<RationalContext, A1, O1> & a, const arithmetic::Rational & b)
584  {
585  return a > expressions::make_expression<RationalContext>(b);
586  }
587 
588  // Comparsions with both operand expression
589  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
590  inline bool operator == (const expressions::Expression<RationalContext, A1, O1> & a,
591  const expressions::Expression<RationalContext, A2, O2> & b)
592  {
593  return compare(a, b) == 0;
594  }
595 
596  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
597  inline bool operator != (const expressions::Expression<RationalContext, A1, O1> & a,
598  const expressions::Expression<RationalContext, A2, O2> & b)
599  {
600  return compare(a, b) != 0;
601  }
602 
603  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
604  inline bool operator <= (const expressions::Expression<RationalContext, A1, O1> & a,
605  const expressions::Expression<RationalContext, A2, O2> & b)
606  {
607  return compare(a, b) <= 0;
608  }
609 
610  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
611  inline bool operator >= (const expressions::Expression<RationalContext, A1, O1> & a,
612  const expressions::Expression<RationalContext, A2, O2> & b)
613  {
614  return compare(a, b) >= 0;
615  }
616 
617  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
618  inline bool operator < (const expressions::Expression<RationalContext, A1, O1> & a,
619  const expressions::Expression<RationalContext, A2, O2> & b)
620  {
621  return compare(a, b) < 0;
622  }
623 
624  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
625  inline bool operator > (const expressions::Expression<RationalContext, A1, O1> & a,
626  const expressions::Expression<RationalContext, A2, O2> & b)
627  {
628  return compare(a, b) > 0;
629  }
630 
631  // First operand is integer conversion expression, second operand arbitrary expression
632 
633  template<class A2, template<typename, typename> class O2, class A1, template<typename, typename> class O1>
634  inline bool operator == (const expressions::Expression<RationalContext, expressions::Expression<IntegerContext, A1, O1>,
635  expressions::ConvertOp_Context> & a,
636  const expressions::Expression<RationalContext, A2, O2> & b)
637  { return compare_z(b.evaluate(), a.op().value()) == 0; }
638  template<class A2, template<typename, typename> class O2, class A1, template<typename, typename> class O1>
639  inline bool operator != (const expressions::Expression<RationalContext, expressions::Expression<IntegerContext, A1, O1>,
640  expressions::ConvertOp_Context> & a,
641  const expressions::Expression<RationalContext, A2, O2> & b)
642  { return compare_z(b.evaluate(), a.op().value()) != 0; }
643  template<class A2, template<typename, typename> class O2, class A1, template<typename, typename> class O1>
644  inline bool operator <= (const expressions::Expression<RationalContext, expressions::Expression<IntegerContext, A1, O1>,
645  expressions::ConvertOp_Context> & a,
646  const expressions::Expression<RationalContext, A2, O2> & b)
647  { return compare_z(b.evaluate(), a.op().value()) >= 0; }
648  template<class A2, template<typename, typename> class O2, class A1, template<typename, typename> class O1>
649  inline bool operator >= (const expressions::Expression<RationalContext, expressions::Expression<IntegerContext, A1, O1>,
650  expressions::ConvertOp_Context> & a,
651  const expressions::Expression<RationalContext, A2, O2> & b)
652  { return compare_z(b.evaluate(), a.op().value()) <= 0; }
653  template<class A2, template<typename, typename> class O2, class A1, template<typename, typename> class O1>
654  inline bool operator < (const expressions::Expression<RationalContext, expressions::Expression<IntegerContext, A1, O1>,
655  expressions::ConvertOp_Context> & a,
656  const expressions::Expression<RationalContext, A2, O2> & b)
657  { return compare_z(b.evaluate(), a.op().value()) > 0; }
658  template<class A2, template<typename, typename> class O2, class A1, template<typename, typename> class O1>
659  inline bool operator > (const expressions::Expression<RationalContext, expressions::Expression<IntegerContext, A1, O1>,
660  expressions::ConvertOp_Context> & a,
661  const expressions::Expression<RationalContext, A2, O2> & b)
662  { return compare_z(b.evaluate(), a.op().value()) < 0; }
663 
664  // First operand is arbitrary expression, Second operand is integer conversion expression
665  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
666  inline bool operator == (const expressions::Expression<RationalContext, A1, O1> & a,
667  const expressions::Expression<RationalContext, expressions::Expression<IntegerContext, A2, O2>,
668  expressions::ConvertOp_Context> & b)
669  { return compare_z(a.evaluate(), b.op().value()) == 0; }
670  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
671  inline bool operator != (const expressions::Expression<RationalContext, A1, O1> & a,
672  const expressions::Expression<RationalContext, expressions::Expression<IntegerContext, A2, O2>,
673  expressions::ConvertOp_Context> & b)
674  { return compare_z(a.evaluate(), b.op().value()) != 0; }
675  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
676  inline bool operator <= (const expressions::Expression<RationalContext, A1, O1> & a,
677  const expressions::Expression<RationalContext, expressions::Expression<IntegerContext, A2, O2>,
678  expressions::ConvertOp_Context> & b)
679  { return compare_z(a.evaluate(), b.op().value()) <= 0; }
680  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
681  inline bool operator >= (const expressions::Expression<RationalContext, A1, O1> & a,
682  const expressions::Expression<RationalContext, expressions::Expression<IntegerContext, A2, O2>,
683  expressions::ConvertOp_Context> & b)
684  { return compare_z(a.evaluate(), b.op().value()) >= 0; }
685  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
686  inline bool operator < (const expressions::Expression<RationalContext, A1, O1> & a,
687  const expressions::Expression<RationalContext, expressions::Expression<IntegerContext, A2, O2>,
688  expressions::ConvertOp_Context> & b)
689  { return compare_z(a.evaluate(), b.op().value()) < 0; }
690  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
691  inline bool operator > (const expressions::Expression<RationalContext, A1, O1> & a,
692  const expressions::Expression<RationalContext, expressions::Expression<IntegerContext, A2, O2>,
693  expressions::ConvertOp_Context> & b)
694  { return compare_z(a.evaluate(), b.op().value()) > 0; }
695 
696  // Predicates
697  template<class A, template<typename, typename> class O>
698  inline bool isZero(const expressions::Expression<RationalContext, A, O> & r)
699  {
700  return isZero(Rational(r));
701  }
702 
703  template<class A, template<typename, typename> class O>
704  inline bool isOne(const expressions::Expression<RationalContext, A, O> & r)
705  {
706  return isOne(Rational(r));
707  }
708 
709  template<class A, template<typename, typename> class O>
710  inline bool isPositive(const expressions::Expression<RationalContext, A, O> & r)
711  {
712  return isPositive(Rational(r));
713  }
714 
715  template<class A, template<typename, typename> class O>
716  inline bool isNonNegative(const expressions::Expression<RationalContext, A, O> & r)
717  {
718  return isNonNegative(Rational(r));
719  }
720 
721  template<class A, template<typename, typename> class O>
722  inline bool isNegative(const expressions::Expression<RationalContext, A, O> & r)
723  {
724  return isNegative(Rational(r));
725  }
726 
727  template<class A, template<typename, typename> class O>
728  inline bool isNonPositive(const expressions::Expression<RationalContext, A, O> & r)
729  {
730  return isZero(Rational(r));
731  }
732  }
733 
744  inline expressions::Expression<RationalContext, expressions::Wrapper<RationalContext>,
755  inline expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
756  expressions::Wrapper<RationalContext> >,
759  expressions::AddOp>(std::make_pair(expressions::Wrapper<RationalContext>(a),
760  expressions::Wrapper<RationalContext>(b))); }
768  inline expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
769  expressions::Wrapper<RationalContext> >,
773  expressions::SubOp>(std::make_pair(expressions::Wrapper<RationalContext>(a),
774  expressions::Wrapper<RationalContext>(b))); }
782  inline expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
783  expressions::Wrapper<RationalContext> >,
787  expressions::MulOp>(std::make_pair(expressions::Wrapper<RationalContext>(a),
788  expressions::Wrapper<RationalContext>(b))); }
796  inline expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
797  expressions::Wrapper<RationalContext> >,
801  expressions::DivOp>(std::make_pair(expressions::Wrapper<RationalContext>(a),
802  expressions::Wrapper<RationalContext>(b))); }
810  inline expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
811  expressions::Wrapper<RationalContext> >,
815  expressions::ModOp>(std::make_pair(expressions::Wrapper<RationalContext>(a),
816  expressions::Wrapper<RationalContext>(b))); }
825  inline expressions::Expression<RationalContext, expressions::Wrapper<RationalContext>,
826  expressions::ShiftCOp> operator << (const Rational & a, signed long b)
829 
837  inline expressions::Expression<RationalContext, expressions::Wrapper<RationalContext>,
838  expressions::ShiftCOp> operator >> (const Rational & a, signed long b)
841 
843 
844  // Basic operations with second operand an expression
845  template<class A, template<typename, typename> class O>
846  inline expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
847  expressions::Expression<RationalContext, A, O> >,
848  expressions::AddOp> operator + (const Rational & a, const expressions::Expression<RationalContext, A, O> & b)
849  { return expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
850  expressions::Expression<RationalContext, A, O> >,
851  expressions::AddOp>(std::make_pair(expressions::Wrapper<RationalContext>(a), b)); }
852  template<class A, template<typename, typename> class O>
853  inline expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
854  expressions::Expression<RationalContext, A, O> >,
855  expressions::SubOp> operator - (const Rational & a, const expressions::Expression<RationalContext, A, O> & b)
856  { return expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
857  expressions::Expression<RationalContext, A, O> >,
858  expressions::SubOp>(std::make_pair(expressions::Wrapper<RationalContext>(a), b)); }
859  template<class A, template<typename, typename> class O>
860  inline expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
861  expressions::Expression<RationalContext, A, O> >,
862  expressions::MulOp> operator * (const Rational & a, const expressions::Expression<RationalContext, A, O> & b)
863  { return expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
864  expressions::Expression<RationalContext, A, O> >,
865  expressions::MulOp>(std::make_pair(expressions::Wrapper<RationalContext>(a), b)); }
866  template<class A, template<typename, typename> class O>
867  inline expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
868  expressions::Expression<RationalContext, A, O> >,
869  expressions::DivOp> operator / (const Rational & a, const expressions::Expression<RationalContext, A, O> & b)
870  { return expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
871  expressions::Expression<RationalContext, A, O> >,
872  expressions::DivOp>(std::make_pair(expressions::Wrapper<RationalContext>(a), b)); }
873  template<class A, template<typename, typename> class O>
874  inline expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
875  expressions::Expression<RationalContext, A, O> >,
876  expressions::ModOp> operator % (const Rational & a, const expressions::Expression<RationalContext, A, O> & b)
877  { return expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
878  expressions::Expression<RationalContext, A, O> >,
879  expressions::ModOp>(std::make_pair(expressions::Wrapper<RationalContext>(a), b)); }
880 
881  namespace expressions
882  {
883  // Basic operations with first operand an expression
884  template<class A, template<typename, typename> class O>
885  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
886  expressions::NegOp> operator - (const expressions::Expression<RationalContext, A, O> & a)
887  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
888  expressions::NegOp>(a); }
889  template<class A, template<typename, typename> class O>
890  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
891  expressions::Wrapper<RationalContext> >,
892  expressions::AddOp> operator + (const expressions::Expression<RationalContext, A, O> & a,
893  const arithmetic::Rational & b)
894  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>, expressions::Wrapper<RationalContext> >,
895  expressions::AddOp>(std::make_pair(a, expressions::Wrapper<RationalContext>(b))); }
896  template<class A, template<typename, typename> class O>
897  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
898  expressions::Wrapper<RationalContext> >,
899  expressions::SubOp> operator - (const expressions::Expression<RationalContext, A, O> & a,
900  const arithmetic::Rational & b)
901  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
902  expressions::Wrapper<RationalContext> >,
903  expressions::SubOp>(std::make_pair(a, expressions::Wrapper<RationalContext>(b))); }
904  template<class A, template<typename, typename> class O>
905  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
906  expressions::Wrapper<RationalContext> >,
907  expressions::MulOp> operator * (const expressions::Expression<RationalContext, A, O> & a,
908  const arithmetic::Rational & b)
909  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
910  expressions::Wrapper<RationalContext> >,
911  expressions::MulOp>(std::make_pair(a, expressions::Wrapper<RationalContext>(b))); }
912  template<class A, template<typename, typename> class O>
913  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
914  expressions::Wrapper<RationalContext> >,
915  expressions::DivOp> operator / (const expressions::Expression<RationalContext, A, O> & a,
916  const arithmetic::Rational & b)
917  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
918  expressions::Wrapper<RationalContext> >,
919  expressions::DivOp>(std::make_pair(a, expressions::Wrapper<RationalContext>(b))); }
920  template<class A, template<typename, typename> class O>
921  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
922  expressions::Wrapper<RationalContext> >,
923  expressions::ModOp> operator % (const expressions::Expression<RationalContext, A, O> & a,
924  const arithmetic::Rational & b)
925  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
926  expressions::Wrapper<RationalContext> >,
927  expressions::ModOp>(std::make_pair(a, expressions::Wrapper<RationalContext>(b))); }
928  template<class A, template<typename, typename> class O>
929  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
930  expressions::ShiftCOp> operator << (const expressions::Expression<RationalContext, A, O> & a,
931  signed long b)
932  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
933  expressions::ShiftCOp>(a, b); }
934 
935  template<class A, template<typename, typename> class O>
936  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
937  expressions::ShiftCOp> operator >> (const expressions::Expression<RationalContext, A, O> & a,
938  signed long b)
939  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
940  expressions::ShiftCOp>(a, -b); }
941 
942  // Basic operations with both operands an expression
943  template<class A1, template<typename, typename> class O1, class A, template<typename, typename> class O>
944  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A1, O1>,
945  expressions::Expression<RationalContext, A, O> >,
946  expressions::AddOp> operator + (const expressions::Expression<RationalContext, A1, O1> & a,
947  const expressions::Expression<RationalContext, A, O> & b)
948  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A1, O1>,
949  expressions::Expression<RationalContext, A, O> >,
950  expressions::AddOp>(std::make_pair(a, b)); }
951  template<class A1, template<typename, typename> class O1, class A, template<typename, typename> class O>
952  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A1, O1>,
953  expressions::Expression<RationalContext, A, O> >,
954  expressions::SubOp> operator - (const expressions::Expression<RationalContext, A1, O1> & a,
955  const expressions::Expression<RationalContext, A, O> & b)
956  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A1, O1>,
957  expressions::Expression<RationalContext, A, O> >,
958  expressions::SubOp>(std::make_pair(a, b)); }
959  template<class A1, template<typename, typename> class O1, class A, template<typename, typename> class O>
960  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A1, O1>,
961  expressions::Expression<RationalContext, A, O> >,
962  expressions::MulOp> operator * (const expressions::Expression<RationalContext, A1, O1> & a,
963  const expressions::Expression<RationalContext, A, O> & b)
964  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A1, O1>,
965  expressions::Expression<RationalContext, A, O> >,
966  expressions::MulOp>(std::make_pair(a, b)); }
967  template<class A1, template<typename, typename> class O1, class A, template<typename, typename> class O>
968  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A1, O1>,
969  expressions::Expression<RationalContext, A, O> >,
970  expressions::DivOp> operator / (const expressions::Expression<RationalContext, A1, O1> & a,
971  const expressions::Expression<RationalContext, A, O> & b)
972  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A1, O1>,
973  expressions::Expression<RationalContext, A, O> >,
974  expressions::DivOp>(std::make_pair(a, b)); }
975  template<class A1, template<typename, typename> class O1, class A, template<typename, typename> class O>
976  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A1, O1>,
977  expressions::Expression<RationalContext, A, O> >,
978  expressions::ModOp> operator % (const expressions::Expression<RationalContext, A1, O1> & a,
979  const expressions::Expression<RationalContext, A, O> & b)
980  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A1, O1>,
981  expressions::Expression<RationalContext, A, O> >,
982  expressions::ModOp>(std::make_pair(a, b)); }
983  }
984 
994  inline expressions::Expression<RationalContext, expressions::Wrapper<RationalContext>,
997  expressions::AbsOp>(expressions::Wrapper<RationalContext>(i)); }
1004  inline expressions::Expression<RationalContext, expressions::Wrapper<RationalContext>,
1007  expressions::SquareOp>(expressions::Wrapper<RationalContext>(i)); }
1009 
1019  inline expressions::Expression<RationalContext, expressions::Wrapper<RationalContext>,
1022  expressions::PowerCOp<signed long>::impl>(expressions::Wrapper<RationalContext>(a), b); }
1030  inline expressions::Expression<RationalContext, expressions::Wrapper<RationalContext>,
1033  expressions::PowerCOp<unsigned long>::impl>(expressions::Wrapper<RationalContext>(a), b); }
1041  inline expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
1042  expressions::Wrapper<IntegerContext> >,
1046  expressions::PowerOp>(std::make_pair(expressions::Wrapper<RationalContext>(a),
1047  expressions::Wrapper<IntegerContext>(b))); }
1049 
1059  inline expressions::Expression<RationalContext, expressions::Wrapper<RationalContext>,
1062  expressions::AbsOp>(expressions::Wrapper<RationalContext>(i)); }
1070  inline expressions::Expression<RationalContext, expressions::Wrapper<RationalContext>,
1073  expressions::SquareOp>(expressions::Wrapper<RationalContext>(i)); }
1075 
1086  inline expressions::Expression<RationalContext, expressions::Wrapper<RationalContext>,
1089  expressions::PowerCOp<signed long>::impl>(expressions::Wrapper<RationalContext>(a), b); }
1098  inline expressions::Expression<RationalContext, expressions::Wrapper<RationalContext>,
1101  expressions::PowerCOp<unsigned long>::impl>(expressions::Wrapper<RationalContext>(a), b); }
1110  inline expressions::Expression<RationalContext, std::pair<expressions::Wrapper<RationalContext>,
1111  expressions::Wrapper<IntegerContext> >,
1112  expressions::PowerOp> power(const Rational & a, const Integer & b, const RationalContext & rc)
1115  expressions::PowerOp>(std::make_pair(expressions::Wrapper<RationalContext>(a),
1116  expressions::Wrapper<IntegerContext>(b))); }
1118 
1119  // Functions applied to expressions
1120  template<class A, template<typename, typename> class O>
1121  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1122  expressions::AbsOp> abs(const expressions::Expression<RationalContext, A, O> & b)
1123  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1124  expressions::AbsOp>(b); }
1125  template<class A, template<typename, typename> class O>
1126  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1127  expressions::SquareOp> square(const expressions::Expression<RationalContext, A, O> & b)
1128  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1129  expressions::SquareOp>(b); }
1130  template<class A, template<typename, typename> class O>
1131  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1132  expressions::PowerCOp<signed long>::impl> power(const expressions::Expression<RationalContext, A, O> & a,
1133  signed long b)
1134  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1135  expressions::PowerCOp<signed long>::impl>(a, b); }
1136  template<class A, template<typename, typename> class O>
1137  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1138  expressions::PowerCOp<unsigned long>::impl> power(const expressions::Expression<RationalContext, A, O> & a,
1139  unsigned long b)
1140  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1141  expressions::PowerCOp<unsigned long>::impl>(a, b); }
1142  template<class A, template<typename, typename> class O>
1143  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
1144  expressions::Wrapper<IntegerContext> >,
1145  expressions::PowerOp> power(const expressions::Expression<RationalContext, A, O> & a,
1146  const Integer & b)
1147  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
1148  expressions::Wrapper<IntegerContext> >,
1149  expressions::PowerOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
1150  template<class A, template<typename, typename> class O>
1151  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1152  expressions::AbsOp> abs(const expressions::Expression<RationalContext, A, O> & b,
1153  const RationalContext &)
1154  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1155  expressions::AbsOp>(b); }
1156  template<class A, template<typename, typename> class O>
1157  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1158  expressions::SquareOp> square(const expressions::Expression<RationalContext, A, O> & b,
1159  const RationalContext &)
1160  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1161  expressions::SquareOp>(b); }
1162  template<class A, template<typename, typename> class O>
1163  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1164  expressions::PowerCOp<signed long>::impl> power(const expressions::Expression<RationalContext, A, O> & a,
1165  signed long b, const RationalContext &)
1166  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1167  expressions::PowerCOp<signed long>::impl>(a, b); }
1168  template<class A, template<typename, typename> class O>
1169  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1170  expressions::PowerCOp<unsigned long>::impl> power(const expressions::Expression<RationalContext, A, O> & a,
1171  unsigned long b, const RationalContext &)
1172  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1173  expressions::PowerCOp<unsigned long>::impl>(a, b); }
1174  template<class A, template<typename, typename> class O>
1175  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
1176  expressions::Wrapper<IntegerContext> >,
1177  expressions::PowerOp> power(const expressions::Expression<RationalContext, A, O> & a,
1178  const Integer & b, const RationalContext &)
1179  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
1180  expressions::Wrapper<IntegerContext> >,
1181  expressions::PowerOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
1182 
1183  namespace expressions
1184  {
1185  // Functions applied to expressions
1186  template<class A, template<typename, typename> class O>
1187  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1188  expressions::AbsOp> abs(const expressions::Expression<RationalContext, A, O> & b)
1189  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1190  expressions::AbsOp>(b); }
1191  template<class A, template<typename, typename> class O>
1192  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1193  expressions::SquareOp> square(const expressions::Expression<RationalContext, A, O> & b)
1194  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1195  expressions::SquareOp>(b); }
1196  template<class A, template<typename, typename> class O>
1197  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1198  expressions::PowerCOp<signed long>::impl> power(const expressions::Expression<RationalContext, A, O> & a,
1199  signed long b)
1200  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1201  expressions::PowerCOp<signed long>::impl>(a, b); }
1202  template<class A, template<typename, typename> class O>
1203  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1204  expressions::PowerCOp<unsigned long>::impl> power(const expressions::Expression<RationalContext, A, O> & a,
1205  unsigned long b)
1206  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1207  expressions::PowerCOp<unsigned long>::impl>(a, b); }
1208  template<class A, template<typename, typename> class O>
1209  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
1210  expressions::Wrapper<IntegerContext> >,
1211  expressions::PowerOp> power(const expressions::Expression<RationalContext, A, O> & a,
1212  const Integer & b)
1213  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
1214  expressions::Wrapper<IntegerContext> >,
1215  expressions::PowerOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
1216  template<class A, template<typename, typename> class O>
1217  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1218  expressions::AbsOp> abs(const expressions::Expression<RationalContext, A, O> & b,
1219  const RationalContext &)
1220  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1221  expressions::AbsOp>(b); }
1222  template<class A, template<typename, typename> class O>
1223  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1224  expressions::SquareOp> square(const expressions::Expression<RationalContext, A, O> & b,
1225  const RationalContext &)
1226  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1227  expressions::SquareOp>(b); }
1228  template<class A, template<typename, typename> class O>
1229  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1230  expressions::PowerCOp<signed long>::impl> power(const expressions::Expression<RationalContext, A, O> & a,
1231  signed long b, const RationalContext &)
1232  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1233  expressions::PowerCOp<signed long>::impl>(a, b); }
1234  template<class A, template<typename, typename> class O>
1235  inline expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1236  expressions::PowerCOp<unsigned long>::impl> power(const expressions::Expression<RationalContext, A, O> & a,
1237  unsigned long b, const RationalContext &)
1238  { return expressions::Expression<RationalContext, expressions::Expression<RationalContext, A, O>,
1239  expressions::PowerCOp<unsigned long>::impl>(a, b); }
1240  template<class A, template<typename, typename> class O>
1241  inline expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
1242  expressions::Wrapper<IntegerContext> >,
1243  expressions::PowerOp> power(const expressions::Expression<RationalContext, A, O> & a,
1244  const Integer & b, const RationalContext &)
1245  { return expressions::Expression<RationalContext, std::pair<expressions::Expression<RationalContext, A, O>,
1246  expressions::Wrapper<IntegerContext> >,
1247  expressions::PowerOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
1248 
1249  template<class A, template<typename, typename> class O>
1250  inline std::ostream & operator << (std::ostream & s, const expressions::Expression<RationalContext, A, O> & E)
1251  {
1252  return s << Rational(E);
1253  }
1254  }
1255 
1256  inline void addmul(Rational & r, const Rational & a, const Rational & b)
1257  {
1258  Rational p = a * b;
1259  r.add_r_neq_1st(p, r);
1260  }
1261 
1262  inline void submul(Rational & r, const Rational & a, const Rational & b)
1263  {
1264  Rational p = a * b;
1265  r.sub_r_neq_1st(p, r, true);
1266  }
1267  }
1268 }
1269 
1270 #endif
Returns the sum of the operands.
void submul(Integer &r, const Integer &a, const Integer &b)
Multiplies a and b and subtracts the result from r.
Integer & operator<<=(Integer &cur, const Integer &i)
Computes the bitwise left shift of cur by i bits, and stores the result in cur.
Integer & operator+=(Integer &cur, const expressions::Expression< IntegerContext, D, expressions::MulOp > &E)
Adds the given multiplication expression to cur.
bool operator<(const Integer &a, const Integer &b)
Compares the current integer with the given one.
Integer & operator%=(Integer &cur, const Integer &i)
Divides cur by the given integer i and stores the remainder in cur.
int compare(const Integer &a, const Integer &b)
Compares the two integers.
expressions::Expression< IntegerContext, expressions::Wrapper< IntegerContext >, expressions::NegOp > operator-(const Integer &a)
Negates the integer.
void shr(Integer &r, const Integer &a, long b)
Shifts a by b bits to the left and stores the result in r.
void do_assign(typename Context::Type &x, const Op &op, const Data &data)
Performs the assignment of the expression to x.
Returns the negative of the operand.
Integer & operator*=(Integer &cur, const Integer &i)
Multiplies the given integer i with cur.
Integer operator--(Integer &cur, int)
Decrements the integer by one and returns the previous value.
expressions::Expression< IntegerContext, expressions::Wrapper< IntegerContext >, expressions::AbsOp > abs(const Integer &i)
Computes and returns the absolute value of i.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::ShLOp > operator<<(const Integer &a, const Integer &b)
Computes the bitwise left shift of the first integer by the number of bits given by the second intege...
bool operator<=(const Integer &a, const Integer &b)
Compares the current integer with the given one.
Integer & operator-=(Integer &cur, const expressions::Expression< IntegerContext, D, expressions::MulOp > &E)
Subtracts the multiplication expression E from cur.
Returns the operand multiplied by 2 to the power of a constant.
void mul(Integer &r, const Integer &a, const Integer &b)
Multiplies a with b and stores the result in r.
void div(Integer &r, const Integer &a, const Integer &b)
Divides a by b and stores the result in r.
Returns the quotient of the operands.
const Data & data() const
Allows to access the expression's data.
void mod(Integer &r, const Integer &a, const Integer &b)
Takes the remainder of the division of a by b and stores it in r.
void increment(Integer &r, const Integer &a)
Increments a by one and stores the result in r.
bool operator==(const Integer &a, const Integer &b)
Compares the current integer with the given one for equality.
Integer & operator/=(Integer &cur, const Integer &i)
Divides cur by the given integer i.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::MulOp > operator*(const Integer &a, const Integer &b)
Multiplies the two integers and returns the result.
Represents a rational number as a quotient of two arbitrary precision integers.
Definition: rational.hpp:431
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::PowerOp > power(const Integer &a, const Integer &b)
Computes and returns a raised to the power of b.
Returns the product of the operands.
Integer operator++(Integer &cur, int)
Increments the integer by one and returns the previous value.
bool operator>(const Integer &a, const Integer &b)
Compares the current integer with the given one.
void shl(Integer &r, const Integer &a, long b)
Shifts a by b bits to the left and stores the result in r.
Returns the remainder of the operands.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::ShROp > operator>>(const Integer &a, const Integer &b)
Computes the bitwise right shift of the first integer by the number of bits given by the second integ...
Returns the power of the first operand to the second operand.
void addmul(Integer &r, const Integer &a, const Integer &b)
Multiplies a and b and adds the result to r.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::ModOp > operator%(const Integer &a, const Integer &b)
Divides the first by the second integer and returns the remainder.
Integer & operator>>=(Integer &cur, const Integer &i)
Computes the bitwise right shift of cur by i bits, and stores the result in cur.
void add(Integer &r, const Integer &a, const Integer &b)
Adds a and b and stores the result in r.
Implementation of raising to a power by a constant exponent.
expressions::Expression< IntegerContext, expressions::Wrapper< IntegerContext >, expressions::SquareOp > square(const Integer &i)
Computes and returns the square of i.
void decrement(Integer &r, const Integer &a)
Decrements a by one and stores the result in r.
Returns the absolute value of the operand.
Returns the square of the operand.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::AddOp > operator+(const Integer &a, const Integer &b)
Adds the two integers and returns the result.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::DivOp > operator/(const Integer &a, const Integer &b)
Divides the first by the second integer and returns the result.
Represents an arbitrary precision integer.
bool operator!=(const Integer &a, const Integer &b)
Compares the current integer with the given one for inequality.
Wraps a variable to behave similarly to an Expression<> object.
Returns the difference of the operands.
bool operator>=(const Integer &a, const Integer &b)
Compares the current integer with the given one.
Represents an arithmetic context for rational numbers.
Definition: rational.hpp:355
void sub(Integer &r, const Integer &a, const Integer &b)
Subtracts b from a and stores the result in r.