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