plll  1.0
arithmetic.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_HPP
24 #define PLLL_INCLUDE_GUARD__ARITHMETIC_HPP
25 
26 #include <plll/config.hpp>
27 #include <plll/helper.hpp>
28 #include <sstream>
29 #include <iomanip>
30 #include <cassert>
31 
43 namespace plll
44 {
51  namespace arithmetic
52  {
53  class Integer;
54  class IntegerContext;
55  class Real;
56  class RealContext;
57 
58  namespace op
59  {
60  struct addition { };
61  struct subtraction { };
62  struct multiplication { };
63  struct division { };
64  struct modulo { };
65  }
66 
67  namespace implementation
68  {
69  template<typename A, typename B, typename Op>
80  }
81 
82  template<typename A, typename B, typename Op>
94  {
95  enum
96  {
103  typename helper::remove_decorations<B>::Result, Op>::intermediate_expression
108  };
119  };
120 
121  namespace op
122  {
123  struct negation { };
124  }
125 
126  namespace implementation
127  {
128  template<typename A, typename Op>
139  }
140 
141  template<typename A, typename Op>
151  {
152  enum
153  {
163  };
171  };
172 
173  class StringContext;
174 
175  namespace traits
176  {
177  template<class Type>
184  struct type_traits;
185 
186  template<>
188  {
189  enum
190  {
191  is_number = true,
192  is_cputype = false,
193  is_realtype = false,
194  is_inttype = true,
195  is_string = false,
196  is_cpp_string = false,
197  is_c_string = false,
198  is_exact = true,
199  has_uniform_rng = true,
200  has_context = true,
201  is_native = false,
202  is_modulo = false,
203  has_infinity = false,
204  is_variable_precision = false,
205  has_squareroot = false,
206  has_full_power = false,
207  has_special_fns = false,
208  has_huge_exponent = false,
209  has_constants = false,
210  has_trigonometric = false
211  };
212 
213  typedef IntegerContext Context;
214  typedef Integer PromoteType;
215  typedef const Integer & ConstReferenceType;
216  };
217 
218  template<>
220  {
221  enum
222  {
223  is_number = true,
224  is_cputype = false,
225  is_realtype = true,
226  is_inttype = false,
227  is_string = false,
228  is_cpp_string = false,
229  is_c_string = false,
230  is_exact = false,
231  has_uniform_rng = true,
232  has_context = true,
233  is_native = false,
234  is_modulo = false,
235  is_variable_precision = true,
236  has_squareroot = true,
237  has_full_power = true,
238  has_special_fns = true,
239  has_huge_exponent = true,
240  has_constants = true,
241  has_trigonometric = true
242  };
243 
244  typedef IntegerContext Context;
245  typedef Real PromoteType;
246  typedef const Real & ConstReferenceType;
247  };
248 
249  template<>
250  struct type_traits<signed int>
251  {
252  enum
253  {
254  is_number = true,
255  is_cputype = true,
256  is_realtype = false,
257  is_inttype = true,
258  is_string = false,
259  is_cpp_string = false,
260  is_c_string = false,
261  is_exact = true,
262  has_uniform_rng = false,
263  has_context = false,
264  is_native = true,
265  is_modulo = true,
266  has_infinity = false,
267  is_variable_precision = false,
268  has_squareroot = false,
269  has_full_power = false,
270  has_special_fns = false,
271  has_huge_exponent = false,
272  has_constants = false,
273  has_trigonometric = false
274  };
275 
276  typedef signed long PromoteType;
277  typedef signed int ConstReferenceType;
278  };
279 
280  template<>
281  struct type_traits<unsigned int>
282  {
283  enum
284  {
285  is_number = true,
286  is_cputype = true,
287  is_realtype = false,
288  is_inttype = true,
289  is_string = false,
290  is_cpp_string = false,
291  is_c_string = false,
292  is_exact = true,
293  has_uniform_rng = false,
294  has_context = false,
295  is_native = true,
296  is_modulo = true,
297  has_infinity = false,
298  is_variable_precision = false,
299  has_squareroot = false,
300  has_full_power = false,
301  has_special_fns = false,
302  has_huge_exponent = false,
303  has_constants = false,
304  has_trigonometric = false
305  };
306 
307  typedef unsigned long PromoteType;
308  typedef unsigned int ConstReferenceType;
309  };
310 
311  template<>
312  struct type_traits<signed long>
313  {
314  enum
315  {
316  is_number = true,
317  is_cputype = true,
318  is_realtype = false,
319  is_inttype = true,
320  is_string = false,
321  is_cpp_string = false,
322  is_c_string = false,
323  is_exact = true,
324  has_uniform_rng = false,
325  has_context = false,
326  is_native = true,
327  is_modulo = true,
328  has_infinity = false,
329  is_variable_precision = false,
330  has_squareroot = false,
331  has_full_power = false,
332  has_special_fns = false,
333  has_huge_exponent = false,
334  has_constants = false,
335  has_trigonometric = false
336  };
337 
338  typedef signed long PromoteType;
339  typedef signed long ConstReferenceType;
340  };
341 
342  template<>
343  struct type_traits<unsigned long>
344  {
345  enum
346  {
347  is_number = true,
348  is_cputype = true,
349  is_realtype = false,
350  is_inttype = true,
351  is_string = false,
352  is_cpp_string = false,
353  is_c_string = false,
354  is_exact = true,
355  has_uniform_rng = false,
356  has_context = false,
357  is_native = true,
358  is_modulo = true,
359  has_infinity = false,
360  is_variable_precision = false,
361  has_squareroot = false,
362  has_full_power = false,
363  has_special_fns = false,
364  has_huge_exponent = false,
365  has_constants = false,
366  has_trigonometric = false
367  };
368 
369  typedef unsigned long PromoteType;
370  typedef unsigned long ConstReferenceType;
371  };
372 
373  template<>
374  struct type_traits<long long>
375  {
376  enum
377  {
378  is_number = true,
379  is_cputype = true,
380  is_realtype = false,
381  is_inttype = true,
382  is_string = false,
383  is_cpp_string = false,
384  is_c_string = false,
385  is_exact = true,
386  has_uniform_rng = false,
387  has_context = false,
388  is_native = true,
389  is_modulo = true,
390  has_infinity = false,
391  is_variable_precision = false,
392  has_squareroot = false,
393  has_full_power = false,
394  has_special_fns = false,
395  has_huge_exponent = false,
396  has_constants = false,
397  has_trigonometric = false
398  };
399 
400  typedef long long PromoteType;
401  typedef long long ConstReferenceType;
402  };
403 
404  template<>
405  struct type_traits<float>
406  {
407  enum
408  {
409  is_number = true,
410  is_cputype = true,
411  is_realtype = true,
412  is_inttype = false,
413  is_string = false,
414  is_cpp_string = false,
415  is_c_string = false,
416  is_exact = false,
417  has_uniform_rng = false,
418  has_context = false,
419  is_native = true,
420  is_modulo = false,
421  is_variable_precision = false,
422  has_squareroot = true,
423  has_full_power = true,
424  has_special_fns = false,
425  has_huge_exponent = false,
426  has_constants = false,
427  has_trigonometric = true
428  };
429 
430  typedef double PromoteType;
431  typedef float ConstReferenceType;
432  };
433 
434  template<>
435  struct type_traits<double>
436  {
437  enum
438  {
439  is_number = true,
440  is_cputype = true,
441  is_realtype = true,
442  is_inttype = false,
443  is_string = false,
444  is_cpp_string = false,
445  is_c_string = false,
446  is_exact = false,
447  has_uniform_rng = false,
448  has_context = false,
449  is_native = true,
450  is_modulo = false,
451  is_variable_precision = false,
452  has_squareroot = true,
453  has_full_power = true,
454  has_special_fns = false,
455  has_huge_exponent = false,
456  has_constants = false,
457  has_trigonometric = true
458  };
459 
460  typedef double PromoteType;
461  typedef double ConstReferenceType;
462  };
463 
464  template<>
465  struct type_traits<long double>
466  {
467  enum
468  {
469  is_number = true,
470  is_cputype = true,
471  is_realtype = true,
472  is_inttype = false,
473  is_string = false,
474  is_cpp_string = false,
475  is_c_string = false,
476  is_exact = false,
477  has_uniform_rng = false,
478  has_context = false,
479  is_native = true,
480  is_modulo = false,
481  is_variable_precision = false,
482  has_squareroot = true,
483  has_full_power = true,
484  has_special_fns = false,
485  has_huge_exponent = false,
486  has_constants = false,
487  has_trigonometric = true
488  };
489 
490  typedef long double PromoteType;
491  typedef long double ConstReferenceType;
492  };
493 
494  template<>
495  struct type_traits<std::string>
496  // TODO: what about unicode strings (wchar_t in C++98, and new character types in
497  // C++11)? ??? !!! ...
498  {
499  typedef StringContext Context;
500 
501  enum
502  {
503  is_number = false,
504  is_realtype = false,
505  is_inttype = false,
506  is_string = true,
507  is_cpp_string = true,
508  is_c_string = false,
509 
510  has_context = true
511  };
512  };
513 
514  template<>
515  struct type_traits<const char *>
516  {
517  enum
518  {
519  is_number = false,
520  is_realtype = false,
521  is_inttype = false,
522  is_string = true,
523  is_cpp_string = false,
524  is_c_string = true
525  };
526  };
527 
528  template<>
529  struct type_traits<char *>
530  {
531  enum
532  {
533  is_number = false,
534  is_realtype = false,
535  is_inttype = false,
536  is_string = true,
537  is_cpp_string = false,
538  is_c_string = true
539  };
540  };
541 
542  template<unsigned n>
543  struct type_traits<const char[n]>
544  {
545  enum
546  {
547  is_number = false,
548  is_realtype = false,
549  is_inttype = false,
550  is_string = true,
551  is_cpp_string = false,
552  is_c_string = true
553  };
554  };
555 
556  template<unsigned n>
557  struct type_traits<char[n]>
558  {
559  enum
560  {
561  is_number = false,
562  is_realtype = false,
563  is_inttype = false,
564  is_string = true,
565  is_cpp_string = false,
566  is_c_string = true
567  };
568  };
569  }
570 
571  using namespace traits;
572 
573  namespace implementation
574  {
575  #define PLLL_INTERNAL_DEFINE_OPERATION(A, B, R) template<typename Op> struct binary_operation_impl<A, B, Op> \
576  { enum { supported = true, intermediate_expression = false }; typedef R ResultType; typedef R IntermediateType; }
577  // signed int
578  PLLL_INTERNAL_DEFINE_OPERATION(signed int, signed int, signed int );
579  PLLL_INTERNAL_DEFINE_OPERATION(signed int, unsigned int, unsigned int );
580  PLLL_INTERNAL_DEFINE_OPERATION(signed int, signed long, signed long );
581  PLLL_INTERNAL_DEFINE_OPERATION(signed int, unsigned long, unsigned long);
582  PLLL_INTERNAL_DEFINE_OPERATION(signed int, long long, long long );
583  PLLL_INTERNAL_DEFINE_OPERATION(signed int, float, float );
584  PLLL_INTERNAL_DEFINE_OPERATION(signed int, double, double );
585  PLLL_INTERNAL_DEFINE_OPERATION(signed int, long double, long double );
586  // unsigned int
587  PLLL_INTERNAL_DEFINE_OPERATION(unsigned int, signed int, unsigned int );
588  PLLL_INTERNAL_DEFINE_OPERATION(unsigned int, unsigned int, unsigned int );
589  PLLL_INTERNAL_DEFINE_OPERATION(unsigned int, signed long, unsigned long);
590  PLLL_INTERNAL_DEFINE_OPERATION(unsigned int, unsigned long, unsigned long);
591  PLLL_INTERNAL_DEFINE_OPERATION(unsigned int, long long, long long );
592  PLLL_INTERNAL_DEFINE_OPERATION(unsigned int, float, float );
593  PLLL_INTERNAL_DEFINE_OPERATION(unsigned int, double, double );
594  PLLL_INTERNAL_DEFINE_OPERATION(unsigned int, long double, long double );
595  // signed long
596  PLLL_INTERNAL_DEFINE_OPERATION(signed long, signed int, signed long );
597  PLLL_INTERNAL_DEFINE_OPERATION(signed long, unsigned int, unsigned long);
598  PLLL_INTERNAL_DEFINE_OPERATION(signed long, signed long, signed long );
599  PLLL_INTERNAL_DEFINE_OPERATION(signed long, unsigned long, unsigned long);
600  PLLL_INTERNAL_DEFINE_OPERATION(signed long, long long, long long );
601  PLLL_INTERNAL_DEFINE_OPERATION(signed long, float, float );
602  PLLL_INTERNAL_DEFINE_OPERATION(signed long, double, double );
603  PLLL_INTERNAL_DEFINE_OPERATION(signed long, long double, long double );
604  // unsigned long
605  PLLL_INTERNAL_DEFINE_OPERATION(unsigned long, signed int, unsigned long);
606  PLLL_INTERNAL_DEFINE_OPERATION(unsigned long, unsigned int, unsigned long);
607  PLLL_INTERNAL_DEFINE_OPERATION(unsigned long, signed long, unsigned long);
608  PLLL_INTERNAL_DEFINE_OPERATION(unsigned long, unsigned long, unsigned long);
609  PLLL_INTERNAL_DEFINE_OPERATION(unsigned long, long long, long long );
610  PLLL_INTERNAL_DEFINE_OPERATION(unsigned long, float, float );
611  PLLL_INTERNAL_DEFINE_OPERATION(unsigned long, double, double );
612  PLLL_INTERNAL_DEFINE_OPERATION(unsigned long, long double, long double );
613  // long long
614  PLLL_INTERNAL_DEFINE_OPERATION(long long, signed int, long long );
615  PLLL_INTERNAL_DEFINE_OPERATION(long long, unsigned int, long long );
616  PLLL_INTERNAL_DEFINE_OPERATION(long long, signed long, long long );
617  PLLL_INTERNAL_DEFINE_OPERATION(long long, unsigned long, long long );
618  PLLL_INTERNAL_DEFINE_OPERATION(long long, long long, long long );
619  PLLL_INTERNAL_DEFINE_OPERATION(long long, float, float );
620  PLLL_INTERNAL_DEFINE_OPERATION(long long, double, double );
621  PLLL_INTERNAL_DEFINE_OPERATION(long long, long double, long double);
622  // float
623  PLLL_INTERNAL_DEFINE_OPERATION(float, signed int, float );
624  PLLL_INTERNAL_DEFINE_OPERATION(float, unsigned int, float );
625  PLLL_INTERNAL_DEFINE_OPERATION(float, signed long, float );
626  PLLL_INTERNAL_DEFINE_OPERATION(float, unsigned long, float );
627  PLLL_INTERNAL_DEFINE_OPERATION(float, long long, float );
628  PLLL_INTERNAL_DEFINE_OPERATION(float, float, float );
629  PLLL_INTERNAL_DEFINE_OPERATION(float, double, double );
630  PLLL_INTERNAL_DEFINE_OPERATION(float, long double, long double);
631  // double
632  PLLL_INTERNAL_DEFINE_OPERATION(double, signed int, double );
633  PLLL_INTERNAL_DEFINE_OPERATION(double, unsigned int, double );
634  PLLL_INTERNAL_DEFINE_OPERATION(double, signed long, double );
635  PLLL_INTERNAL_DEFINE_OPERATION(double, unsigned long, double );
636  PLLL_INTERNAL_DEFINE_OPERATION(double, long long, double );
637  PLLL_INTERNAL_DEFINE_OPERATION(double, float, double );
638  PLLL_INTERNAL_DEFINE_OPERATION(double, double, double );
639  PLLL_INTERNAL_DEFINE_OPERATION(double, long double, long double);
640  // long double
641  PLLL_INTERNAL_DEFINE_OPERATION(long double, signed int, long double);
642  PLLL_INTERNAL_DEFINE_OPERATION(long double, unsigned int, long double);
643  PLLL_INTERNAL_DEFINE_OPERATION(long double, signed long, long double);
644  PLLL_INTERNAL_DEFINE_OPERATION(long double, unsigned long, long double);
645  PLLL_INTERNAL_DEFINE_OPERATION(long double, long long, long double);
646  PLLL_INTERNAL_DEFINE_OPERATION(long double, float, long double);
647  PLLL_INTERNAL_DEFINE_OPERATION(long double, double, long double);
648  PLLL_INTERNAL_DEFINE_OPERATION(long double, long double, long double);
649  #undef PLLL_INTERNAL_DEFINE_OPERATION
650 
651  #define PLLL_INTERNAL_DEFINE_OPERATION(A, R) template<> struct unary_operation_impl<A, op::negation> \
652  { enum { supported = true, intermediate_expression = false }; typedef R ResultType; typedef R IntermediateType; }
653  PLLL_INTERNAL_DEFINE_OPERATION(signed int, signed int );
654  PLLL_INTERNAL_DEFINE_OPERATION(unsigned int, unsigned int );
655  PLLL_INTERNAL_DEFINE_OPERATION(signed long, signed long );
656  PLLL_INTERNAL_DEFINE_OPERATION(unsigned long, unsigned long);
657  PLLL_INTERNAL_DEFINE_OPERATION(long long, long long );
658  PLLL_INTERNAL_DEFINE_OPERATION(float, float );
659  PLLL_INTERNAL_DEFINE_OPERATION(double, double );
660  PLLL_INTERNAL_DEFINE_OPERATION(long double, long double );
661  #undef PLLL_INTERNAL_DEFINE_OPERATION
662 
663  template<class SourceType, class DestContext>
714  }
715 
720  template<class SourceType, class DestContext>
734  void convert(typename DestContext::Type & dst, const SourceType & src, const DestContext & context)
735  {
737  }
738 
739  template<class SourceType, class DestContext>
753  typename implementation::conversion_impl<SourceType, DestContext>::RetVal convert(const SourceType & src, const DestContext & context)
754  {
756  }
757 
758  template<class SourceType, class DestContext>
774  void convert_fraction(typename DestContext::Type & dst, const SourceType & src1, const SourceType & src2,
775  const DestContext & context)
776  {
777  PLLL_INTERNAL_STATIC_CHECK(DestContext::is_realtype, NeedsRealTypeDestination);
779  }
780 
781  template<class SourceType, class DestContext>
797  typename implementation::conversion_impl<SourceType, DestContext>::RetVal_Frac convert_fraction(const SourceType & src1, const SourceType & src2,
798  const DestContext & context)
799  {
800  PLLL_INTERNAL_STATIC_CHECK(DestContext::is_realtype, NeedsRealTypeDestination);
802  }
803 
804  template<class SourceType, class DestContext>
819  void convert_floor(typename DestContext::Type & dst, const SourceType & src, const DestContext & context)
820  {
822  PLLL_INTERNAL_STATIC_CHECK(DestContext::is_inttype, NeedsIntegerTypeDestination);
824  }
825 
826  template<class SourceType, class DestContext>
841  typename implementation::conversion_impl<SourceType, DestContext>::RetVal_Floor convert_floor(const SourceType & src, const DestContext & context)
842  {
844  PLLL_INTERNAL_STATIC_CHECK(DestContext::is_inttype, NeedsIntegerTypeDestination);
846  }
847 
848  template<class SourceType, class DestContext>
863  void convert_round(typename DestContext::Type & dst, const SourceType & src, const DestContext & context)
864  {
866  PLLL_INTERNAL_STATIC_CHECK(DestContext::is_inttype, NeedsIntegerTypeDestination);
868  }
869 
870  template<class SourceType, class DestContext>
885  typename implementation::conversion_impl<SourceType, DestContext>::RetVal_Round convert_round(const SourceType & src, const DestContext & context)
886  {
888  PLLL_INTERNAL_STATIC_CHECK(DestContext::is_inttype, NeedsIntegerTypeDestination);
890  }
891 
892  template<class SourceType, class DestContext>
909  void convert_round(typename DestContext::Type & dst, const SourceType & src, bool & up, const DestContext & context)
910  {
912  PLLL_INTERNAL_STATIC_CHECK(DestContext::is_inttype, NeedsIntegerTypeDestination);
914  }
915 
916  template<class SourceType, class DestContext>
933  typename implementation::conversion_impl<SourceType, DestContext>::RetVal_Round2 convert_round(const SourceType & src, bool & up, const DestContext & context)
934  {
936  PLLL_INTERNAL_STATIC_CHECK(DestContext::is_inttype, NeedsIntegerTypeDestination);
938  }
939 
940  template<class SourceType, class DestContext>
955  void convert_ceil(typename DestContext::Type & dst, const SourceType & src, const DestContext & context)
956  {
958  PLLL_INTERNAL_STATIC_CHECK(DestContext::is_inttype, NeedsIntegerTypeDestination);
960  }
961 
962  template<class SourceType, class DestContext>
977  typename implementation::conversion_impl<SourceType, DestContext>::RetVal_Ceil convert_ceil(const SourceType & src, const DestContext & context)
978  {
980  PLLL_INTERNAL_STATIC_CHECK(DestContext::is_inttype, NeedsIntegerTypeDestination);
982  }
983 
984  namespace implementation
985  {
986  template<class SourceType>
995 
996  template<class Native, class SourceType, bool NativeInt, bool SourceInt>
1016  }
1017 
1018  template<class Native, class SourceType>
1032  convert(const SourceType & src)
1033  {
1036  }
1037 
1038  template<class Native, class SourceType>
1039  typename implementation::nativeconversion_impl2<Native, SourceType, traits::type_traits<Native>::is_inttype || !traits::type_traits<Native>::is_number,
1040  traits::type_traits<SourceType>::is_inttype || !traits::type_traits<SourceType>::is_number>::RetVal_Floor
1052  convert_floor(const SourceType & src)
1053  {
1058  }
1059 
1060  template<class Native, class SourceType>
1072  typename implementation::nativeconversion_impl2<Native, SourceType, traits::type_traits<Native>::is_inttype || !traits::type_traits<Native>::is_number,
1073  traits::type_traits<SourceType>::is_inttype || !traits::type_traits<SourceType>::is_number>::RetVal_Round
1074  convert_round(const SourceType & src)
1075  {
1080  }
1081 
1082  template<class Native, class SourceType>
1096  typename implementation::nativeconversion_impl2<Native, SourceType, traits::type_traits<Native>::is_inttype || !traits::type_traits<Native>::is_number,
1097  traits::type_traits<SourceType>::is_inttype || !traits::type_traits<SourceType>::is_number>::RetVal_Round2
1098  convert_round(const SourceType & src, bool & up)
1099  {
1104  }
1105 
1106  template<class Native, class SourceType>
1107  typename implementation::nativeconversion_impl2<Native, SourceType, traits::type_traits<Native>::is_inttype || !traits::type_traits<Native>::is_number,
1108  traits::type_traits<SourceType>::is_inttype || !traits::type_traits<SourceType>::is_number>::RetVal_Ceil
1120  convert_ceil(const SourceType & src)
1121  {
1126  }
1127 
1129 
1139  {
1140  private:
1141  unsigned d_base;
1142 
1143  public:
1147  typedef std::string Type;
1148 
1152  enum { is_cputype = false, is_realtype = false, is_inttype = false };
1153 
1157  inline StringContext()
1158  : d_base(10)
1159  {
1160  }
1161 
1167  inline StringContext(unsigned base)
1168  : d_base(base)
1169  {
1170  assert(base >= 2);
1171  }
1172 
1178  inline unsigned base() const
1179  {
1180  return d_base;
1181  }
1182  };
1183 
1191  {
1192  public:
1193  inline HexStringContext()
1194  : StringContext(16)
1195  {
1196  }
1197  };
1198 
1206  {
1207  public:
1208  inline OctalStringContext()
1209  : StringContext(8)
1210  {
1211  }
1212  };
1213 
1214  namespace implementation
1215  {
1216  template<class SourceType, bool SourceInt>
1222  class nativeconversion_impl2<signed int, SourceType, true, SourceInt>
1223  {
1224  public:
1225  typedef signed int RetVal;
1228  typedef typename helper::SelectFirstType<SourceInt, void, signed int>::result RetVal_Round2;
1230 
1231  static RetVal convert(const SourceType & src)
1232  {
1234  }
1235 
1236  static RetVal_Floor convert_floor(const SourceType & src)
1237  {
1239  }
1240 
1241  static RetVal_Round convert_round(const SourceType & src)
1242  {
1244  }
1245 
1246  static RetVal_Round2 convert_round(const SourceType & src, bool & up)
1247  {
1249  }
1250 
1251  static RetVal_Ceil convert_ceil(const SourceType & src)
1252  {
1254  }
1255  };
1256 
1257  template<class SourceType, bool SourceInt>
1266  class nativeconversion_impl2<unsigned int, SourceType, true, SourceInt>
1267  {
1268  public:
1269  typedef unsigned int RetVal;
1274 
1275  static RetVal convert(const SourceType & src)
1276  {
1278  }
1279 
1280  static RetVal_Floor convert_floor(const SourceType & src)
1281  {
1283  }
1284 
1285  static RetVal_Round convert_round(const SourceType & src)
1286  {
1288  }
1289 
1290  static RetVal_Round2 convert_round(const SourceType & src, bool & up)
1291  {
1293  }
1294 
1295  static RetVal_Ceil convert_ceil(const SourceType & src)
1296  {
1298  }
1299  };
1300 
1301  template<class SourceType, bool SourceInt>
1310  class nativeconversion_impl2<signed long, SourceType, true, SourceInt>
1311  {
1312  public:
1313  typedef signed long RetVal;
1318 
1319  static RetVal convert(const SourceType & src)
1320  {
1322  }
1323 
1324  static RetVal_Floor convert_floor(const SourceType & src)
1325  {
1327  }
1328 
1329  static RetVal_Round convert_round(const SourceType & src)
1330  {
1332  }
1333 
1334  static RetVal_Round2 convert_round(const SourceType & src, bool & up)
1335  {
1337  }
1338 
1339  static RetVal_Ceil convert_ceil(const SourceType & src)
1340  {
1342  }
1343  };
1344 
1345  template<class SourceType, bool SourceInt>
1354  class nativeconversion_impl2<unsigned long, SourceType, true, SourceInt>
1355  {
1356  public:
1357  typedef unsigned long RetVal;
1362 
1363  static unsigned long convert(const SourceType & src)
1364  {
1366  }
1367 
1368  static RetVal_Floor convert_floor(const SourceType & src)
1369  {
1371  }
1372 
1373  static RetVal_Round convert_round(const SourceType & src)
1374  {
1376  }
1377 
1378  static RetVal_Round2 convert_round(const SourceType & src, bool & up)
1379  {
1381  }
1382 
1383  static RetVal_Ceil convert_ceil(const SourceType & src)
1384  {
1386  }
1387  };
1388 
1389  template<class SourceType, bool SourceInt>
1398  class nativeconversion_impl2<long long, SourceType, true, SourceInt>
1399  {
1400  public:
1401  typedef long long RetVal;
1404  typedef typename helper::SelectFirstType<SourceInt, void, long long>::result RetVal_Round2;
1406 
1407  static RetVal convert(const SourceType & src)
1408  {
1410  }
1411 
1412  static RetVal_Floor convert_floor(const SourceType & src)
1413  {
1415  }
1416 
1417  static RetVal_Round convert_round(const SourceType & src)
1418  {
1420  }
1421 
1422  static RetVal_Round2 convert_round(const SourceType & src, bool & up)
1423  {
1425  }
1426 
1427  static RetVal_Ceil convert_ceil(const SourceType & src)
1428  {
1430  }
1431  };
1432 
1433  template<class SourceType, bool SourceInt>
1442  class nativeconversion_impl2<float, SourceType, false, SourceInt>
1443  {
1444  public:
1445  typedef float RetVal;
1446  typedef void RetVal_Floor;
1447  typedef void RetVal_Ceil;
1448  typedef void RetVal_Round;
1449  typedef void RetVal_Round2;
1450 
1451  static RetVal convert(const SourceType & src)
1452  {
1454  }
1455  };
1456 
1457  template<class SourceType, bool SourceInt>
1463  class nativeconversion_impl2<double, SourceType, false, SourceInt>
1464  {
1465  public:
1466  typedef double RetVal;
1467  typedef void RetVal_Floor;
1468  typedef void RetVal_Ceil;
1469  typedef void RetVal_Round;
1470  typedef void RetVal_Round2;
1471 
1472  static RetVal convert(const SourceType & src)
1473  {
1475  }
1476  };
1477 
1478  template<class SourceType, bool SourceInt>
1484  class nativeconversion_impl2<long double, SourceType, false, SourceInt>
1485  {
1486  public:
1487  typedef long double RetVal;
1488  typedef void RetVal_Floor;
1489  typedef void RetVal_Ceil;
1490  typedef void RetVal_Round;
1491  typedef void RetVal_Round2;
1492 
1493  static RetVal convert(const SourceType & src)
1494  {
1496  }
1497  };
1498 
1499  template<class Context> class conversion_impl<typename Context::Type, Context>
1506  {
1507  public:
1508  typedef const typename Context::Type & RetVal;
1510  typedef void RetVal_Floor;
1511  typedef void RetVal_Ceil;
1512  typedef void RetVal_Round;
1513  typedef void RetVal_Round2;
1514 
1515  static void convert(typename Context::Type & d, const typename Context::Type & v, const Context & c)
1516  {
1517  d = v;
1518  }
1519 
1520  static RetVal convert(const typename Context::Type & v, const Context & c)
1521  {
1522  return v;
1523  }
1524 
1525  static void convert_frac(typename Context::Type & d, const typename Context::Type & v1, const typename Context::Type & v2, const Context & c)
1526  {
1527  d = v1 / v2;
1528  }
1529 
1530  static RetVal_Frac convert_frac(const typename Context::Type & v1, const typename Context::Type & v2, const Context & c)
1531  {
1532  return v1 / v2;
1533  }
1534  };
1535 
1536  template<class Context>
1562 
1563  template<class Type>
1584 
1585  template<class Context>
1591  {
1592  public:
1593  typedef typename Context::Type RetVal1;
1594  typedef typename Context::Type RetVal2;
1595 
1596  static bool convert(typename Context::Type & res, const std::string & s, const Context &)
1597  {
1598  std::istringstream ss(s);
1599  ss >> res;
1600  return ss;
1601  }
1602 
1603  static bool convert(typename Context::Type & res, const char * s, const Context & c)
1604  {
1605  std::istringstream ss(s);
1606  ss >> res;
1607  return ss;
1608  }
1609 
1610  static RetVal1 convert(const std::string & s, const Context & c)
1611  {
1612  RetVal1 res(c);
1613  convert(res, s, c);
1614  return res;
1615  }
1616 
1617  static RetVal2 convert(const char * s, const Context & c)
1618  {
1619  RetVal2 res(c);
1620  convert(res, s, c);
1621  return res;
1622  }
1623  };
1624 
1625  template<class Type>
1626  class to_string_conversion
1631  {
1632  public:
1633  typedef std::string RetVal;
1634 
1635  static RetVal convert(const Type & t)
1636  {
1637  std::ostringstream ss;
1638  ss << t;
1639  return ss.str();
1640  }
1641 
1642  static RetVal convert(const Type & t, unsigned base)
1643  {
1644  std::ostringstream ss;
1645  ss << std::setbase(base) << t;
1646  return ss.str();
1647  }
1648 
1649  static void convert(std::string & str, const Type & t)
1650  {
1651  std::ostringstream ss;
1652  ss << t;
1653  str = ss.str();
1654  }
1655 
1656  static void convert(std::string & str, const Type & t, unsigned base)
1657  {
1658  std::ostringstream ss;
1659  ss << std::setbase(base) << t;
1660  str = ss.str();
1661  }
1662  };
1663 
1664  template<class Type>
1671  {
1672  public:
1673  typedef typename to_string_conversion<Type>::RetVal RetVal;
1674  typedef void RetVal_Floor;
1675  typedef void RetVal_Ceil;
1676  typedef void RetVal_Round;
1677  typedef void RetVal_Round2;
1678 
1679  static inline void convert(std::string & str, const Type & v, const StringContext & c)
1680  {
1682  }
1683 
1684  static inline RetVal convert(const Type & v, const StringContext & c)
1685  {
1687  }
1688  };
1689 
1690  template<class Type>
1698  {
1699  public:
1700  typedef typename to_string_conversion<Type>::RetVal RetVal;
1701  typedef void RetVal_Floor;
1702  typedef void RetVal_Ceil;
1703  typedef void RetVal_Round;
1704  typedef void RetVal_Round2;
1705 
1706  static inline void convert(std::string & str, const Type & v, const HexStringContext & c)
1707  {
1709  }
1710 
1711  static inline RetVal convert(const Type & v, const HexStringContext & c)
1712  {
1714  }
1715  };
1716 
1717  template<class Type>
1725  {
1726  public:
1727  typedef typename to_string_conversion<Type>::RetVal RetVal;
1728  typedef void RetVal_Floor;
1729  typedef void RetVal_Ceil;
1730  typedef void RetVal_Round;
1731  typedef void RetVal_Round2;
1732 
1733  static inline void convert(std::string & str, const Type & v, const OctalStringContext & c)
1734  {
1736  }
1737 
1738  static inline RetVal convert(const Type & v, const OctalStringContext & c)
1739  {
1741  }
1742  };
1743 
1744  template<class Context>
1751  class conversion_impl<std::string, Context>
1752  {
1753  public:
1754  typedef typename from_string_conversion<Context>::RetVal1 RetVal;
1755  typedef void RetVal_Floor;
1756  typedef void RetVal_Ceil;
1757  typedef void RetVal_Round;
1758  typedef void RetVal_Round2;
1759 
1760  static void convert(typename Context::Type & d, const std::string & s, const Context & c)
1761  {
1763  }
1764 
1765  static RetVal convert(const std::string & s, const Context & c)
1766  {
1768  }
1769  };
1770 
1771  template<class Context>
1778  class conversion_impl<const char *, Context>
1779  {
1780  public:
1781  typedef typename from_string_conversion<Context>::RetVal2 RetVal;
1782  typedef void RetVal_Floor;
1783  typedef void RetVal_Ceil;
1784  typedef void RetVal_Round;
1785  typedef void RetVal_Round2;
1786 
1787  static inline void convert(typename Context::Type & d, const char * s, const Context & c)
1788  {
1790  }
1791 
1792  static inline RetVal convert(const char * s, const Context & c)
1793  {
1795  }
1796  };
1797 
1798  template<class Context>
1805  class conversion_impl<char *, Context>
1806  {
1807  public:
1808  typedef typename from_string_conversion<Context>::RetVal2 RetVal;
1809  typedef void RetVal_Floor;
1810  typedef void RetVal_Ceil;
1811  typedef void RetVal_Round;
1812  typedef void RetVal_Round2;
1813 
1814  static inline void convert(typename Context::Type & d, char * s, const Context & c)
1815  {
1816  from_string_conversion<Context>::convert(d, static_cast<const char *>(s), c);
1817  }
1818 
1819  static inline RetVal convert(char * s, const Context & c)
1820  {
1821  return from_string_conversion<Context>::convert(static_cast<const char *>(s), c);
1822  }
1823  };
1824 
1825  template<unsigned n, class Context>
1832  class conversion_impl<const char[n], Context>
1833  {
1834  public:
1835  typedef typename from_string_conversion<Context>::RetVal2 RetVal;
1836  typedef void RetVal_Floor;
1837  typedef void RetVal_Ceil;
1838  typedef void RetVal_Round;
1839  typedef void RetVal_Round2;
1840 
1841  static inline void convert(typename Context::Type & d, const char * s, const Context & c)
1842  {
1844  }
1845 
1846  static inline RetVal convert(const char * s, const Context & c)
1847  {
1849  }
1850  };
1851 
1852  template<unsigned n, class Context>
1859  class conversion_impl<char[n], Context>
1860  {
1861  public:
1862  typedef typename from_string_conversion<Context>::RetVal2 RetVal;
1863  typedef void RetVal_Floor;
1864  typedef void RetVal_Ceil;
1865  typedef void RetVal_Round;
1866  typedef void RetVal_Round2;
1867 
1868  static inline void convert(typename Context::Type & d, const char * s, const Context & c)
1869  {
1870  from_string_conversion<Context>::convert(d, static_cast<const char *>(s), c);
1871  }
1872 
1873  static inline RetVal convert(const char * s, const Context & c)
1874  {
1875  return from_string_conversion<Context>::convert(static_cast<const char *>(s), c);
1876  }
1877  };
1878 
1879  template<class SourceType, bool SourceInt>
1886  class nativeconversion_impl2<std::string, SourceType, true, SourceInt>
1887  {
1888  public:
1889  typedef typename to_string_conversion<SourceType>::RetVal RetVal;
1890  typedef void RetVal_Floor;
1891  typedef void RetVal_Round;
1892  typedef void RetVal_Round2;
1893  typedef void RetVal_Ceil;
1894 
1895  static inline RetVal convert(const SourceType & v)
1896  {
1898  }
1899  };
1900 
1901  template<> class nativeconversion_impl<std::string>
1908  {
1909  public:
1910  static int toInt(const std::string & v)
1911  {
1912  std::istringstream s(v);
1913  int res;
1914  s >> res;
1915  return res;
1916  }
1917 
1918  static unsigned int toUInt(const std::string & v)
1919  {
1920  std::istringstream s(v);
1921  unsigned int res;
1922  s >> res;
1923  return res;
1924  }
1925 
1926  static long toLong(const std::string & v)
1927  {
1928  std::istringstream s(v);
1929  long res;
1930  s >> res;
1931  return res;
1932  }
1933 
1934  static long toULong(const std::string & v)
1935  {
1936  std::istringstream s(v);
1937  unsigned long res;
1938  s >> res;
1939  return res;
1940  }
1941 
1942  static long long toLongLong(const std::string & v)
1943  {
1944  std::istringstream s(v);
1945  long long res;
1946  s >> res;
1947  return res;
1948  }
1949 
1950  static float toFloat(const std::string & v)
1951  {
1952  std::istringstream s(v);
1953  float res;
1954  s >> res;
1955  return res;
1956  }
1957 
1958  static double toDouble(const std::string & v)
1959  {
1960  std::istringstream s(v);
1961  double res;
1962  s >> res;
1963  return res;
1964  }
1965 
1966  static long double toLongDouble(const std::string & v)
1967  {
1968  std::istringstream s(v);
1969  long double res;
1970  s >> res;
1971  return res;
1972  }
1973  };
1974 
1975  template<> class nativeconversion_impl<const char *>
1982  {
1983  public:
1984  static int toInt(const char * v)
1985  {
1986  std::istringstream s(v);
1987  int res;
1988  s >> res;
1989  return res;
1990  }
1991 
1992  static unsigned int toUInt(const char * v)
1993  {
1994  std::istringstream s(v);
1995  unsigned int res;
1996  s >> res;
1997  return res;
1998  }
1999 
2000  static long toLong(const char * v)
2001  {
2002  std::istringstream s(v);
2003  long res;
2004  s >> res;
2005  return res;
2006  }
2007 
2008  static unsigned long toULong(const char * v)
2009  {
2010  std::istringstream s(v);
2011  unsigned long res;
2012  s >> res;
2013  return res;
2014  }
2015 
2016  static long long toLongLong(const char * v)
2017  {
2018  std::istringstream s(v);
2019  long long res;
2020  s >> res;
2021  return res;
2022  }
2023 
2024  static float toFloat(const char * v)
2025  {
2026  std::istringstream s(v);
2027  float res;
2028  s >> res;
2029  return res;
2030  }
2031 
2032  static double toDouble(const char * v)
2033  {
2034  std::istringstream s(v);
2035  double res;
2036  s >> res;
2037  return res;
2038  }
2039 
2040  static long double toLongDouble(const char * v)
2041  {
2042  std::istringstream s(v);
2043  long double res;
2044  s >> res;
2045  return res;
2046  }
2047  };
2048 
2049  template<> class nativeconversion_impl<char *>
2056  {
2057  public:
2058  static inline int toInt(char * v)
2059  {
2061  }
2062 
2063  static inline unsigned int toUInt(char * v)
2064  {
2066  }
2067 
2068  static inline long toLong(char * v)
2069  {
2071  }
2072 
2073  static inline unsigned long toULong(char * v)
2074  {
2076  }
2077 
2078  static inline long long toLongLong(char * v)
2079  {
2081  }
2082 
2083  static inline float toFloat(char * v)
2084  {
2086  }
2087 
2088  static inline double toDouble(char * v)
2089  {
2091  }
2092 
2093  static inline long double toLongDouble(char * v)
2094  {
2096  }
2097  };
2098 
2099  template<unsigned n> class nativeconversion_impl<char [n]>
2106  {
2107  public:
2108  static inline int toInt(const char * v)
2109  {
2111  }
2112 
2113  static inline unsigned int toUInt(const char * v)
2114  {
2116  }
2117 
2118  static inline long toLong(const char * v)
2119  {
2121  }
2122 
2123  static inline unsigned long toULong(const char * v)
2124  {
2126  }
2127 
2128  static inline long long toLongLong(const char * v)
2129  {
2131  }
2132 
2133  static inline float toFloat(const char * v)
2134  {
2136  }
2137 
2138  static inline double toDouble(const char * v)
2139  {
2141  }
2142 
2143  static inline long double toLongDouble(const char * v)
2144  {
2146  }
2147  };
2148 
2149  template<unsigned n> class nativeconversion_impl<const char [n]>
2156  {
2157  public:
2158  static inline int toInt(const char * v)
2159  {
2161  }
2162 
2163  static inline unsigned int toUInt(const char * v)
2164  {
2166  }
2167 
2168  static inline long toLong(const char * v)
2169  {
2171  }
2172 
2173  static inline unsigned long toULong(const char * v)
2174  {
2176  }
2177 
2178  static inline long long toLongLong(const char * v)
2179  {
2181  }
2182 
2183  static inline float toFloat(const char * v)
2184  {
2186  }
2187 
2188  static inline double toDouble(const char * v)
2189  {
2191  }
2192 
2193  static inline long double toLongDouble(const char * v)
2194  {
2196  }
2197  };
2198  }
2199  }
2200 }
2201 
2203 
2204 namespace plll
2205 {
2206  namespace arithmetic
2207  {
2208  namespace implementation
2209  {
2210  extern IntegerContext g_intcontext;
2211 
2212  template<class Source, bool SourceInt>
2213  class nativeconversion_impl2<Integer, Source, true, SourceInt>
2218  {
2219  public:
2220  typedef typename conversion_impl<Source, IntegerContext>::RetVal RetVal;
2225 
2226  static RetVal convert(const Source & v)
2227  {
2228  return conversion_impl<Source, IntegerContext>::convert(v, g_intcontext);
2229  }
2230 
2231  static RetVal_Floor convert_floor(const Source & v)
2232  {
2233  return conversion_impl<Source, IntegerContext>::floor(v, g_intcontext);
2234  }
2235 
2236  static RetVal_Round convert_round(const Source & v)
2237  {
2238  return conversion_impl<Source, IntegerContext>::round(v, g_intcontext);
2239  }
2240 
2241  static RetVal_Round2 convert_round(const Source & v, bool & up)
2242  {
2243  return conversion_impl<Source, IntegerContext>::round(v, up, g_intcontext);
2244  }
2245 
2246  static RetVal_Ceil convert_ceil(const Source & v)
2247  {
2248  return conversion_impl<Source, IntegerContext>::ceil(v, g_intcontext);
2249  }
2250  };
2251  }
2252  }
2253 }
2254 
2255 #include <plll/arithmetic-gmp.hpp>
2256 
2257 #endif
Provides information on the result of an unary arithmetic operation.
Definition: arithmetic.hpp:138
implementation::binary_operation_impl< typename helper::remove_decorations< A >::Result, typename helper::remove_decorations< B >::Result, Op >::ResultType ResultType
Definition: arithmetic.hpp:110
StringContext(unsigned base)
Creates a string context for an arbitrary base.
#define PLLL_INTERNAL_STATIC_CHECK(condition, IdentifierWhichIsAMessage)
Definition: helper.hpp:83
Provides information on the result of a binary arithmetic operation.
Definition: arithmetic.hpp:93
An "arithmetic" context for octal (base 8) conversions to std::strings.
An "arithmetic" context for conversions to std::strings.
implementation::nativeconversion_impl2< Native, SourceType, traits::type_traits< Native >::is_inttype||!traits::type_traits< Native >::is_number, traits::type_traits< SourceType >::is_inttype||!traits::type_traits< SourceType >::is_number >::RetVal convert(const SourceType &src)
Converts the value in src to the native type Native and returns the result.
Provides conversion implementation from type SourceType to DestContext::Type.
Definition: arithmetic.hpp:713
Provides information on the result of a binary arithmetic operation.
Definition: arithmetic.hpp:79
Provides information on the result of an unary arithmetic operation.
Definition: arithmetic.hpp:150
void convert(typename DestContext::Type &dst, const SourceType &src, const DestContext &context)
Converts the value in src to the type described by context and stores the result in dst...
Definition: arithmetic.hpp:734
Provides facilities to convert strings to types.
implementation::remove_decorations_impl< A >::result Result
The stripped type.
Definition: helper.hpp:289
implementation::unary_operation_impl< typename helper::remove_decorations< typename MTIn::CoeffType_Get >::Result, arithmetic::op::negation >::IntermediateType IntermediateType
Definition: arithmetic.hpp:166
implementation::select_first_type_impl< cond, A, B >::result result
The result type. Either A or B, depending on the value of cond.
Definition: helper.hpp:124
StringContext()
Creates a string context for base 10 (decimal).
implementation::binary_operation_impl< typename helper::remove_decorations< A >::Result, typename helper::remove_decorations< B >::Result, Op >::IntermediateType IntermediateType
Definition: arithmetic.hpp:114
Provides facilities to convert types to std::strings.
Implementation backend for conversions from context types to native types.
Definition: arithmetic.hpp:994
void convert_round(typename DestContext::Type &dst, const SourceType &src, const DestContext &context)
Converts the rounded value in src to the type described by context and stores the result in dst...
Definition: arithmetic.hpp:863
unsigned base() const
Queries the base of this context.
An "arithmetic" context for hexadecimal (base 16) conversions to std::strings.
Represents an arbitrary precision floating point value.
Header for arbitrary precision integer and floating point arithmetic, provided by GMP and MPFR...
void convert_fraction(typename DestContext::Type &dst, const SourceType &src1, const SourceType &src2, const DestContext &context)
Converts the values in src1 and scr2 to the type described by context and stores their quotient in ds...
Definition: arithmetic.hpp:774
Main header for arithmetic expressions.
Implementation backend for native conversion functions.
Helper templates.
implementation::unary_operation_impl< typename helper::remove_decorations< typename MTIn::CoeffType_Get >::Result, arithmetic::op::negation >::ResultType ResultType
Definition: arithmetic.hpp:164
A type selector template.
Definition: helper.hpp:120
void convert_floor(typename DestContext::Type &dst, const SourceType &src, const DestContext &context)
Converts the floor of the value in src to the type described by context and stores the result in dst...
Definition: arithmetic.hpp:819
void convert_ceil(typename DestContext::Type &dst, const SourceType &src, const DestContext &context)
Converts the ceil of the value in src to the type described by context and stores the result in dst...
Definition: arithmetic.hpp:955
std::string Type
The type.
Provides information on arithmetic (and string) types.
Definition: arithmetic.hpp:184
Represents an arbitrary precision integer.
Represents an arithmetic context for arbitrary precision integer.