plll  1.0
arithmetic-gmp-iops.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__ARITHMETIC_GMP_INTEGER_OPS_HPP
24 #define PLLL_INCLUDE_GUARD__ARITHMETIC_GMP_INTEGER_OPS_HPP
25 
32 namespace plll
33 {
34  namespace arithmetic
35  {
36  namespace expressions
37  {
38  // Adding integer and (un)signed long
39  template<class D>
40  void do_assign(arithmetic::Integer & x,
41  const AddOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > > &,
42  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > & data)
43  {
44  add_ui(x, data.first.evaluate(), data.second.data().evaluate());
45  }
46 
47  template<class D>
48  void do_assign(arithmetic::Integer & x,
49  const AddOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > > &,
50  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > & data)
51  {
52  add_si(x, data.first.evaluate(), data.second.data().evaluate());
53  }
54 
55  template<class D>
56  void do_assign(arithmetic::Integer & x,
57  const AddOp<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context>, D> > &,
58  const std::pair< expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context>, D> & data)
59  {
60  add_ui(x, data.second.evaluate(), data.first.data().evaluate());
61  }
62 
63  template<class D>
64  void do_assign(arithmetic::Integer & x,
65  const AddOp<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context>, D> > &,
66  const std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context>, D> & data)
67  {
68  add_si(x, data.second.evaluate(), data.first.data().evaluate());
69  }
70 
71  // Subtracting integer and (un)signed long
72  template<class D>
73  void do_assign(arithmetic::Integer & x,
74  const SubOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > > &,
75  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > & data)
76  {
77  sub_ui(x, data.first.evaluate(), data.second.data().evaluate());
78  }
79 
80  template<class D>
81  void do_assign(arithmetic::Integer & x,
82  const SubOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > > &,
83  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > & data)
84  {
85  sub_si(x, data.first.evaluate(), data.second.data().evaluate());
86  }
87 
88  template<class D>
89  void do_assign(arithmetic::Integer & x,
90  const SubOp<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context>, D> > &,
91  const std::pair< expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context>, D> & data)
92  {
93  ui_sub(x, data.first.data().evaluate(), data.second.evaluate());
94  }
95 
96  template<class D>
97  void do_assign(arithmetic::Integer & x,
98  const SubOp<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context>, D> > &,
99  const std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context>, D> & data)
100  {
101  si_sub(x, data.first.data().evaluate(), data.second.evaluate());
102  }
103 
104  // Multiplying integer and (un)signed long
105  template<class D>
106  void do_assign(arithmetic::Integer & x,
107  const MulOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > > &,
108  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > & data)
109  {
110  mul_ui(x, data.first.evaluate(), data.second.data().evaluate());
111  }
112 
113  template<class D>
114  void do_assign(arithmetic::Integer & x,
115  const MulOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > > &,
116  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > & data)
117  {
118  mul_si(x, data.first.evaluate(), data.second.data().evaluate());
119  }
120 
121  template<class D>
122  void do_assign(arithmetic::Integer & x,
123  const MulOp<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context>, D> > &,
124  const std::pair< expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context>, D> & data)
125  {
126  mul_ui(x, data.second.evaluate(), data.first.data().evaluate());
127  }
128 
129  template<class D>
130  void do_assign(arithmetic::Integer & x,
131  const MulOp<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context>, D> > &,
132  const std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context>, D> & data)
133  {
134  mul_si(x, data.second.evaluate(), data.first.data().evaluate());
135  }
136 
137  // Dividing integer by (un)signed long
138  template<class D>
139  void do_assign(arithmetic::Integer & x,
140  const DivOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > > &,
141  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > & data)
142  {
143  div_ui(x, data.first.evaluate(), data.second.data().evaluate());
144  }
145 
146  template<class D>
147  void do_assign(arithmetic::Integer & x,
148  const DivOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > > &,
149  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > & data)
150  {
151  div_si(x, data.first.evaluate(), data.second.data().evaluate());
152  }
153 
154  // Modulo integer by (un)signed long
155  template<class D>
156  void do_assign(arithmetic::Integer & x,
157  const ModOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > > &,
158  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > & data)
159  {
160  mod_ui(x, data.first.evaluate(), data.second.data().evaluate());
161  }
162 
163  template<class D>
164  void do_assign(arithmetic::Integer & x,
165  const ModOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > > &,
166  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > & data)
167  {
168  mod_si(x, data.first.evaluate(), data.second.data().evaluate());
169  }
170 
171  // GCD with (un)signed long
172  template<class D>
173  void do_assign(arithmetic::Integer & x,
174  const GCDOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > > &,
175  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > & data)
176  {
177  gcd_ui(x, data.first.evaluate(), data.second.data().evaluate());
178  }
179 
180  template<class D>
181  void do_assign(arithmetic::Integer & x,
182  const GCDOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > > &,
183  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > & data)
184  {
185  gcd_si(x, data.first.evaluate(), data.second.data().evaluate());
186  }
187 
188  template<class D>
189  void do_assign(arithmetic::Integer & x,
190  const GCDOp<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context>, D> > &,
191  const std::pair< expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context>, D> & data)
192  {
193  gcd_ui(x, data.second.evaluate(), data.first.data().evaluate());
194  }
195 
196  template<class D>
197  void do_assign(arithmetic::Integer & x,
198  const GCDOp<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context>, D> > &,
199  const std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context>, D> & data)
200  {
201  gcd_si(x, data.second.evaluate(), data.first.data().evaluate());
202  }
203 
204  // LCM with (un)signed long
205  template<class D>
206  void do_assign(arithmetic::Integer & x,
207  const LCMOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > > &,
208  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> > & data)
209  {
210  lcm_ui(x, data.first.evaluate(), data.second.data().evaluate());
211  }
212 
213  template<class D>
214  void do_assign(arithmetic::Integer & x,
215  const LCMOp<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > > &,
216  const std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> > & data)
217  {
218  lcm_si(x, data.first.evaluate(), data.second.data().evaluate());
219  }
220 
221  template<class D>
222  void do_assign(arithmetic::Integer & x,
223  const LCMOp<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context>, D> > &,
224  const std::pair< expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context>, D> & data)
225  {
226  lcm_ui(x, data.second.evaluate(), data.first.data().evaluate());
227  }
228 
229  template<class D>
230  void do_assign(arithmetic::Integer & x,
231  const LCMOp<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context>, D> > &,
232  const std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context>, D> & data)
233  {
234  lcm_si(x, data.second.evaluate(), data.first.data().evaluate());
235  }
236  }
237 
248  inline expressions::Expression<IntegerContext, expressions::Wrapper<IntegerContext>,
258  inline expressions::Expression<IntegerContext, expressions::Wrapper<IntegerContext>,
269  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
270  expressions::Wrapper<IntegerContext> >,
274  expressions::AddOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
275  expressions::Wrapper<IntegerContext>(b))); }
283  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
284  expressions::Wrapper<IntegerContext> >,
288  expressions::SubOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
289  expressions::Wrapper<IntegerContext>(b))); }
297  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
298  expressions::Wrapper<IntegerContext> >,
302  expressions::MulOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
303  expressions::Wrapper<IntegerContext>(b))); }
311  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
312  expressions::Wrapper<IntegerContext> >,
316  expressions::DivOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
317  expressions::Wrapper<IntegerContext>(b))); }
325  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
326  expressions::Wrapper<IntegerContext> >,
330  expressions::ModOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
331  expressions::Wrapper<IntegerContext>(b))); }
339  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
340  expressions::Wrapper<IntegerContext> >,
344  expressions::AndOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
345  expressions::Wrapper<IntegerContext>(b))); }
353  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
354  expressions::Wrapper<IntegerContext> >,
358  expressions::OrOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
359  expressions::Wrapper<IntegerContext>(b))); }
367  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
368  expressions::Wrapper<IntegerContext> >,
372  expressions::XOROp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
373  expressions::Wrapper<IntegerContext>(b))); }
384  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
385  expressions::Wrapper<IntegerContext> >,
389  expressions::ShLOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
390  expressions::Wrapper<IntegerContext>(b))); }
402  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
403  expressions::Wrapper<IntegerContext> >,
407  expressions::ShROp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
408  expressions::Wrapper<IntegerContext>(b))); }
419  inline expressions::Expression<IntegerContext, expressions::Wrapper<IntegerContext>,
420  expressions::ShiftCOp> operator << (const Integer & a, signed long b)
434  inline expressions::Expression<IntegerContext, expressions::Wrapper<IntegerContext>,
435  expressions::ShiftCOp> operator >> (const Integer & a, signed long b)
439 
440  // second operand is expression
441  template<class A2, template<typename, typename> class O2>
442  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
443  expressions::Expression<IntegerContext, A2, O2> >,
444  expressions::AddOp> operator + (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
445  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
446  expressions::Expression<IntegerContext, A2, O2> >,
447  expressions::AddOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
448  template<class A2, template<typename, typename> class O2>
449  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
450  expressions::Expression<IntegerContext, A2, O2> >,
451  expressions::SubOp> operator - (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
452  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
453  expressions::Expression<IntegerContext, A2, O2> >,
454  expressions::SubOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
455  template<class A2, template<typename, typename> class O2>
456  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
457  expressions::Expression<IntegerContext, A2, O2> >,
458  expressions::MulOp> operator * (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
459  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
460  expressions::Expression<IntegerContext, A2, O2> >,
461  expressions::MulOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
462  template<class A2, template<typename, typename> class O2>
463  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
464  expressions::Expression<IntegerContext, A2, O2> >,
465  expressions::DivOp> operator / (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
466  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
467  expressions::Expression<IntegerContext, A2, O2> >,
468  expressions::DivOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
469  template<class A2, template<typename, typename> class O2>
470  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
471  expressions::Expression<IntegerContext, A2, O2> >,
472  expressions::ModOp> operator % (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
473  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
474  expressions::Expression<IntegerContext, A2, O2> >,
475  expressions::ModOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
476  template<class A2, template<typename, typename> class O2>
477  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
478  expressions::Expression<IntegerContext, A2, O2> >,
479  expressions::AndOp> operator & (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
480  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
481  expressions::Expression<IntegerContext, A2, O2> >,
482  expressions::AndOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
483  template<class A2, template<typename, typename> class O2>
484  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
485  expressions::Expression<IntegerContext, A2, O2> >,
486  expressions::OrOp> operator | (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
487  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
488  expressions::Expression<IntegerContext, A2, O2> >,
489  expressions::OrOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
490  template<class A2, template<typename, typename> class O2>
491  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
492  expressions::Expression<IntegerContext, A2, O2> >,
493  expressions::XOROp> operator ^ (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
494  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
495  expressions::Expression<IntegerContext, A2, O2> >,
496  expressions::XOROp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
497  template<class A2, template<typename, typename> class O2>
498  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
499  expressions::Expression<IntegerContext, A2, O2> >,
500  expressions::ShLOp> operator << (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
501  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
502  expressions::Expression<IntegerContext, A2, O2> >,
503  expressions::ShLOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
504  template<class A2, template<typename, typename> class O2>
505  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
506  expressions::Expression<IntegerContext, A2, O2> >,
507  expressions::ShROp> operator >> (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
508  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
509  expressions::Expression<IntegerContext, A2, O2> >,
510  expressions::ShROp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
511 
512  namespace expressions
513  {
514  // first operand is expression
515  template<class A1, template<typename, typename> class O1>
516  inline expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A1, O1>,
517  expressions::NegOp> operator - (const expressions::Expression<IntegerContext, A1, O1> & a)
518  { return expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A1, O1>,
519  expressions::NegOp>(a); }
520  template<class A1, template<typename, typename> class O1>
521  inline expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A1, O1>,
522  expressions::BitInvOp> operator ~ (const expressions::Expression<IntegerContext, A1, O1> & a)
523  { return expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A1, O1>,
524  expressions::BitInvOp>(a); }
525  template<class A1, template<typename, typename> class O1>
526  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
527  expressions::Wrapper<IntegerContext> >,
528  expressions::AddOp> operator + (const expressions::Expression<IntegerContext, A1, O1> & a, const Integer & b)
529  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
530  expressions::Wrapper<IntegerContext> >,
531  expressions::AddOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
532  template<class A1, template<typename, typename> class O1>
533  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
534  expressions::Wrapper<IntegerContext> >,
535  expressions::SubOp> operator - (const expressions::Expression<IntegerContext, A1, O1> & a, const Integer & b)
536  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
537  expressions::Wrapper<IntegerContext> >,
538  expressions::SubOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
539  template<class A1, template<typename, typename> class O1>
540  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
541  expressions::Wrapper<IntegerContext> >,
542  expressions::MulOp> operator * (const expressions::Expression<IntegerContext, A1, O1> & a, const Integer & b)
543  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
544  expressions::Wrapper<IntegerContext> >,
545  expressions::MulOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
546  template<class A1, template<typename, typename> class O1>
547  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
548  expressions::Wrapper<IntegerContext> >,
549  expressions::DivOp> operator / (const expressions::Expression<IntegerContext, A1, O1> & a, const Integer & b)
550  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
551  expressions::Wrapper<IntegerContext> >,
552  expressions::DivOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
553  template<class A1, template<typename, typename> class O1>
554  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
555  expressions::Wrapper<IntegerContext> >,
556  expressions::ModOp> operator % (const expressions::Expression<IntegerContext, A1, O1> & a, const Integer & b)
557  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
558  expressions::Wrapper<IntegerContext> >,
559  expressions::ModOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
560  template<class A1, template<typename, typename> class O1>
561  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
562  expressions::Wrapper<IntegerContext> >,
563  expressions::AndOp> operator & (const expressions::Expression<IntegerContext, A1, O1> & a, const Integer & b)
564  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
565  expressions::Wrapper<IntegerContext> >,
566  expressions::AndOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
567  template<class A1, template<typename, typename> class O1>
568  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
569  expressions::Wrapper<IntegerContext> >,
570  expressions::OrOp> operator | (const expressions::Expression<IntegerContext, A1, O1> & a, const Integer & b)
571  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
572  expressions::Wrapper<IntegerContext> >,
573  expressions::OrOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
574  template<class A1, template<typename, typename> class O1>
575  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
576  expressions::Wrapper<IntegerContext> >,
577  expressions::XOROp> operator ^ (const expressions::Expression<IntegerContext, A1, O1> & a, const Integer & b)
578  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
579  expressions::Wrapper<IntegerContext> >,
580  expressions::XOROp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
581  template<class A1, template<typename, typename> class O1>
582  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
583  expressions::Wrapper<IntegerContext> >,
584  expressions::ShLOp> operator << (const expressions::Expression<IntegerContext, A1, O1> & a, const Integer & b)
585  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
586  expressions::Wrapper<IntegerContext> >,
587  expressions::ShLOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
588  template<class A1, template<typename, typename> class O1>
589  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
590  expressions::Wrapper<IntegerContext> >,
591  expressions::ShROp> operator >> (const expressions::Expression<IntegerContext, A1, O1> & a, const Integer & b)
592  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
593  expressions::Wrapper<IntegerContext> >,
594  expressions::ShROp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
595  template<class A1, template<typename, typename> class O1>
596  inline expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A1, O1>,
597  expressions::ShiftCOp> operator << (const expressions::Expression<IntegerContext, A1, O1> & a, signed long b)
598  { return expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A1, O1>,
599  expressions::ShiftCOp>(a, b); }
600  template<class A1, template<typename, typename> class O1>
601  inline expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A1, O1>,
602  expressions::ShiftCOp> operator >> (const expressions::Expression<IntegerContext, A1, O1> & a, signed long b)
603  { return expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A1, O1>,
604  expressions::ShiftCOp>(a, -b); }
605 
606  // both operands are expressions
607  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
608  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
609  expressions::Expression<IntegerContext, A2, O2> >,
610  expressions::AddOp> operator + (const expressions::Expression<IntegerContext, A1, O1> & a,
611  const expressions::Expression<IntegerContext, A2, O2> & b)
612  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
613  expressions::Expression<IntegerContext, A2, O2> >,
614  expressions::AddOp>(std::make_pair(a, b)); }
615  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
616  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
617  expressions::Expression<IntegerContext, A2, O2> >,
618  expressions::SubOp> operator - (const expressions::Expression<IntegerContext, A1, O1> & a,
619  const expressions::Expression<IntegerContext, A2, O2> & b)
620  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
621  expressions::Expression<IntegerContext, A2, O2> >,
622  expressions::SubOp>(std::make_pair(a, b)); }
623  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
624  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
625  expressions::Expression<IntegerContext, A2, O2> >,
626  expressions::MulOp> operator * (const expressions::Expression<IntegerContext, A1, O1> & a,
627  const expressions::Expression<IntegerContext, A2, O2> & b)
628  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
629  expressions::Expression<IntegerContext, A2, O2> >,
630  expressions::MulOp>(std::make_pair(a, b)); }
631  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
632  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
633  expressions::Expression<IntegerContext, A2, O2> >,
634  expressions::DivOp> operator / (const expressions::Expression<IntegerContext, A1, O1> & a,
635  const expressions::Expression<IntegerContext, A2, O2> & b)
636  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
637  expressions::Expression<IntegerContext, A2, O2> >,
638  expressions::DivOp>(std::make_pair(a, b)); }
639  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
640  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
641  expressions::Expression<IntegerContext, A2, O2> >,
642  expressions::ModOp> operator % (const expressions::Expression<IntegerContext, A1, O1> & a,
643  const expressions::Expression<IntegerContext, A2, O2> & b)
644  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
645  expressions::Expression<IntegerContext, A2, O2> >,
646  expressions::ModOp>(std::make_pair(a, b)); }
647  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
648  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
649  expressions::Expression<IntegerContext, A2, O2> >,
650  expressions::AndOp> operator & (const expressions::Expression<IntegerContext, A1, O1> & a,
651  const expressions::Expression<IntegerContext, A2, O2> & b)
652  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
653  expressions::Expression<IntegerContext, A2, O2> >,
654  expressions::AndOp>(std::make_pair(a, b)); }
655  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
656  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
657  expressions::Expression<IntegerContext, A2, O2> >,
658  expressions::OrOp> operator | (const expressions::Expression<IntegerContext, A1, O1> & a,
659  const expressions::Expression<IntegerContext, A2, O2> & b)
660  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
661  expressions::Expression<IntegerContext, A2, O2> >,
662  expressions::OrOp>(std::make_pair(a, b)); }
663  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
664  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
665  expressions::Expression<IntegerContext, A2, O2> >,
666  expressions::XOROp> operator ^ (const expressions::Expression<IntegerContext, A1, O1> & a,
667  const expressions::Expression<IntegerContext, A2, O2> & b)
668  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
669  expressions::Expression<IntegerContext, A2, O2> >,
670  expressions::XOROp>(std::make_pair(a, b)); }
671  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
672  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
673  expressions::Expression<IntegerContext, A2, O2> >,
674  expressions::ShLOp> operator << (const expressions::Expression<IntegerContext, A1, O1> & a,
675  const expressions::Expression<IntegerContext, A2, O2> & b)
676  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
677  expressions::Expression<IntegerContext, A2, O2> >,
678  expressions::ShLOp>(std::make_pair(a, b)); }
679  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
680  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
681  expressions::Expression<IntegerContext, A2, O2> >,
682  expressions::ShROp> operator >> (const expressions::Expression<IntegerContext, A1, O1> & a,
683  const expressions::Expression<IntegerContext, A2, O2> & b)
684  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A1, O1>,
685  expressions::Expression<IntegerContext, A2, O2> >,
686  expressions::ShROp>(std::make_pair(a, b)); }
687 
688  template<class A, template<typename, typename> class O>
689  inline bool isZero(const expressions::Expression<IntegerContext, A, O> & i)
690  {
691  return isZero(i.evaluate());
692  }
693 
694  template<class A, template<typename, typename> class O>
695  inline bool isOne(const expressions::Expression<IntegerContext, A, O> & i)
696  {
697  return isOne(i.evaluate());
698  }
699 
700  template<class A, template<typename, typename> class O>
701  inline bool isPMOne(const expressions::Expression<IntegerContext, A, O> & i)
702  {
703  return isPMOne(i.evaluate());
704  }
705 
706  template<class A, template<typename, typename> class O>
707  inline bool isPMTwo(const expressions::Expression<IntegerContext, A, O> & i)
708  {
709  return isPMTwo(i.evaluate());
710  }
711 
712  template<class A, template<typename, typename> class O>
713  inline bool isPositive(const expressions::Expression<IntegerContext, A, O> & i)
714  {
715  return isPositive(i.evaluate());
716  }
717 
718  template<class A, template<typename, typename> class O>
719  inline bool isNonNegative(const expressions::Expression<IntegerContext, A, O> & i)
720  {
721  return isNonNegative(i.evaluate());
722  }
723 
724  template<class A, template<typename, typename> class O>
725  inline bool isNegative(const expressions::Expression<IntegerContext, A, O> & i)
726  {
727  return isNegative(i.evaluate());
728  }
729 
730  template<class A, template<typename, typename> class O>
731  inline bool isNonPositive(const expressions::Expression<IntegerContext, A, O> & i)
732  {
733  return isNonPositive(i.evaluate());
734  }
735 
736  template<class A, template<typename, typename> class O>
737  inline std::ostream & operator << (std::ostream & s, const expressions::Expression<IntegerContext, A, O> & i)
738  {
739  return s << i.evaluate();
740  }
741  }
742 
753  inline Integer operator ++ (Integer & cur, int)
754  {
755  Integer r(cur);
756  increment(cur, cur);
757  return r;
758  }
759 
766  inline Integer operator -- (Integer & cur, int)
767  {
768  Integer r(cur);
769  decrement(cur, cur);
770  return r;
771  }
772 
779  inline Integer & operator ++ (Integer & cur)
780  {
781  increment(cur, cur);
782  return cur;
783  }
784 
791  inline Integer & operator -- (Integer & cur)
792  {
793  decrement(cur, cur);
794  return cur;
795  }
796 
798 
813  template<class D>
815  {
816  submul(cur, E.data().first.evaluate(), E.data().second.evaluate());
817  return cur;
818  }
819 
827  inline Integer & operator -= (Integer & cur, const Integer & i)
828  {
829  sub(cur, cur, i);
830  return cur;
831  }
832 
843  template<class D>
845  {
846  addmul(cur, E.data().first.evaluate(), E.data().second.evaluate());
847  return cur;
848  }
849 
857  inline Integer & operator += (Integer & cur, const Integer & i)
858  {
859  add(cur, cur, i);
860  return cur;
861  }
862 
870  inline Integer & operator *= (Integer & cur, const Integer & i)
871  {
872  mul(cur, cur, i);
873  return cur;
874  }
875 
883  inline Integer & operator /= (Integer & cur, const Integer & i)
884  {
885  div(cur, cur, i);
886  return cur;
887  }
888 
897  inline Integer & operator %= (Integer & cur, const Integer & i)
898  {
899  mod(cur, cur, i);
900  return cur;
901  }
902 
910  inline Integer & operator |= (Integer & cur, const Integer & i)
911  {
912  bor(cur, cur, i);
913  return cur;
914  }
915 
923  inline Integer & operator &= (Integer & cur, const Integer & i)
924  {
925  band(cur, cur, i);
926  return cur;
927  }
928 
937  inline Integer & operator ^= (Integer & cur, const Integer & i)
938  {
939  bxor(cur, cur, i);
940  return cur;
941  }
942 
953  inline Integer & operator <<= (Integer & cur, const Integer & i)
954  {
955  shl(cur, cur, i);
956  return cur;
957  }
958 
969  inline Integer & operator >>= (Integer & cur, const Integer & i)
970  {
971  shr(cur, cur, i);
972  return cur;
973  }
974 
985  inline Integer & operator <<= (Integer & cur, long i)
986  {
987  shl(cur, cur, i);
988  return cur;
989  }
990 
1001  inline Integer & operator >>= (Integer & cur, long i)
1002  {
1003  shr(cur, cur, i);
1004  return cur;
1005  }
1006 
1008 
1009  inline Integer & operator -= (Integer & cur, const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & E)
1010  {
1011  sub_si(cur, cur, E.data().evaluate());
1012  return cur;
1013  }
1014 
1015  inline Integer & operator -= (Integer & cur, const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & E)
1016  {
1017  sub_ui(cur, cur, E.data().evaluate());
1018  return cur;
1019  }
1020 
1021  template<class D>
1022  inline Integer & operator -= (Integer & cur, const expressions::Expression<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> >, expressions::MulOp> & E)
1023  {
1024  submul_ui(cur, E.data().first.evaluate(), E.data().second.data().evaluate());
1025  return cur;
1026  }
1027 
1028  template<class D>
1029  inline Integer & operator -= (Integer & cur, const expressions::Expression<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> >, expressions::MulOp> & E)
1030  {
1031  submul_si(cur, E.data().first.evaluate(), E.data().second.data().evaluate());
1032  return cur;
1033  }
1034 
1035  template<class D>
1036  inline Integer & operator -= (Integer & cur, const expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context>, D>, expressions::MulOp> & E)
1037  {
1038  submul_ui(cur, E.data().second.evaluate(), E.data().first.data().evaluate());
1039  return cur;
1040  }
1041 
1042  template<class D>
1043  inline Integer & operator -= (Integer & cur, const expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context>, D>, expressions::MulOp> & E)
1044  {
1045  mpz_submul_ui(cur, E.data().second.evaluate(), E.data().first.data().evaluate());
1046  return cur;
1047  }
1048 
1049  inline Integer & operator += (Integer & cur, const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & E)
1050  {
1051  add_si(cur, cur, E.data().evaluate());
1052  return cur;
1053  }
1054 
1055  inline Integer & operator += (Integer & cur, const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & E)
1056  {
1057  add_ui(cur, cur, E.data().evaluate());
1058  return cur;
1059  }
1060 
1061  template<class D>
1062  inline Integer & operator += (Integer & cur, const expressions::Expression<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> >, expressions::MulOp> & E)
1063  {
1064  addmul_ui(cur, E.data().first.evaluate(), E.data().second.data().evaluate());
1065  return cur;
1066  }
1067 
1068  template<class D>
1069  inline Integer & operator += (Integer & cur, const expressions::Expression<IntegerContext, std::pair<D, expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> >, expressions::MulOp> & E)
1070  {
1071  addmul_si(cur, E.data().first.evaluate(), E.data().second.data().evaluate());
1072  return cur;
1073  }
1074 
1075  template<class D>
1076  inline Integer & operator += (Integer & cur, const expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context>, D>, expressions::MulOp> & E)
1077  {
1078  addmul_ui(cur, E.data().second.evaluate(), E.data().first.data().evaluate());
1079  return cur;
1080  }
1081 
1082  template<class D>
1083  inline Integer & operator += (Integer & cur, const expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context>, D>, expressions::MulOp> & E)
1084  {
1085  addmul_si(cur, E.data().second.evaluate(), E.data().first.data().evaluate());
1086  return cur;
1087  }
1088 
1089  inline Integer & operator *= (Integer & cur, const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & E)
1090  {
1091  mpz_mul_si(cur.getInternal(), cur.getInternal(), E.data().evaluate());
1092  return cur;
1093  }
1094 
1095  inline Integer & operator *= (Integer & cur, const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & E)
1096  {
1097  mpz_mul_ui(cur.getInternal(), cur.getInternal(), E.data().evaluate());
1098  return cur;
1099  }
1100 
1101  inline Integer & operator /= (Integer & cur, const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & E)
1102  {
1103  if (E.data().evaluate() < 0)
1104  {
1105  mpz_tdiv_q_ui(cur.getInternal(), cur.getInternal(), -E.data().evaluate());
1106  neg(cur, cur);
1107  }
1108  else
1109  mpz_tdiv_q_ui(cur.getInternal(), cur.getInternal(), E.data().evaluate());
1110  return cur;
1111  }
1112 
1113  inline Integer & operator /= (Integer & cur, const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & E)
1114  {
1115  mpz_tdiv_q_ui(cur.getInternal(), cur.getInternal(), E.data().evaluate());
1116  return cur;
1117  }
1118 
1119  inline Integer & operator %= (Integer & cur, const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & E)
1120  {
1121  if (E.data().evaluate() < 0)
1122  mpz_tdiv_r_ui(cur.getInternal(), cur.getInternal(), -E.data().evaluate());
1123  else
1124  mpz_tdiv_r_ui(cur.getInternal(), cur.getInternal(), E.data().evaluate());
1125  return cur;
1126  }
1127 
1128  inline Integer & operator %= (Integer & cur, const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & E)
1129  {
1130  mpz_tdiv_r_ui(cur.getInternal(), cur.getInternal(), E.data().evaluate());
1131  return cur;
1132  }
1133 
1144  inline bool operator == (const Integer & a, const Integer & b)
1145  {
1146  return mpz_cmp(a.d_value, b.d_value) == 0;
1147  }
1148 
1155  inline bool operator != (const Integer & a, const Integer & b)
1156  {
1157  return mpz_cmp(a.d_value, b.d_value) != 0;
1158  }
1159 
1166  inline bool operator <= (const Integer & a, const Integer & b)
1167  {
1168  return mpz_cmp(a.d_value, b.d_value) <= 0;
1169  }
1170 
1177  inline bool operator >= (const Integer & a, const Integer & b)
1178  {
1179  return mpz_cmp(a.d_value, b.d_value) >= 0;
1180  }
1181 
1188  inline bool operator < (const Integer & a, const Integer & b)
1189  {
1190  return mpz_cmp(a.d_value, b.d_value) < 0;
1191  }
1192 
1199  inline bool operator > (const Integer & a, const Integer & b)
1200  {
1201  return mpz_cmp(a.d_value, b.d_value) > 0;
1202  }
1203 
1205 
1206  // Second operand is expression: make both operands expressions
1207  template<class A2, template<typename, typename> class O2>
1208  inline bool operator == (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
1209  {
1210  return expressions::make_expression<IntegerContext>(a) == b;
1211  }
1212 
1213  template<class A2, template<typename, typename> class O2>
1214  inline bool operator != (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
1215  {
1216  return expressions::make_expression<IntegerContext>(a) != b;
1217  }
1218 
1219  template<class A2, template<typename, typename> class O2>
1220  inline bool operator <= (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
1221  {
1222  return expressions::make_expression<IntegerContext>(a) <= b;
1223  }
1224 
1225  template<class A2, template<typename, typename> class O2>
1226  inline bool operator >= (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
1227  {
1228  return expressions::make_expression<IntegerContext>(a) >= b;
1229  }
1230 
1231  template<class A2, template<typename, typename> class O2>
1232  inline bool operator < (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
1233  {
1234  return expressions::make_expression<IntegerContext>(a) < b;
1235  }
1236 
1237  template<class A2, template<typename, typename> class O2>
1238  inline bool operator > (const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
1239  {
1240  return expressions::make_expression<IntegerContext>(a) > b;
1241  }
1242 
1243  namespace implementation
1244  {
1245  namespace Integer_impl
1246  {
1247  // First operand is expression: make both operands expressions
1248  template<class A1, template<typename, typename> class O1>
1249  inline bool operator == (const expressions::Expression<IntegerContext, A1, O1> & a, const arithmetic::Integer & b)
1250  {
1251  return a == expressions::make_expression<IntegerContext>(b);
1252  }
1253 
1254  template<class A1, template<typename, typename> class O1>
1255  inline bool operator != (const expressions::Expression<IntegerContext, A1, O1> & a, const arithmetic::Integer & b)
1256  {
1257  return a != expressions::make_expression<IntegerContext>(b);
1258  }
1259 
1260  template<class A1, template<typename, typename> class O1>
1261  inline bool operator <= (const expressions::Expression<IntegerContext, A1, O1> & a, const arithmetic::Integer & b)
1262  {
1263  return a <= expressions::make_expression<IntegerContext>(b);
1264  }
1265 
1266  template<class A1, template<typename, typename> class O1>
1267  inline bool operator >= (const expressions::Expression<IntegerContext, A1, O1> & a, const arithmetic::Integer & b)
1268  {
1269  return a >= expressions::make_expression<IntegerContext>(b);
1270  }
1271 
1272  template<class A1, template<typename, typename> class O1>
1273  inline bool operator < (const expressions::Expression<IntegerContext, A1, O1> & a, const arithmetic::Integer & b)
1274  {
1275  return a < expressions::make_expression<IntegerContext>(b);
1276  }
1277 
1278  template<class A1, template<typename, typename> class O1>
1279  inline bool operator > (const expressions::Expression<IntegerContext, A1, O1> & a, const arithmetic::Integer & b)
1280  {
1281  return a > expressions::make_expression<IntegerContext>(b);
1282  }
1283 
1284  // Both operands are expressions
1285  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
1286  inline bool operator == (const expressions::Expression<IntegerContext, A1, O1> & a,
1287  const expressions::Expression<IntegerContext, A2, O2> & b)
1288  {
1289  return a.evaluate() == b.evaluate();
1290  }
1291 
1292  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
1293  inline bool operator != (const expressions::Expression<IntegerContext, A1, O1> & a,
1294  const expressions::Expression<IntegerContext, A2, O2> & b)
1295  {
1296  return a.evaluate() != b.evaluate();
1297  }
1298 
1299  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
1300  inline bool operator <= (const expressions::Expression<IntegerContext, A1, O1> & a,
1301  const expressions::Expression<IntegerContext, A2, O2> & b)
1302  {
1303  return a.evaluate() <= b.evaluate();
1304  }
1305 
1306  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
1307  inline bool operator >= (const expressions::Expression<IntegerContext, A1, O1> & a,
1308  const expressions::Expression<IntegerContext, A2, O2> & b)
1309  {
1310  return a.evaluate() >= b.evaluate();
1311  }
1312 
1313  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
1314  inline bool operator < (const expressions::Expression<IntegerContext, A1, O1> & a,
1315  const expressions::Expression<IntegerContext, A2, O2> & b)
1316  {
1317  return a.evaluate() < b.evaluate();
1318  }
1319 
1320  template<class A1, template<typename, typename> class O1, class A2, template<typename, typename> class O2>
1321  inline bool operator > (const expressions::Expression<IntegerContext, A1, O1> & a,
1322  const expressions::Expression<IntegerContext, A2, O2> & b)
1323  {
1324  return a.evaluate() > b.evaluate();
1325  }
1326 
1327  // First operand is integer conversion expression, second operand arbitrary expression
1328  template<class A2, template<typename, typename> class O2>
1329  inline bool operator == (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & a,
1330  const expressions::Expression<IntegerContext, A2, O2> & b)
1331  { return compare_ui(b.evaluate(), a.data().evaluate()) == 0; }
1332  template<class A2, template<typename, typename> class O2>
1333  inline bool operator != (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & a,
1334  const expressions::Expression<IntegerContext, A2, O2> & b)
1335  { return compare_ui(b.evaluate(), a.data().evaluate()) != 0; }
1336  template<class A2, template<typename, typename> class O2>
1337  inline bool operator <= (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & a,
1338  const expressions::Expression<IntegerContext, A2, O2> & b)
1339  { return compare_ui(b.evaluate(), a.data().evaluate()) >= 0; }
1340  template<class A2, template<typename, typename> class O2>
1341  inline bool operator >= (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & a,
1342  const expressions::Expression<IntegerContext, A2, O2> & b)
1343  { return compare_ui(b.evaluate(), a.data().evaluate()) <= 0; }
1344  template<class A2, template<typename, typename> class O2>
1345  inline bool operator < (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & a,
1346  const expressions::Expression<IntegerContext, A2, O2> & b)
1347  { return compare_ui(b.evaluate(), a.data().evaluate()) > 0; }
1348  template<class A2, template<typename, typename> class O2>
1349  inline bool operator > (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & a,
1350  const expressions::Expression<IntegerContext, A2, O2> & b)
1351  { return compare_ui(b.evaluate(), a.data().evaluate()) < 0; }
1352 
1353  template<class A2, template<typename, typename> class O2>
1354  inline bool operator == (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & a,
1355  const expressions::Expression<IntegerContext, A2, O2> & b)
1356  { return compare_si(b.evaluate(), a.data().evaluate()) == 0; }
1357  template<class A2, template<typename, typename> class O2>
1358  inline bool operator != (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & a,
1359  const expressions::Expression<IntegerContext, A2, O2> & b)
1360  { return compare_si(b.evaluate(), a.data().evaluate()) != 0; }
1361  template<class A2, template<typename, typename> class O2>
1362  inline bool operator <= (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & a,
1363  const expressions::Expression<IntegerContext, A2, O2> & b)
1364  { return compare_si(b.evaluate(), a.data().evaluate()) >= 0; }
1365  template<class A2, template<typename, typename> class O2>
1366  inline bool operator >= (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & a,
1367  const expressions::Expression<IntegerContext, A2, O2> & b)
1368  { return compare_si(b.evaluate(), a.data().evaluate()) <= 0; }
1369  template<class A2, template<typename, typename> class O2>
1370  inline bool operator < (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & a,
1371  const expressions::Expression<IntegerContext, A2, O2> & b)
1372  { return compare_si(b.evaluate(), a.data().evaluate()) > 0; }
1373  template<class A2, template<typename, typename> class O2>
1374  inline bool operator > (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & a,
1375  const expressions::Expression<IntegerContext, A2, O2> & b)
1376  { return compare_si(b.evaluate(), a.data().evaluate()) < 0; }
1377 
1378  template<class A2, template<typename, typename> class O2>
1379  inline bool operator == (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<double>, expressions::ConvertOp_Context> & a,
1380  const expressions::Expression<IntegerContext, A2, O2> & b)
1381  { return compare_d(b.evaluate(), a.data().evaluate()) == 0; }
1382  template<class A2, template<typename, typename> class O2>
1383  inline bool operator != (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<double>, expressions::ConvertOp_Context> & a,
1384  const expressions::Expression<IntegerContext, A2, O2> & b)
1385  { return compare_d(b.evaluate(), a.data().evaluate()) != 0; }
1386  template<class A2, template<typename, typename> class O2>
1387  inline bool operator <= (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<double>, expressions::ConvertOp_Context> & a,
1388  const expressions::Expression<IntegerContext, A2, O2> & b)
1389  { return compare_d(b.evaluate(), a.data().evaluate()) >= 0; }
1390  template<class A2, template<typename, typename> class O2>
1391  inline bool operator >= (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<double>, expressions::ConvertOp_Context> & a,
1392  const expressions::Expression<IntegerContext, A2, O2> & b)
1393  { return compare_d(b.evaluate(), a.data().evaluate()) <= 0; }
1394  template<class A2, template<typename, typename> class O2>
1395  inline bool operator < (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<double>, expressions::ConvertOp_Context> & a,
1396  const expressions::Expression<IntegerContext, A2, O2> & b)
1397  { return compare_d(b.evaluate(), a.data().evaluate()) > 0; }
1398  template<class A2, template<typename, typename> class O2>
1399  inline bool operator > (const expressions::Expression<IntegerContext, expressions::ConversionWrapper<double>, expressions::ConvertOp_Context> & a,
1400  const expressions::Expression<IntegerContext, A2, O2> & b)
1401  { return compare_d(b.evaluate(), a.data().evaluate()) < 0; }
1402 
1403  // First operand is arbitrary expression, Second operand is integer conversion expression
1404  template<class A1, template<typename, typename> class O1>
1405  inline bool operator == (const expressions::Expression<IntegerContext, A1, O1> & a,
1406  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & b)
1407  { return compare_ui(a.evaluate(), b.data().evaluate()) == 0; }
1408  template<class A1, template<typename, typename> class O1>
1409  inline bool operator != (const expressions::Expression<IntegerContext, A1, O1> & a,
1410  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & b)
1411  { return compare_ui(a.evaluate(), b.data().evaluate()) != 0; }
1412  template<class A1, template<typename, typename> class O1>
1413  inline bool operator <= (const expressions::Expression<IntegerContext, A1, O1> & a,
1414  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & b)
1415  { return compare_ui(a.evaluate(), b.data().evaluate()) <= 0; }
1416  template<class A1, template<typename, typename> class O1>
1417  inline bool operator >= (const expressions::Expression<IntegerContext, A1, O1> & a,
1418  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & b)
1419  { return compare_ui(a.evaluate(), b.data().evaluate()) >= 0; }
1420  template<class A1, template<typename, typename> class O1>
1421  inline bool operator < (const expressions::Expression<IntegerContext, A1, O1> & a,
1422  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & b)
1423  { return compare_ui(a.evaluate(), b.data().evaluate()) < 0; }
1424  template<class A1, template<typename, typename> class O1>
1425  inline bool operator > (const expressions::Expression<IntegerContext, A1, O1> & a,
1426  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<unsigned long>, expressions::ConvertOp_Context> & b)
1427  { return compare_ui(a.evaluate(), b.data().evaluate()) > 0; }
1428 
1429  template<class A1, template<typename, typename> class O1>
1430  inline bool operator == (const expressions::Expression<IntegerContext, A1, O1> & a,
1431  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & b)
1432  { return compare_si(a.evaluate(), b.data().evaluate()) == 0; }
1433  template<class A1, template<typename, typename> class O1>
1434  inline bool operator != (const expressions::Expression<IntegerContext, A1, O1> & a,
1435  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & b)
1436  { return compare_si(a.evaluate(), b.data().evaluate()) != 0; }
1437  template<class A1, template<typename, typename> class O1>
1438  inline bool operator <= (const expressions::Expression<IntegerContext, A1, O1> & a,
1439  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & b)
1440  { return compare_si(a.evaluate(), b.data().evaluate()) <= 0; }
1441  template<class A1, template<typename, typename> class O1>
1442  inline bool operator >= (const expressions::Expression<IntegerContext, A1, O1> & a,
1443  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & b)
1444  { return compare_si(a.evaluate(), b.data().evaluate()) >= 0; }
1445  template<class A1, template<typename, typename> class O1>
1446  inline bool operator < (const expressions::Expression<IntegerContext, A1, O1> & a,
1447  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & b)
1448  { return compare_si(a.evaluate(), b.data().evaluate()) < 0; }
1449  template<class A1, template<typename, typename> class O1>
1450  inline bool operator > (const expressions::Expression<IntegerContext, A1, O1> & a,
1451  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<signed long>, expressions::ConvertOp_Context> & b)
1452  { return compare_si(a.evaluate(), b.data().evaluate()) > 0; }
1453 
1454  template<class A1, template<typename, typename> class O1>
1455  inline bool operator == (const expressions::Expression<IntegerContext, A1, O1> & a,
1456  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<double>, expressions::ConvertOp_Context> & b)
1457  { return compare_d(a.evaluate(), b.data().evaluate()) == 0; }
1458  template<class A1, template<typename, typename> class O1>
1459  inline bool operator != (const expressions::Expression<IntegerContext, A1, O1> & a,
1460  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<double>, expressions::ConvertOp_Context> & b)
1461  { return compare_d(a.evaluate(), b.data().evaluate()) != 0; }
1462  template<class A1, template<typename, typename> class O1>
1463  inline bool operator <= (const expressions::Expression<IntegerContext, A1, O1> & a,
1464  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<double>, expressions::ConvertOp_Context> & b)
1465  { return compare_d(a.evaluate(), b.data().evaluate()) <= 0; }
1466  template<class A1, template<typename, typename> class O1>
1467  inline bool operator >= (const expressions::Expression<IntegerContext, A1, O1> & a,
1468  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<double>, expressions::ConvertOp_Context> & b)
1469  { return compare_d(a.evaluate(), b.data().evaluate()) >= 0; }
1470  template<class A1, template<typename, typename> class O1>
1471  inline bool operator < (const expressions::Expression<IntegerContext, A1, O1> & a,
1472  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<double>, expressions::ConvertOp_Context> & b)
1473  { return compare_d(a.evaluate(), b.data().evaluate()) < 0; }
1474  template<class A1, template<typename, typename> class O1>
1475  inline bool operator > (const expressions::Expression<IntegerContext, A1, O1> & a,
1476  const expressions::Expression<IntegerContext, expressions::ConversionWrapper<double>, expressions::ConvertOp_Context> & b)
1477  { return compare_d(a.evaluate(), b.data().evaluate()) > 0; }
1478  }
1479  }
1480 
1489  inline expressions::Expression<IntegerContext, expressions::Wrapper<IntegerContext>,
1492  expressions::AbsOp>(expressions::Wrapper<IntegerContext>(i)); }
1498  inline expressions::Expression<IntegerContext, expressions::Wrapper<IntegerContext>,
1501  expressions::SquareOp>(expressions::Wrapper<IntegerContext>(i)); }
1503 
1511  inline expressions::Expression<IntegerContext, expressions::Wrapper<IntegerContext>,
1514  expressions::SqrtCeilOp>(expressions::Wrapper<IntegerContext>(i)); }
1520  inline expressions::Expression<IntegerContext, expressions::Wrapper<IntegerContext>,
1523  expressions::SqrtFloorOp>(expressions::Wrapper<IntegerContext>(i)); }
1525 
1534  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1535  expressions::Wrapper<IntegerContext> >,
1536  expressions::GCDOp> GCD(const Integer & a, const Integer & b)
1538  expressions::Wrapper<IntegerContext> >,
1539  expressions::GCDOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
1540  expressions::Wrapper<IntegerContext>(b))); }
1547  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1548  expressions::Wrapper<IntegerContext> >,
1549  expressions::LCMOp> LCM(const Integer & a, const Integer & b)
1551  expressions::Wrapper<IntegerContext> >,
1552  expressions::LCMOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
1553  expressions::Wrapper<IntegerContext>(b))); }
1555 
1564  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1565  expressions::Wrapper<IntegerContext> >,
1568  expressions::Wrapper<IntegerContext> >,
1569  expressions::PowerOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
1570  expressions::Wrapper<IntegerContext>(b))); }
1572 
1581  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1582  expressions::Wrapper<IntegerContext> >,
1585  expressions::Wrapper<IntegerContext> >,
1586  expressions::FloorDivOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
1587  expressions::Wrapper<IntegerContext>(b))); }
1594  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1595  expressions::Wrapper<IntegerContext> >,
1598  expressions::Wrapper<IntegerContext> >,
1599  expressions::CeilDivOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
1600  expressions::Wrapper<IntegerContext>(b))); }
1607  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1608  expressions::Wrapper<IntegerContext> >,
1611  expressions::Wrapper<IntegerContext> >,
1612  expressions::RoundDivOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a),
1613  expressions::Wrapper<IntegerContext>(b))); }
1615 
1624  inline expressions::Expression<IntegerContext, expressions::Wrapper<IntegerContext>,
1627  expressions::PowerCOp<signed long>::impl>(expressions::Wrapper<IntegerContext>(a), b); }
1629 
1630  template<class A2, template<typename, typename> class O2>
1631  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1632  expressions::Expression<IntegerContext, A2, O2> >,
1633  expressions::GCDOp> GCD(const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
1634  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1635  expressions::Expression<IntegerContext, A2, O2> >,
1636  expressions::GCDOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
1637  template<class A2, template<typename, typename> class O2>
1638  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1639  expressions::Expression<IntegerContext, A2, O2> >,
1640  expressions::LCMOp> LCM(const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
1641  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1642  expressions::Expression<IntegerContext, A2, O2> >,
1643  expressions::LCMOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
1644 
1645  template<class A2, template<typename, typename> class O2>
1646  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1647  expressions::Expression<IntegerContext, A2, O2> >,
1648  expressions::PowerOp> power(const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
1649  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1650  expressions::Expression<IntegerContext, A2, O2> >,
1651  expressions::PowerOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
1652  template<class A2, template<typename, typename> class O2>
1653  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1654  expressions::Expression<IntegerContext, A2, O2> >,
1655  expressions::FloorDivOp> floorDiv(const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
1656  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1657  expressions::Expression<IntegerContext, A2, O2> >,
1658  expressions::FloorDivOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
1659  template<class A2, template<typename, typename> class O2>
1660  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1661  expressions::Expression<IntegerContext, A2, O2> >,
1662  expressions::CeilDivOp> ceilDiv(const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
1663  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1664  expressions::Expression<IntegerContext, A2, O2> >,
1665  expressions::CeilDivOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
1666  template<class A2, template<typename, typename> class O2>
1667  inline expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1668  expressions::Expression<IntegerContext, A2, O2> >,
1669  expressions::RoundDivOp> roundDiv(const Integer & a, const expressions::Expression<IntegerContext, A2, O2> & b)
1670  { return expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>,
1671  expressions::Expression<IntegerContext, A2, O2> >,
1672  expressions::RoundDivOp>(std::make_pair(expressions::Wrapper<IntegerContext>(a), b)); }
1673 
1674  namespace implementation
1675  {
1676  template<class A, template<typename, typename> class O>
1677  inline expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A, O>,
1678  expressions::AbsOp> abs(const expressions::Expression<IntegerContext, A, O> & b)
1679  { return expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A, O>,
1680  expressions::AbsOp>(b); }
1681  template<class A, template<typename, typename> class O>
1682  inline expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A, O>,
1683  expressions::SquareOp> square(const expressions::Expression<IntegerContext, A, O> & b)
1684  { return expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A, O>,
1685  expressions::SquareOp>(b); }
1686  template<class A, template<typename, typename> class O>
1687  inline expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A, O>,
1688  expressions::SqrtCeilOp> sqrtCeil(const expressions::Expression<IntegerContext, A, O> & b)
1689  { return expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A, O>,
1690  expressions::SqrtCeilOp>(b); }
1691  template<class A, template<typename, typename> class O>
1692  inline expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A, O>,
1693  expressions::SqrtFloorOp> sqrtFloor(const expressions::Expression<IntegerContext, A, O> & b)
1694  { return expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A, O>,
1695  expressions::SqrtFloorOp>(b); }
1696  template<class A, template<typename, typename> class O, class A2, template<typename, typename> class O2>
1697  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1698  expressions::Expression<IntegerContext, A2, O2> >,
1699  expressions::GCDOp> GCD(const expressions::Expression<IntegerContext, A, O> & a,
1700  const expressions::Expression<IntegerContext, A2, O2> & b)
1701  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1702  expressions::Expression<IntegerContext, A2, O2> >,
1703  expressions::GCDOp>(std::make_pair(a, b)); }
1704  template<class A, template<typename, typename> class O>
1705  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1706  expressions::Wrapper<IntegerContext> >,
1707  expressions::GCDOp> GCD(const expressions::Expression<IntegerContext, A, O> & a, const arithmetic::Integer & b)
1708  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1709  expressions::Wrapper<IntegerContext> >,
1710  expressions::GCDOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
1711  template<class A, template<typename, typename> class O, class A2, template<typename, typename> class O2>
1712  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1713  expressions::Expression<IntegerContext, A2, O2> >,
1714  expressions::LCMOp> LCM(const expressions::Expression<IntegerContext, A, O> & a,
1715  const expressions::Expression<IntegerContext, A2, O2> & b)
1716  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1717  expressions::Expression<IntegerContext, A2, O2> >,
1718  expressions::LCMOp>(std::make_pair(a, b)); }
1719  template<class A, template<typename, typename> class O>
1720  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1721  expressions::Wrapper<IntegerContext> >,
1722  expressions::LCMOp> LCM(const expressions::Expression<IntegerContext, A, O> & a, const arithmetic::Integer & b)
1723  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1724  expressions::Wrapper<IntegerContext> >,
1725  expressions::LCMOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
1726  template<class A, template<typename, typename> class O, class A2, template<typename, typename> class O2>
1727  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1728  expressions::Expression<IntegerContext, A2, O2> >,
1729  expressions::PowerOp> power(const expressions::Expression<IntegerContext, A, O> & a,
1730  const expressions::Expression<IntegerContext, A2, O2> & b)
1731  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1732  expressions::Expression<IntegerContext, A2, O2> >,
1733  expressions::PowerOp>(std::make_pair(a, b)); }
1734  template<class A, template<typename, typename> class O>
1735  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1736  expressions::Wrapper<IntegerContext> >,
1737  expressions::PowerOp> power(const expressions::Expression<IntegerContext, A, O> & a, const arithmetic::Integer & b)
1738  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1739  expressions::Wrapper<IntegerContext> >,
1740  expressions::PowerOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
1741  template<class A, template<typename, typename> class O, class A2, template<typename, typename> class O2>
1742  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1743  expressions::Expression<IntegerContext, A2, O2> >,
1744  expressions::FloorDivOp> floorDiv(const expressions::Expression<IntegerContext, A, O> & a,
1745  const expressions::Expression<IntegerContext, A2, O2> & b)
1746  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1747  expressions::Expression<IntegerContext, A2, O2> >,
1748  expressions::FloorDivOp>(std::make_pair(a, b)); }
1749  template<class A, template<typename, typename> class O>
1750  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1751  expressions::Wrapper<IntegerContext> >,
1752  expressions::FloorDivOp> floorDiv(const expressions::Expression<IntegerContext, A, O> & a, const arithmetic::Integer & b)
1753  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1754  expressions::Wrapper<IntegerContext> >,
1755  expressions::FloorDivOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
1756  template<class A, template<typename, typename> class O, class A2, template<typename, typename> class O2>
1757  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1758  expressions::Expression<IntegerContext, A2, O2> >,
1759  expressions::CeilDivOp> ceilDiv(const expressions::Expression<IntegerContext, A, O> & a,
1760  const expressions::Expression<IntegerContext, A2, O2> & b)
1761  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1762  expressions::Expression<IntegerContext, A2, O2> >,
1763  expressions::CeilDivOp>(std::make_pair(a, b)); }
1764  template<class A, template<typename, typename> class O>
1765  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1766  expressions::Wrapper<IntegerContext> >,
1767  expressions::CeilDivOp> ceilDiv(const expressions::Expression<IntegerContext, A, O> & a, const arithmetic::Integer & b)
1768  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1769  expressions::Wrapper<IntegerContext> >,
1770  expressions::CeilDivOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
1771  template<class A, template<typename, typename> class O, class A2, template<typename, typename> class O2>
1772  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1773  expressions::Expression<IntegerContext, A2, O2> >,
1774  expressions::RoundDivOp> roundDiv(const expressions::Expression<IntegerContext, A, O> & a,
1775  const expressions::Expression<IntegerContext, A2, O2> & b)
1776  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1777  expressions::Expression<IntegerContext, A2, O2> >,
1778  expressions::RoundDivOp>(std::make_pair(a, b)); }
1779  template<class A, template<typename, typename> class O>
1780  inline expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1781  expressions::Wrapper<IntegerContext> >,
1782  expressions::RoundDivOp> roundDiv(const expressions::Expression<IntegerContext, A, O> & a, const arithmetic::Integer & b)
1783  { return expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, A, O>,
1784  expressions::Wrapper<IntegerContext> >,
1785  expressions::RoundDivOp>(std::make_pair(a, expressions::Wrapper<IntegerContext>(b))); }
1786  template<class A, template<typename, typename> class O>
1787  inline expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A, O>,
1788  expressions::PowerCOp<signed long>::impl> power(const expressions::Expression<IntegerContext, A, O> & a, signed long b)
1789  { return expressions::Expression<IntegerContext, expressions::Expression<IntegerContext, A, O>,
1790  expressions::PowerCOp<signed long>::impl>(a, b); }
1791  }
1792  }
1793 }
1794 
1795 #endif
Returns the sum of the operands.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::FloorDivOp > floorDiv(const Integer &a, const Integer &b)
Computes and returns .
void submul(Integer &r, const Integer &a, const Integer &b)
Multiplies a and b and subtracts the result from r.
Returns the rounded quotient of the two operands.
Returns the ceil of the quotient of the two operands.
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.
Returns the ceil of the square root of the operand.
Integer & operator%=(Integer &cur, const Integer &i)
Divides cur by the given integer i and stores the remainder in cur.
expressions::Expression< IntegerContext, expressions::Wrapper< IntegerContext >, expressions::NegOp > operator-(const Integer &a)
Negates the integer.
Returns the floor of the quotient of the two operands.
void shr(Integer &r, const Integer &a, long b)
Shifts a by b bits to the left and stores the result in r.
expressions::Expression< IntegerContext, expressions::Wrapper< IntegerContext >, expressions::SqrtFloorOp > sqrtFloor(const Integer &i)
Computes and returns the floor of the square root of i.
void do_assign(typename Context::Type &x, const Op &op, const Data &data)
Performs the assignment of the expression to x.
Integer & operator&=(Integer &cur, const Integer &i)
Computes the bitwise and of cur with i and stores the result in cur.
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...
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::LCMOp > LCM(const Integer &a, const Integer &b)
Computes and returns the non-negative Least Common Multiple of a and b.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::CeilDivOp > ceilDiv(const Integer &a, const Integer &b)
Computes and returns .
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 bitwise AND of the operands.
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.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::AndOp > operator&(const Integer &a, const Integer &b)
Computes the bitwise and of the two integers and returns the result.
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)
Computes the bitwise or of cur with i and stores the result in cur.
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.
void bor(Integer &r, const Integer &a, const Integer &b)
Computes the bitwise or of a and b and stores the result in r.
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.
expressions::Expression< IntegerContext, expressions::Wrapper< IntegerContext >, expressions::SqrtCeilOp > sqrtCeil(const Integer &i)
Computes and returns the ceil of the square root of i.
Returns the floor of the square root of the operand.
void bxor(Integer &r, const Integer &a, const Integer &b)
Computes the bitwise exclusive or of a and b and stores the result in r.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::OrOp > operator|(const Integer &a, const Integer &b)
Computes the bitwise or of the two integers and returns the result.
Returns the product of the operands.
Integer & operator^=(Integer &cur, const Integer &i)
Computes the bitwise exclusive or of cur with i and stores the result in cur.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::RoundDivOp > roundDiv(const Integer &a, const Integer &b)
Computes and returns .
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.
void band(Integer &r, const Integer &a, const Integer &b)
Computes the bitwise and of a and b 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...
void neg(Integer &r, const Integer &a)
Negates a and stores the result in r.
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.
Returns the GCD of the two operands.
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.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::XOROp > operator^(const Integer &a, const Integer &b)
Computes the bitwise exclusive or of the two integers and returns the result.
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 bitwise OR of the operands.
Returns the absolute value of the operand.
Returns the LCM of the two operands.
Returns the bitwise inversion of the operands.
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.
Returns the first operand divided by 2 to the power of the second operand.
expressions::Expression< IntegerContext, expressions::Wrapper< IntegerContext >, expressions::BitInvOp > operator~(const Integer &a)
Bitwise negates the integer.
bool operator!=(const Integer &a, const Integer &b)
Compares the current integer with the given one for inequality.
Returns the bitwise XOR (exclusive or) of the operands.
Wraps a variable to behave similarly to an Expression<> object.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::GCDOp > GCD(const Integer &a, const Integer &b)
Computes and returns the non-negative Greatest Common Divisor of a and b.
Returns the difference of the operands.
bool operator>=(const Integer &a, const Integer &b)
Compares the current integer with the given one.
Returns the first operand multiplied by 2 to the power of the second operand.
void sub(Integer &r, const Integer &a, const Integer &b)
Subtracts b from a and stores the result in r.