1 // Copyright (c) 2006-2008 Max-Planck-Institute Saarbruecken (Germany). 2 // All rights reserved. 3 // 4 // This file is part of CGAL (www.cgal.org) 5 // 6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Number_types/include/CGAL/Sqrt_extension/Fraction_traits.h $ 7 // $Id: Fraction_traits.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot 8 // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial 9 // 10 // 11 // Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de> 12 13 14 #ifndef CGAL_SQRT_EXTENSION_FRACTION_TRAITS_H 15 #define CGAL_SQRT_EXTENSION_FRACTION_TRAITS_H 16 17 #include <CGAL/basic.h> 18 19 namespace CGAL { 20 21 22 23 24 //################################# CGAL::Fraction_traits ################## 25 // Select the right alternative as Fraction_traits 26 // The actual Type traits is Intern::Sqrt_ext_Ftr_base_2 27 // The selction is done in two steps: 28 // 1. Inter::Sqrt_ext_Ftr_base_1 selects by the BOOL_TAG whether the COEFF type 29 // Is_fraction 30 // 2. Intern::Sqrt_ext_Ftr_base_2 checks whether the internal type of the ROOT 31 // is still implicite convertible to the new COEFF type. 32 // since the ROOT type it self can not be converted. 33 namespace Intern{ 34 template <class EXT, bool> class Sqrt_ext_Ftr_base_2; 35 template <class EXT, class BOOL_TAG> class Sqrt_ext_Ftr_base_1; 36 } 37 38 /*! \ingroup CGAL_Sqrt_extension 39 \ingroup CGAL_Fraction_traits_spec 40 \brief Specialisation of CGAL::Fraction_traits for CGAL::Sqrt_extension. 41 * 42 * Extensions provide suitable specializations of \c CGAL::Fraction_traits. 43 * They are decomposable iff their coefficient type is. 44 * The denominator \e d of a Extension \e ext is a low common multiple 45 * (see \c CGAL::Fraction_traits::Common_factor for details) of the 46 * denominators of its coefficients. The numerator is the Extenion 47 * \e d*ext with a fraction-free coefficient type. 48 * 49 * This works for nested Sqrt_extensions, too. 50 */ 51 52 template <class COEFF, class ROOT, class ACDE_TAG, class FP_TAG > 53 class Fraction_traits< Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG > > 54 : public Intern::Sqrt_ext_Ftr_base_1< 55 Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG >, 56 typename CGAL::Fraction_traits<COEFF>::Is_fraction > 57 { 58 // nothing new 59 }; 60 61 namespace Intern { 62 63 // Use this if the coefficients cannot be decomposed 64 // into numerator and denominator 65 template <class NT_ > 66 class Sqrt_ext_Ftr_base_2< NT_, false > { 67 public: 68 typedef NT_ NT; 69 typedef ::CGAL::Tag_false Is_fraction; 70 typedef ::CGAL::Null_tag Numerator_type; 71 typedef ::CGAL::Null_tag Denominator_type; 72 typedef ::CGAL::Null_tag Common_factor; 73 typedef ::CGAL::Null_tag Decompose; 74 typedef ::CGAL::Null_tag Compose; 75 }; 76 77 template <class COEFF, class ROOT, class ACDE_TAG,class FP_TAG> 78 class Sqrt_ext_Ftr_base_2< Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG>, true > { 79 private: 80 typedef Fraction_traits<COEFF> CFT; 81 public: 82 typedef Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG> NT; 83 typedef CGAL::Tag_true Is_fraction; 84 typedef Sqrt_extension<typename CFT::Numerator_type,ROOT,ACDE_TAG,FP_TAG> Numerator_type; 85 typedef typename CFT::Denominator_type Denominator_type; 86 typedef typename Algebraic_structure_traits<Denominator_type>::Gcd Common_factor; 87 88 class Decompose { 89 public: 90 typedef NT first_argument_type; 91 typedef Numerator_type second_argument_type; 92 typedef Denominator_type& third_argument_type; operator()93 void operator () (const NT& ext, 94 Numerator_type& num, 95 Denominator_type& den){ 96 typename CFT::Decompose decompose; 97 typename CFT::Common_factor common_factor; 98 typedef typename CFT::Numerator_type NUM; 99 typedef typename CFT::Denominator_type DEN; 100 101 if(ext.is_extended()){ 102 NUM a0_num, a1_num; 103 DEN a0_den, a1_den; 104 DEN common_den; 105 decompose(ext.a0(),a0_num,a0_den); 106 decompose(ext.a1(),a1_num,a1_den); 107 common_den=common_factor(a0_den,a1_den); 108 typename CGAL::Coercion_traits<NUM,DEN>::Cast cast; 109 a0_num = cast(a0_num) * 110 cast(CGAL::integral_division(a1_den,common_den)); 111 a1_num = cast(a1_num) * 112 cast(CGAL::integral_division(a0_den,common_den)); 113 den = CGAL::integral_division(a0_den,common_den)*a1_den; 114 num = Numerator_type(a0_num,a1_num,ext.root()); 115 }else{ 116 NUM a0_num; 117 decompose(ext.a0(),a0_num,den); 118 num = Numerator_type(a0_num); 119 } 120 } 121 }; 122 class Compose { 123 public: 124 typedef Numerator_type first_argument_type; 125 typedef Denominator_type second_argument_type; 126 typedef NT result_type; operator()127 NT operator () (const Numerator_type& num, 128 const Denominator_type& den){ 129 if(num.is_extended()){ 130 typename CFT::Compose compose; 131 COEFF a0=compose(num.a0(),den); 132 COEFF a1=compose(num.a1(),den); 133 return NT(a0,a1,num.root()); 134 }else{ 135 typename CFT::Compose compose; 136 COEFF a0=compose(num.a0(),den); 137 return NT(a0); 138 } 139 } 140 }; 141 }; 142 143 template <class EXT, class BOOL_TAG> 144 class Sqrt_ext_Ftr_base_1; 145 146 template <class COEFF, class ROOT, class ACDE_TAG, class FP_TAG> 147 class Sqrt_ext_Ftr_base_1< Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG>, CGAL::Tag_true > 148 : public Sqrt_ext_Ftr_base_2< 149 Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG>, 150 ::boost::is_same< typename CGAL::Coercion_traits<ROOT,typename CGAL::Fraction_traits<COEFF>::Numerator_type>::Type, 151 typename CGAL::Fraction_traits<COEFF>::Numerator_type>::value > 152 { 153 //nothing new 154 }; 155 156 template <class COEFF, class ROOT, class ACDE_TAG, class FP_TAG> 157 class Sqrt_ext_Ftr_base_1< Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG>, CGAL::Tag_false > 158 : public Sqrt_ext_Ftr_base_2< Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG>, false> 159 { 160 //nothing new 161 }; 162 } // namespace Intern 163 164 165 /* 166 namespace Intern{ 167 template <class SqrtExt,class BoolTag> class Sqrt_ext_Coftr_base_1; 168 template <class SqrtExt> 169 class Sqrt_ext_Coftr_base_1< SqrtExt, CGAL::Tag_false >{ 170 public: 171 typedef SqrtExt Numerator_type; 172 typedef ::CGAL::Tag_false Is_composable; 173 typedef ::CGAL::Null_tag Denominator_type; 174 typedef ::CGAL::Null_tag Type; 175 typedef ::CGAL::Null_tag Compose; 176 }; 177 template <class SqrtExt> 178 class Sqrt_ext_Coftr_base_1< SqrtExt, CGAL::Tag_true >{ 179 typedef typename SqrtExt::NT Coeff; 180 typedef typename SqrtExt::ROOT Root; 181 typedef typename CGAL::Cofraction_traits<Coeff> CFT; 182 typedef typename CFT::Type Type_coeff; 183 184 public: 185 typedef SqrtExt Numerator_type; 186 typedef ::CGAL::Tag_true Is_composable; 187 typedef typename CFT::Denominator_type Denominator; 188 typedef CGAL::Sqrt_extension<Type_coeff,Root,ACDE_TAG,FP_TAG> Type; 189 190 class Compose { 191 public: 192 //! first argument type 193 typedef Numerator_type first_argument_type; 194 //! second argument type 195 typedef Denominator_type second_argument_type; 196 //! result type 197 typedef Type result_type; 198 //! Compose fraction 199 Type operator() (Numerator_type num, 200 Denominator_type den){ 201 if(num.is_extended()){ 202 typename CFT::Compose compose_coeff; 203 Type_coeff a0_new(compose_coeff(num.a0(),den)); 204 Type_coeff a1_new(compose_coeff(num.a1(),den)); 205 return result_type(a0_new, a1_new, num.root()); 206 }else{ 207 typename CFT::Compose compose_coeff; 208 return result_type(compose_coeff(num.a0(),den)); 209 } 210 }; 211 }; 212 }; 213 } 214 215 template <class Coeff, class Root,class ACDE_TAG, class FP_TAG> 216 class Cofraction_traits<Sqrt_extension<Coeff,Root,ACDE_TAG,FP_TAG> > 217 :public Intern::Sqrt_ext_Coftr_base_1< 218 Sqrt_extension<Coeff,Root,ACDE_TAG,FP_TAG>, 219 typename CGAL::Cofraction_traits<Coeff>::Is_composable>{ 220 //nothing new; 221 }; 222 */ 223 224 } //namespace CGAL 225 226 #endif 227