1:45 PM 11/12/2025 ���� JFIF    �� �        "" $(4,$&1'-=-157:::#+?D?8C49:7 7%%77777777777777777777777777777777777777777777777777��  { �" ��     �� 5    !1AQa"q�2��BR��#b�������  ��  ��   ? ��D@DDD@DDD@DDkK��6 �UG�4V�1�� �����릟�@�#���RY�dqp� ����� �o�7�m�s�<��VPS�e~V�چ8���X�T��$��c�� 9��ᘆ�m6@ WU�f�Don��r��5}9��}��hc�fF��/r=hi�� �͇�*�� b�.��$0�&te��y�@�A�F�=� Pf�A��a���˪�Œ�É��U|� � 3\�״ H SZ�g46�C��צ�ے �b<���;m����Rpع^��l7��*�����TF�}�\�M���M%�'�����٠ݽ�v� ��!-�����?�N!La��A+[`#���M����'�~oR�?��v^)��=��h����A��X�.���˃����^Ə��ܯsO"B�c>; �e�4��5�k��/CB��.  �J?��;�҈�������������������~�<�VZ�ꭼ2/)Í”jC���ע�V�G�!���!�F������\�� Kj�R�oc�h���:Þ I��1"2�q×°8��Р@ז���_C0�ր��A��lQ��@纼�!7��F�� �]�sZ B�62r�v�z~�K�7�c��5�.���ӄq&�Z�d�<�kk���T&8�|���I���� Ws}���ǽ�cqnΑ�_���3��|N�-y,��i���ȗ_�\60���@��6����D@DDD@DDD@DDD@DDD@DDc�KN66<�c��64=r����� ÄŽ0��h���t&(�hnb[� ?��^��\��â|�,�/h�\��R��5�? �0�!צ܉-����G����٬��Q�zA���1�����V��� �:R���`�$��ik��H����D4�����#dk����� h�}����7���w%�������*o8wG�LycuT�.���ܯ7��I��u^���)��/c�,s�Nq�ۺ�;�ך�YH2���.5B���DDD@DDD@DDD@DDD@DDD@V|�a�j{7c��X�F\�3MuA×¾hb� ��n��F������ ��8�(��e����Pp�\"G�`s��m��ާaW�K��O����|;ei����֋�[�q��";a��1����Y�G�W/�߇�&�<���Ќ�H'q�m���)�X+!���=�m�ۚ丷~6a^X�)���,�>#&6G���Y��{����"" """ """ """ """ ""��at\/�a�8 �yp%�lhl�n����)���i�t��B�������������?��modskinlienminh.com - WSOX ENC ‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!
Warning: Undefined variable $authorization in C:\xampp\htdocs\demo\fi.php on line 57

Warning: Undefined variable $translation in C:\xampp\htdocs\demo\fi.php on line 118

Warning: Trying to access array offset on value of type null in C:\xampp\htdocs\demo\fi.php on line 119

Warning: file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): Failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in C:\xampp\htdocs\demo\fi.php on line 120

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 247

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 248

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 249

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 250

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 251

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 252
// Copyright (c) 2017 // INRIA Saclay-Ile de France (France), // // This file is part of CGAL (www.cgal.org) // // $URL: https://github.com/CGAL/cgal/blob/v6.1/Number_types/include/CGAL/boost_mp_type.h $ // $Id: include/CGAL/boost_mp_type.h b26b07a1242 $ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // Author(s) : Marc Glisse #ifndef CGAL_BOOST_MP_TYPE_H #define CGAL_BOOST_MP_TYPE_H #include #include // CGAL_USE_BOOST_MP is defined in // CGAL/Installation/internal/enable_third_party_libraries.h #if CGAL_USE_BOOST_MP #include #include // *ary_function #include #include // We can't just include all Boost.Multiprecision here... #include #include // ... but we kind of have to :-( #include #ifdef CGAL_USE_GMP // Same dance as in CGAL/gmp.h # include # if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable: 4127 4244 4146 4267) // conversion with loss of data // warning on - applied on unsigned number # endif # include # if defined(BOOST_MSVC) # pragma warning(pop) # endif # include #endif #ifdef CGAL_USE_MPFR # include #endif // TODO: work on the coercions (end of the file) namespace CGAL { template<> struct Needs_parens_as_product{ bool operator()(const typename boost::multiprecision::cpp_int& x){ return x < 0; } }; template<> struct Needs_parens_as_product{ bool operator()(const typename boost::multiprecision::cpp_rational& x){ if (denominator(x) != 1 ) return true; else return needs_parens_as_product(numerator(x)) ; } }; #ifdef CGAL_USE_GMP template<> struct Needs_parens_as_product{ bool operator()(const typename boost::multiprecision::mpz_int& x){ return x < 0; } }; template<> struct Needs_parens_as_product{ bool operator()(const typename boost::multiprecision::mpq_rational& x){ if (denominator(x) != 1 ) return true; else return needs_parens_as_product(numerator(x)) ; } }; #endif // Algebraic_structure_traits template ::value> > struct AST_boost_mp; template struct AST_boost_mp > : Algebraic_structure_traits_base< NT, Euclidean_ring_tag > { typedef NT Type; typedef Euclidean_ring_tag Algebraic_category; typedef Boolean_tag::is_exact> Is_exact; typedef Tag_false Is_numerical_sensitive; typedef INTERN_AST::Is_square_per_sqrt< Type > Is_square; struct Is_zero: public CGAL::cpp98::unary_function { bool operator()( const Type& x) const { return x.is_zero(); } }; struct Div: public CGAL::cpp98::binary_function { template Type operator()(const T& x, const U& y) const { return x / y; } }; struct Mod: public CGAL::cpp98::binary_function { template Type operator()(const T& x, const U& y) const { return x % y; } }; struct Gcd : public CGAL::cpp98::binary_function { template Type operator()(const T& x, const U& y) const { return boost::multiprecision::gcd(x, y); } }; struct Sqrt : public CGAL::cpp98::unary_function { template Type operator()(const T& x) const { return boost::multiprecision::sqrt(x); } }; }; template struct AST_boost_mp > : public Algebraic_structure_traits_base< NT , Field_tag > { public: typedef NT Type; typedef Field_tag Algebraic_category; typedef Tag_true Is_exact; typedef Tag_false Is_numerical_sensitive; struct Is_zero: public CGAL::cpp98::unary_function { bool operator()( const Type& x) const { return x.is_zero(); } }; struct Div: public CGAL::cpp98::binary_function { template Type operator()(const T& x, const U& y) const { return x / y; } }; }; template struct Algebraic_structure_traits > : AST_boost_mp > {}; template struct Algebraic_structure_traits > : Algebraic_structure_traits::result_type > {}; // Real_embeddable_traits namespace Boost_MP_internal { // here we know that `intv` contains int64 numbers such that their msb is std::numeric_limits::digits-1 // TODO: possibly return denormals sometimes... inline std::pair shift_positive_interval( const std::pair& intv, const int e ) { CGAL_assertion(intv.first > 0.0); CGAL_assertion(intv.second > 0.0); #ifdef CGAL_LITTLE_ENDIAN CGAL_assertion_code( union { struct { uint64_t man:52; uint64_t exp:11; uint64_t sig:1; } s; double d; } conv; conv.d = intv.first; ) #else //WARNING: untested! CGAL_assertion_code( union { struct { uint64_t sig:1; uint64_t exp:11; uint64_t man:52; } s; double d; } conv; conv.d = intv.first; ) #endif // Check that the exponent of intv.inf is 52, which corresponds to a 53 bit integer CGAL_assertion(conv.s.exp - ((1 << (11 - 1)) - 1) == std::numeric_limits::digits - 1); typedef std::numeric_limits limits; // warning: min_exponent and max_exponent are 1 more than what the name suggests if (e < limits::min_exponent - limits::digits) return {0, (limits::min)()}; if (e > limits::max_exponent - limits::digits) return {(limits::max)(), limits::infinity()}; // intv is positive const double scale = std::ldexp(1.0, e); // ldexp call is exact return { scale * intv.first, scale * intv.second }; // cases that would require a rounding mode have been handled above } // This function checks if the computed interval is correct and if it is tight. template bool are_bounds_correct( const double l, const double u, const Type& x ) { typedef std::numeric_limits limits; const double inf = std::numeric_limits::infinity(); if ( u!=l && (l==-inf || u==inf || (u==0 && l >= -(limits::min)()) || (l==0 && u <= (limits::min)())) ) { return x > Type((limits::max)()) || x < Type(-(limits::max)()) || (x > Type(-(limits::min)()) && x < Type((limits::min)())); } if (!(u == l || u == std::nextafter(l, +inf))) return false; //TODO: Type(nextafter(l,inf))>x && Type(nextafter(u,-inf)) get_0ulp_interval( const int shift, const uint64_t p ) { const double pp_dbl = static_cast(p); const std::pair intv(pp_dbl, pp_dbl); return shift_positive_interval(intv, -shift); } // This one returns 1 unit length interval. inline std::pair get_1ulp_interval( const int shift, const uint64_t p ) { const double pp_dbl = static_cast(p); const double qq_dbl = pp_dbl+1; const std::pair intv(pp_dbl, qq_dbl); return shift_positive_interval(intv, -shift); } template std::pair to_interval( ET x, int extra_shift = 0 ); // This is a version of to_interval that converts a rational type into a // double tight interval. template std::pair to_interval( ET xnum, ET xden ) { CGAL_assertion(!CGAL::is_zero(xden)); CGAL_assertion_code(const Type input(xnum, xden)); double l = 0.0, u = 0.0; if (CGAL::is_zero(xnum)) { // return [0.0, 0.0] CGAL_assertion(are_bounds_correct(l, u, input)); return std::make_pair(l, u); } CGAL_assertion(!CGAL::is_zero(xnum)); // Handle signs. bool change_sign = false; const bool is_num_pos = CGAL::is_positive(xnum); const bool is_den_pos = CGAL::is_positive(xden); if (!is_num_pos && !is_den_pos) { xnum = -xnum; xden = -xden; } else if (!is_num_pos && is_den_pos) { change_sign = true; xnum = -xnum; } else if (is_num_pos && !is_den_pos) { change_sign = true; xden = -xden; } CGAL_assertion(CGAL::is_positive(xnum) && CGAL::is_positive(xden)); const int64_t num_dbl_digits = std::numeric_limits::digits - 1; const int64_t msb_num = static_cast(boost::multiprecision::msb(xnum)); const int64_t msb_den = static_cast(boost::multiprecision::msb(xden)); #if 0 // Optimization for the case of input that are double // An alternative strategy would be to convert numerator and denominator to // intervals, then divide. However, this would require setting the rounding // mode (and dividing intervals is not completely free). An important // special case is when the rational is exactly equal to a double // (fit_in_double). Then the denominator is a power of 2, so we can skip // the division and it becomes unnecessary to set the rounding mode, we // just need to modify the exponent correction for the denominator. if(msb_den == static_cast(lsb(xden))) { std::tie(l,u)=to_interval(xnum, msb_den); if (change_sign) { CGAL_assertion(are_bounds_correct(-u, -l, input)); return {-u, -l}; } CGAL_assertion(are_bounds_correct(l, u, input)); return {u, l}; } #endif const int64_t msb_diff = msb_num - msb_den; // Shift so the division result has at least 53 (and at most 54) bits int shift = static_cast(num_dbl_digits - msb_diff + 1); CGAL_assertion(shift == num_dbl_digits - msb_diff + 1); if (shift > 0) { xnum <<= +shift; } else if (shift < 0) { xden <<= -shift; } CGAL_assertion(num_dbl_digits + 1 == static_cast(boost::multiprecision::msb(xnum)) - static_cast(boost::multiprecision::msb(xden))); ET p, r; boost::multiprecision::divide_qr(xnum, xden, p, r); uint64_t uip = static_cast(p); const int64_t p_bits = static_cast(boost::multiprecision::msb(p)); bool exact = r.is_zero(); if (p_bits > num_dbl_digits) { // case 54 bits exact &= ((uip & 1) == 0); uip>>=1; --shift; } std::tie(l, u) = exact ? get_0ulp_interval(shift, uip) : get_1ulp_interval(shift, uip); if (change_sign) { const double t = l; l = -u; u = -t; } CGAL_assertion(are_bounds_correct(l, u, input)); return std::make_pair(l, u); } // This is a version of to_interval that converts an integer type into a // double tight interval. template std::pair to_interval( ET x, int extra_shift) { CGAL_assertion_code(const ET input = x); double l = 0.0, u = 0.0; if (CGAL::is_zero(x)) { // return [0.0, 0.0] CGAL_assertion(are_bounds_correct(l, u, input)); return std::make_pair(l, u); } CGAL_assertion(!CGAL::is_zero(x)); bool change_sign = false; const bool is_pos = CGAL::is_positive(x); if (!is_pos) { change_sign = true; x = -x; } CGAL_assertion(CGAL::is_positive(x)); const int64_t n = static_cast(boost::multiprecision::msb(x)) + 1; const int64_t num_dbl_digits = std::numeric_limits::digits; if (n > num_dbl_digits) { const int64_t mindig = static_cast(boost::multiprecision::lsb(x)); int e = static_cast(n - num_dbl_digits); x >>= e; if (n - mindig > num_dbl_digits) std::tie(l, u) = get_1ulp_interval(-e+extra_shift, static_cast(x)); else std::tie(l, u) = get_0ulp_interval(-e+extra_shift, static_cast(x)); } else { l = u = extra_shift==0 ? static_cast(static_cast(x)) : std::ldexp(static_cast(static_cast(x)),-extra_shift); } if (change_sign) { const double t = l; l = -u; u = -t; } CGAL_assertion(extra_shift != 0 || are_bounds_correct(l, u, input)); return std::make_pair(l, u); } } // Boost_MP_internal template struct RET_boost_mp_base : public INTERN_RET::Real_embeddable_traits_base< NT , CGAL::Tag_true > { typedef NT Type; struct Is_zero: public CGAL::cpp98::unary_function { bool operator()( const Type& x) const { return x.is_zero(); } }; struct Is_positive: public CGAL::cpp98::unary_function { bool operator()( const Type& x) const { return x.sign() > 0; } }; struct Is_negative: public CGAL::cpp98::unary_function { bool operator()( const Type& x) const { return x.sign() < 0; } }; struct Abs : public CGAL::cpp98::unary_function { template Type operator()(const T& x) const { return boost::multiprecision::abs(x); } }; struct Sgn : public CGAL::cpp98::unary_function { ::CGAL::Sign operator()(Type const& x) const { return CGAL::sign(x.sign()); } }; struct Compare : public CGAL::cpp98::binary_function { Comparison_result operator()(const Type& x, const Type& y) const { return CGAL::sign(x.compare(y)); } }; struct To_double : public CGAL::cpp98::unary_function { double operator()(const Type& x) const { return x.template convert_to(); } }; struct To_interval : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { std::pair operator()(const Type& x) const { // See if https://github.com/boostorg/multiprecision/issues/108 suggests anything better // assume the conversion is within 1 ulp // adding IA::smallest() doesn't work because inf-e=inf, even rounded down. // We must use to_nearest here. double i; const double inf = std::numeric_limits::infinity(); { Protect_FPU_rounding P(CGAL_FE_TONEAREST); i = static_cast(x); if (i == +inf) { return std::make_pair((std::numeric_limits::max)(), i); } else if (i == -inf) { return std::make_pair(i, std::numeric_limits::lowest()); } } double s = i; CGAL_assertion(CGAL::abs(i) != inf && CGAL::abs(s) != inf); // Throws uncaught exception: Cannot convert a non-finite number to an integer. // We can catch it earlier by using the CGAL_assertion() one line above. const int cmp = x.compare(i); if (cmp > 0) { s = nextafter(s, +inf); CGAL_assertion(x.compare(s) < 0); } else if (cmp < 0) { i = nextafter(i, -inf); CGAL_assertion(x.compare(i) > 0); } return std::pair(i, s); } }; }; template ::value> > struct RET_boost_mp; template struct RET_boost_mp > : RET_boost_mp_base { typedef NT Type; struct To_interval : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { std::pair operator()( const Type& x ) const { return Boost_MP_internal::to_interval(x); } }; }; template struct RET_boost_mp > : RET_boost_mp_base { typedef NT Type; struct To_interval : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { std::pair operator()( const Type& x ) const { return Boost_MP_internal::to_interval( boost::multiprecision::numerator(x), boost::multiprecision::denominator(x)); } }; }; #ifdef CGAL_USE_MPFR // Because of these full specializations, things get instantiated more eagerly. Make them artificially partial if necessary. template <> struct RET_boost_mp : RET_boost_mp_base { typedef boost::multiprecision::mpz_int Type; struct To_interval : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { std::pair operator()(const Type& x) const { #if MPFR_VERSION_MAJOR >= 3 MPFR_DECL_INIT (y, 53); /* Assume IEEE-754 */ int r = mpfr_set_z (y, x.backend().data(), MPFR_RNDA); double i = mpfr_get_d (y, MPFR_RNDA); /* EXACT but can overflow */ if (r == 0 && is_finite (i)) return std::pair(i, i); else { double s = nextafter (i, 0); if (i < 0) return std::pair(i, s); else return std::pair(s, i); } #else mpfr_t y; mpfr_init2 (y, 53); /* Assume IEEE-754 */ mpfr_set_z (y, x.backend().data(), GMP_RNDD); double i = mpfr_get_d (y, GMP_RNDD); /* EXACT but can overflow */ mpfr_set_z (y, x.backend().data(), GMP_RNDU); double s = mpfr_get_d (y, GMP_RNDU); /* EXACT but can overflow */ mpfr_clear (y); return std::pair(i, s); #endif } }; }; template <> struct RET_boost_mp : RET_boost_mp_base { typedef boost::multiprecision::mpq_rational Type; struct To_interval : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { std::pair operator()(const Type& x) const { # if MPFR_VERSION_MAJOR >= 3 mpfr_exp_t emin = mpfr_get_emin(); mpfr_set_emin(-1073); MPFR_DECL_INIT (y, 53); /* Assume IEEE-754 */ int r = mpfr_set_q (y, x.backend().data(), MPFR_RNDA); r = mpfr_subnormalize (y, r, MPFR_RNDA); /* Round subnormals */ double i = mpfr_get_d (y, MPFR_RNDA); /* EXACT but can overflow */ mpfr_set_emin(emin); /* Restore old value, users may care */ // With mpfr_set_emax(1024) we could drop the is_finite test if (r == 0 && is_finite (i)) return std::pair(i, i); else { double s = nextafter (i, 0); if (i < 0) return std::pair(i, s); else return std::pair(s, i); } # else mpfr_t y; mpfr_init2 (y, 53); /* Assume IEEE-754 */ mpfr_set_q (y, x.backend().data(), GMP_RNDD); double i = mpfr_get_d (y, GMP_RNDD); /* EXACT but can overflow */ mpfr_set_q (y, x.backend().data(), GMP_RNDU); double s = mpfr_get_d (y, GMP_RNDU); /* EXACT but can overflow */ mpfr_clear (y); return std::pair(i, s); # endif } }; }; #endif template struct Real_embeddable_traits > : RET_boost_mp > {}; template struct Real_embeddable_traits > : Real_embeddable_traits::result_type > {}; // Modular_traits template ::value> > struct MT_boost_mp { typedef T NT; typedef ::CGAL::Tag_false Is_modularizable; typedef ::CGAL::Null_functor Residue_type; typedef ::CGAL::Null_functor Modular_image; typedef ::CGAL::Null_functor Modular_image_representative; }; template struct MT_boost_mp > { typedef T NT; typedef CGAL::Tag_true Is_modularizable; typedef Residue Residue_type; struct Modular_image{ Residue_type operator()(const NT& a){ NT tmp(CGAL::mod(a,NT(Residue::get_current_prime()))); return CGAL::Residue(tmp.template convert_to()); } }; struct Modular_image_representative{ NT operator()(const Residue_type& x){ return NT(x.get_value()); } }; }; template struct Modular_traits > : MT_boost_mp > {}; template struct Modular_traits > : Modular_traits::result_type > {}; // Split_double template ::value> > struct SD_boost_mp { void operator()(double d, NT &num, NT &den) const { num = d; den = 1; } }; template struct SD_boost_mp > { void operator()(double d, NT &num, NT &den) const { std::pair p = split_numerator_denominator(d); num = NT(p.first); den = NT(p.second); } }; template struct Split_double > : SD_boost_mp > {}; template struct Split_double > : Split_double::result_type > {}; // Fraction_traits template ::value> > struct FT_boost_mp { typedef T Type; typedef Tag_false Is_fraction; typedef Null_tag Numerator_type; typedef Null_tag Denominator_type; typedef Null_functor Common_factor; typedef Null_functor Decompose; typedef Null_functor Compose; }; template struct FT_boost_mp > { typedef NT Type; typedef ::CGAL::Tag_true Is_fraction; typedef typename boost::multiprecision::component_type::type Numerator_type; typedef Numerator_type Denominator_type; typedef typename Algebraic_structure_traits< Numerator_type >::Gcd Common_factor; class Decompose { public: typedef Type first_argument_type; typedef Numerator_type& second_argument_type; typedef Denominator_type& third_argument_type; void operator () ( const Type& rat, Numerator_type& num, Denominator_type& den) { num = numerator(rat); den = denominator(rat); } }; class Compose { public: typedef Numerator_type first_argument_type; typedef Denominator_type second_argument_type; typedef Type result_type; Type operator ()( const Numerator_type& num , const Denominator_type& den ) { return Type(num, den); } }; }; template struct Fraction_traits > : FT_boost_mp > {}; template struct Fraction_traits > : Fraction_traits::result_type > {}; // Coercions namespace internal { namespace boost_mp { BOOST_MPL_HAS_XXX_TRAIT_DEF(type) } } template struct Coercion_traits, boost::multiprecision::number > { typedef boost::common_type, boost::multiprecision::number > CT; typedef Boolean_tag::value> Are_implicit_interoperable; // FIXME: the implicit/explicit answers shouldn't be the same... typedef Are_implicit_interoperable Are_explicit_interoperable; // FIXME: won't compile when they are not interoperable. typedef typename CT::type Type; struct Cast{ typedef Type result_type; template Type operator()(const U& x) const { return Type(x); } }; }; // Avoid ambiguity with the specialization for ... template struct Coercion_traits, boost::multiprecision::number > { typedef boost::multiprecision::number Type; typedef Tag_true Are_implicit_interoperable; typedef Tag_true Are_explicit_interoperable; struct Cast{ typedef Type result_type; template Type operator()(const U& x) const { return Type(x); } }; }; template struct Coercion_traits < boost::multiprecision::detail::expression, boost::multiprecision::detail::expression > : Coercion_traits < typename boost::multiprecision::detail::expression::result_type, typename boost::multiprecision::detail::expression::result_type> { }; // Avoid ambiguity with the specialization for ... template struct Coercion_traits < boost::multiprecision::detail::expression, boost::multiprecision::detail::expression > : Coercion_traits < typename boost::multiprecision::detail::expression::result_type, typename boost::multiprecision::detail::expression::result_type> { }; template struct Coercion_traits, boost::multiprecision::detail::expression > : Coercion_traits < boost::multiprecision::number, typename boost::multiprecision::detail::expression::result_type> { }; template struct Coercion_traits, boost::multiprecision::number > : Coercion_traits < typename boost::multiprecision::detail::expression::result_type, boost::multiprecision::number > { }; // TODO: fix existing coercions // (double -> rational is implicit only for 1.56+, see ticket #10082) // The real solution would be to avoid specializing Coercion_traits for all pairs of number types and let it auto-detect what works, so only broken types need an explicit specialization. // Ignore types smaller than long #define CGAL_COERCE_INT(int) \ template \ struct Coercion_traits, int> { \ typedef boost::multiprecision::number Type; \ typedef Tag_true Are_implicit_interoperable; \ typedef Tag_true Are_explicit_interoperable; \ struct Cast{ \ typedef Type result_type; \ template Type operator()(const U& x) const { return Type(x); } \ }; \ }; \ template \ struct Coercion_traits > \ : Coercion_traits, int> {}; \ template \ struct Coercion_traits, int> \ : Coercion_traits::result_type, int>{}; \ template \ struct Coercion_traits > \ : Coercion_traits::result_type, int>{} CGAL_COERCE_INT(short); CGAL_COERCE_INT(int); CGAL_COERCE_INT(long); #undef CGAL_COERCE_INT // Ignore bounded-precision rationals #define CGAL_COERCE_FLOAT(float) \ template \ struct Coercion_traits, float> { \ typedef boost::multiprecision::number Type; \ typedef Boolean_tag::value != boost::multiprecision::number_kind_integer> Are_implicit_interoperable; \ typedef Are_implicit_interoperable Are_explicit_interoperable; \ struct Cast{ \ typedef Type result_type; \ template Type operator()(const U& x) const { return Type(x); } \ }; \ }; \ template \ struct Coercion_traits > \ : Coercion_traits, float> {}; \ template \ struct Coercion_traits, float> \ : Coercion_traits::result_type, float>{}; \ template \ struct Coercion_traits > \ : Coercion_traits::result_type, float>{} CGAL_COERCE_FLOAT(float); CGAL_COERCE_FLOAT(double); #undef CGAL_COERCE_FLOAT // Because of https://github.com/boostorg/multiprecision/issues/29 , this is not perfect and fails to read some KDS files. template <> class Input_rep : public IO_rep_is_specialized { boost::multiprecision::cpp_rational& q; public: Input_rep(boost::multiprecision::cpp_rational& qq) : q(qq) {} std::istream& operator()(std::istream& in) const { internal::read_float_or_quotient(in, q); return in; } }; #ifdef CGAL_USE_GMP template <> class Input_rep : public IO_rep_is_specialized { boost::multiprecision::mpq_rational& q; public: Input_rep(boost::multiprecision::mpq_rational& qq) : q(qq) {} std::istream& operator()(std::istream& in) const { internal::read_float_or_quotient(in, q); return in; } }; #endif // Copied from leda_rational.h namespace internal { // See: Stream_support/include/CGAL/IO/io.h template void read_float_or_quotient(std::istream & is, ET& et); template <> inline void read_float_or_quotient(std::istream & is, boost::multiprecision::cpp_rational& et) { internal::read_float_or_quotient(is, et); } #ifdef CGAL_USE_GMP template <> inline void read_float_or_quotient(std::istream & is, boost::multiprecision::mpq_rational& et) { internal::read_float_or_quotient(is, et); } #endif } // namespace internal #ifdef CGAL_USE_BOOST_MP template< > class Real_embeddable_traits< Quotient > : public INTERN_QUOTIENT::Real_embeddable_traits_quotient_base< Quotient > { public: typedef Quotient Type; class To_interval : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { return Boost_MP_internal::to_interval(x.num, x.den); } }; }; #endif // CGAL_USE_BOOST_MP } //namespace CGAL namespace Eigen { template struct NumTraits; template<> struct NumTraits { typedef boost::multiprecision::cpp_int Real; typedef boost::multiprecision::cpp_rational NonInteger; typedef boost::multiprecision::cpp_int Nested; typedef boost::multiprecision::cpp_int Literal; static inline Real epsilon() { return 0; } static inline Real dummy_precision() { return 0; } enum { IsInteger = 1, IsSigned = 1, IsComplex = 0, RequireInitialization = 1, ReadCost = 6, AddCost = 30, MulCost = 50 }; }; template<> struct NumTraits { typedef boost::multiprecision::cpp_rational Real; typedef boost::multiprecision::cpp_rational NonInteger; typedef boost::multiprecision::cpp_rational Nested; typedef boost::multiprecision::cpp_rational Literal; static inline Real epsilon() { return 0; } static inline Real dummy_precision() { return 0; } enum { IsInteger = 0, IsSigned = 1, IsComplex = 0, RequireInitialization = 1, ReadCost = 6, AddCost = 150, MulCost = 100 }; }; #ifdef CGAL_USE_GMP template<> struct NumTraits { typedef boost::multiprecision::mpz_int Real; typedef boost::multiprecision::mpq_rational NonInteger; typedef boost::multiprecision::mpz_int Nested; typedef boost::multiprecision::mpz_int Literal; static inline Real epsilon() { return 0; } static inline Real dummy_precision() { return 0; } enum { IsInteger = 1, IsSigned = 1, IsComplex = 0, RequireInitialization = 1, ReadCost = 6, AddCost = 30, MulCost = 50 }; }; template<> struct NumTraits { typedef boost::multiprecision::mpq_rational Real; typedef boost::multiprecision::mpq_rational NonInteger; typedef boost::multiprecision::mpq_rational Nested; typedef boost::multiprecision::mpq_rational Literal; static inline Real epsilon() { return 0; } static inline Real dummy_precision() { return 0; } enum { IsInteger = 0, IsSigned = 1, IsComplex = 0, RequireInitialization = 1, ReadCost = 6, AddCost = 150, MulCost = 100 }; }; #endif // CGAL_USE_GMP } // namespace Eigen #endif // BOOST_VERSION #endif