dust3d/thirdparty/cgal/CGAL-5.1/include/CGAL/Sqrt_extension/Fraction_traits.h

227 lines
8.3 KiB
C
Raw Normal View History

// Copyright (c) 2006-2008 Max-Planck-Institute Saarbruecken (Germany).
// All rights reserved.
//
2020-10-13 12:44:25 +00:00
// This file is part of CGAL (www.cgal.org)
//
2020-10-13 12:44:25 +00:00
// $URL: https://github.com/CGAL/cgal/blob/v5.1/Number_types/include/CGAL/Sqrt_extension/Fraction_traits.h $
// $Id: Fraction_traits.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
#ifndef CGAL_SQRT_EXTENSION_FRACTION_TRAITS_H
#define CGAL_SQRT_EXTENSION_FRACTION_TRAITS_H
#include <CGAL/basic.h>
namespace CGAL {
//################################# CGAL::Fraction_traits ##################
// Select the right alternative as Fraction_traits
// The actual Type traits is Intern::Sqrt_ext_Ftr_base_2
// The selction is done in two steps:
// 1. Inter::Sqrt_ext_Ftr_base_1 selects by the BOOL_TAG whether the COEFF type
// Is_fraction
// 2. Intern::Sqrt_ext_Ftr_base_2 checks whether the internal type of the ROOT
// is still implicite convertible to the new COEFF type.
// since the ROOT type it self can not be converted.
namespace Intern{
template <class EXT, bool> class Sqrt_ext_Ftr_base_2;
template <class EXT, class BOOL_TAG> class Sqrt_ext_Ftr_base_1;
}
/*! \ingroup CGAL_Sqrt_extension
\ingroup CGAL_Fraction_traits_spec
\brief Specialisation of CGAL::Fraction_traits for CGAL::Sqrt_extension.
*
* Extensions provide suitable specializations of \c CGAL::Fraction_traits.
* They are decomposable iff their coefficient type is.
* The denominator \e d of a Extension \e ext is a low common multiple
* (see \c CGAL::Fraction_traits::Common_factor for details) of the
* denominators of its coefficients. The numerator is the Extenion
* \e d*ext with a fraction-free coefficient type.
*
* This works for nested Sqrt_extensions, too.
*/
template <class COEFF, class ROOT, class ACDE_TAG, class FP_TAG >
class Fraction_traits< Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG > >
: public Intern::Sqrt_ext_Ftr_base_1<
Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG >,
typename CGAL::Fraction_traits<COEFF>::Is_fraction >
{
// nothing new
};
namespace Intern {
// Use this if the coefficients cannot be decomposed
// into numerator and denominator
template <class NT_ >
class Sqrt_ext_Ftr_base_2< NT_, false > {
public:
typedef NT_ NT;
typedef ::CGAL::Tag_false Is_fraction;
typedef ::CGAL::Null_tag Numerator_type;
typedef ::CGAL::Null_tag Denominator_type;
typedef ::CGAL::Null_tag Common_factor;
typedef ::CGAL::Null_tag Decompose;
typedef ::CGAL::Null_tag Compose;
};
template <class COEFF, class ROOT, class ACDE_TAG,class FP_TAG>
class Sqrt_ext_Ftr_base_2< Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG>, true > {
private:
typedef Fraction_traits<COEFF> CFT;
public:
typedef Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG> NT;
typedef CGAL::Tag_true Is_fraction;
typedef Sqrt_extension<typename CFT::Numerator_type,ROOT,ACDE_TAG,FP_TAG> Numerator_type;
typedef typename CFT::Denominator_type Denominator_type;
typedef typename Algebraic_structure_traits<Denominator_type>::Gcd Common_factor;
class Decompose {
public:
typedef NT first_argument_type;
typedef Numerator_type second_argument_type;
typedef Denominator_type& third_argument_type;
void operator () (const NT& ext,
Numerator_type& num,
Denominator_type& den){
typename CFT::Decompose decompose;
typename CFT::Common_factor common_factor;
typedef typename CFT::Numerator_type NUM;
typedef typename CFT::Denominator_type DEN;
if(ext.is_extended()){
NUM a0_num, a1_num;
DEN a0_den, a1_den;
DEN common_den;
decompose(ext.a0(),a0_num,a0_den);
decompose(ext.a1(),a1_num,a1_den);
common_den=common_factor(a0_den,a1_den);
typename CGAL::Coercion_traits<NUM,DEN>::Cast cast;
2020-10-13 12:44:25 +00:00
a0_num = cast(a0_num) *
cast(CGAL::integral_division(a1_den,common_den));
2020-10-13 12:44:25 +00:00
a1_num = cast(a1_num) *
cast(CGAL::integral_division(a0_den,common_den));
den = CGAL::integral_division(a0_den,common_den)*a1_den;
num = Numerator_type(a0_num,a1_num,ext.root());
}else{
NUM a0_num;
decompose(ext.a0(),a0_num,den);
num = Numerator_type(a0_num);
}
}
};
class Compose {
public:
typedef Numerator_type first_argument_type;
typedef Denominator_type second_argument_type;
typedef NT result_type;
NT operator () (const Numerator_type& num,
const Denominator_type& den){
if(num.is_extended()){
typename CFT::Compose compose;
COEFF a0=compose(num.a0(),den);
COEFF a1=compose(num.a1(),den);
return NT(a0,a1,num.root());
}else{
typename CFT::Compose compose;
COEFF a0=compose(num.a0(),den);
return NT(a0);
}
}
};
};
template <class EXT, class BOOL_TAG>
class Sqrt_ext_Ftr_base_1;
template <class COEFF, class ROOT, class ACDE_TAG, class FP_TAG>
class Sqrt_ext_Ftr_base_1< Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG>, CGAL::Tag_true >
: public Sqrt_ext_Ftr_base_2<
Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG>,
::boost::is_same< typename CGAL::Coercion_traits<ROOT,typename CGAL::Fraction_traits<COEFF>::Numerator_type>::Type,
typename CGAL::Fraction_traits<COEFF>::Numerator_type>::value >
{
//nothing new
};
template <class COEFF, class ROOT, class ACDE_TAG, class FP_TAG>
class Sqrt_ext_Ftr_base_1< Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG>, CGAL::Tag_false >
: public Sqrt_ext_Ftr_base_2< Sqrt_extension<COEFF,ROOT,ACDE_TAG,FP_TAG>, false>
{
//nothing new
};
} // namespace Intern
/*
namespace Intern{
template <class SqrtExt,class BoolTag> class Sqrt_ext_Coftr_base_1;
template <class SqrtExt>
class Sqrt_ext_Coftr_base_1< SqrtExt, CGAL::Tag_false >{
public:
typedef SqrtExt Numerator_type;
typedef ::CGAL::Tag_false Is_composable;
typedef ::CGAL::Null_tag Denominator_type;
typedef ::CGAL::Null_tag Type;
typedef ::CGAL::Null_tag Compose;
};
template <class SqrtExt>
class Sqrt_ext_Coftr_base_1< SqrtExt, CGAL::Tag_true >{
typedef typename SqrtExt::NT Coeff;
typedef typename SqrtExt::ROOT Root;
typedef typename CGAL::Cofraction_traits<Coeff> CFT;
typedef typename CFT::Type Type_coeff;
public:
typedef SqrtExt Numerator_type;
typedef ::CGAL::Tag_true Is_composable;
typedef typename CFT::Denominator_type Denominator;
typedef CGAL::Sqrt_extension<Type_coeff,Root,ACDE_TAG,FP_TAG> Type;
class Compose {
public:
//! first argument type
typedef Numerator_type first_argument_type;
//! second argument type
typedef Denominator_type second_argument_type;
//! result type
typedef Type result_type;
//! Compose fraction
Type operator() (Numerator_type num,
Denominator_type den){
if(num.is_extended()){
typename CFT::Compose compose_coeff;
Type_coeff a0_new(compose_coeff(num.a0(),den));
Type_coeff a1_new(compose_coeff(num.a1(),den));
return result_type(a0_new, a1_new, num.root());
}else{
typename CFT::Compose compose_coeff;
return result_type(compose_coeff(num.a0(),den));
}
};
};
};
}
template <class Coeff, class Root,class ACDE_TAG, class FP_TAG>
class Cofraction_traits<Sqrt_extension<Coeff,Root,ACDE_TAG,FP_TAG> >
:public Intern::Sqrt_ext_Coftr_base_1<
Sqrt_extension<Coeff,Root,ACDE_TAG,FP_TAG>,
typename CGAL::Cofraction_traits<Coeff>::Is_composable>{
//nothing new;
};
*/
} //namespace CGAL
#endif