// Copyright (c) 1999,2007 // Utrecht University (The Netherlands), // ETH Zurich (Switzerland), // INRIA Sophia-Antipolis (France), // Max-Planck-Institute Saarbruecken (Germany), // and Tel-Aviv University (Israel). All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 3 of the License, // or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0+ // // // Author(s) : Stefan Schirra, Michael Hemmer #ifndef CGAL_INT_H #define CGAL_INT_H #include #include #include namespace CGAL { namespace INTERN_INT { template< class Type > class Is_square_per_double_conversion : public CGAL::cpp98::binary_function< Type, Type&, bool > { public: bool operator()( const Type& x, Type& y ) const { y = (Type) std::sqrt( (double)x ); return x == y * y; } bool operator()( const Type& x ) const { Type y = (Type) std::sqrt( (double)x ); return x == y * y; } }; } // INTERN_INT // int template<> class Algebraic_structure_traits< int > : public Algebraic_structure_traits_base< int, Euclidean_ring_tag > { public: typedef Tag_false Is_exact; typedef Tag_true Is_numerical_sensitive; typedef INTERN_AST::Div_per_operator< Type > Div; typedef INTERN_AST::Mod_per_operator< Type > Mod; typedef INTERN_INT:: Is_square_per_double_conversion< Type > Is_square; }; template <> class Real_embeddable_traits< int > : public INTERN_RET::Real_embeddable_traits_base< int , CGAL::Tag_true > {}; /*! \ingroup CGAL_Modular_traits_spec \brief Specialization of CGAL::Modular_traits for \c int. A model of concept ModularTraits, supports \c int. */ template class Modular_traits; template<> class Modular_traits{ public: typedef int NT; typedef ::CGAL::Tag_true Is_modularizable; typedef Residue Residue_type; struct Modular_image{ Residue_type operator()(int i){ return Residue_type(i); } }; struct Modular_image_representative{ NT operator()(const Residue_type& x){ return x.get_value(); } }; }; // long template<> class Algebraic_structure_traits< long int > : public Algebraic_structure_traits_base< long int, Euclidean_ring_tag > { public: typedef Tag_false Is_exact; typedef Tag_true Is_numerical_sensitive; typedef INTERN_AST::Div_per_operator< Type > Div; typedef INTERN_AST::Mod_per_operator< Type > Mod; typedef INTERN_INT:: Is_square_per_double_conversion< Type > Is_square; }; template <> class Real_embeddable_traits< long int > : public INTERN_RET::Real_embeddable_traits_base< long int , CGAL::Tag_true > { public: class To_interval : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { return Interval_nt(x).pair(); } }; }; /*! \ingroup CGAL_Modular_traits_spec \brief Specialization of CGAL::Modular_traits for \c long. A model of concept ModularTraits, supports \c long. */ template<> class Modular_traits{ public: typedef long NT; typedef ::CGAL::Tag_true Is_modularizable; typedef Residue Residue_type; struct Modular_image{ Residue_type operator()(long i){ return Residue_type(i); } }; struct Modular_image_representative{ NT operator()(const Residue_type& x){ return NT(x.get_value()); } }; }; // short template<> class Algebraic_structure_traits< short int > : public Algebraic_structure_traits_base< short int, Euclidean_ring_tag > { public: typedef Tag_false Is_exact; typedef Tag_true Is_numerical_sensitive; // Explicitly defined functors which have no support for implicit // interoperability. This is nescessary because of the implicit conversion // to int for binary operations between short ints. class Integral_division : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, const Type& y) const { Algebraic_structure_traits::Div actual_div; CGAL_precondition_msg( actual_div( x, y) * y == x, "'x' must be divisible by 'y' in " "Algebraic_structure_traits<...>::Integral_div()(x,y)" ); return actual_div( x, y); } }; class Gcd : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, const Type& y) const { Algebraic_structure_traits::Mod mod; Algebraic_structure_traits::Unit_part unit_part; Algebraic_structure_traits::Integral_division integral_div; // First: the extreme cases and negative sign corrections. if (x == Type(0)) { if (y == Type(0)) return Type(0); return integral_div( y, unit_part(y) ); } if (y == Type(0)) return integral_div(x, unit_part(x) ); Type u = integral_div( x, unit_part(x) ); Type v = integral_div( y, unit_part(y) ); // Second: assuming mod is the most expensive op here, we don't compute it // unnecessarily if u < v if (u < v) { v = mod(v,u); // maintain invariant of v > 0 for the loop below if ( v == Type(0) ) return u; } Type w; do { w = mod(u,v); if ( w == Type(0)) return v; u = mod(v,w); if ( u == Type(0)) return w; v = mod(w,u); } while (v != Type(0)); return u; } }; class Div_mod { public: typedef Type first_argument_type; typedef Type second_argument_type; typedef Type& third_argument_type; typedef Type& fourth_argument_type; typedef void result_type; void operator()( const Type& x, const Type& y, Type& q, Type& r) const { q = Type(x / y); r = Type(x % y); CGAL_assertion(x == q * y + r); return; } }; // based on \c Div_mod. class Div : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, const Type& y) const { return Type(x / y); }; }; // based on \c Div_mod. class Mod : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, const Type& y) const { return Type(x % y); }; }; typedef INTERN_INT:: Is_square_per_double_conversion< Type > Is_square; }; template <> class Real_embeddable_traits< short int > : public INTERN_RET::Real_embeddable_traits_base< short int , CGAL::Tag_true > {}; // unsigned int template <> class Real_embeddable_traits< unsigned int > : public INTERN_RET::Real_embeddable_traits_base< unsigned int , CGAL::Tag_true > {}; // unsigned long template <> class Real_embeddable_traits< unsigned long > : public INTERN_RET::Real_embeddable_traits_base< unsigned long , CGAL::Tag_true > { public: class To_interval : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { return Interval_nt(x).pair(); } }; }; // Note : "long long" support is in } //namespace CGAL #endif // CGAL_INT_H