// Copyright (c) 2008 Max-Planck-Institute Saarbruecken (Germany) // // This file is part of CGAL (www.cgal.org) // // $URL: https://github.com/CGAL/cgal/blob/v5.1/Polynomial/include/CGAL/Polynomial/Coercion_traits.h $ // $Id: Coercion_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 // // ============================================================================ #ifndef CGAL_POLYNOMIAL_COERCION_TRAITS_H #define CGAL_POLYNOMIAL_COERCION_TRAITS_H // The coercion type of two polynomials is a polynomial in d=max(d1,d2) // variables, where d1 and d2 are the number of variables the two // polynomials. (This also includes the case of d1 = 0 or d2 = 0.) // Moreover, the new Innermost_coefficient_type is the coercion type of the // two Innermost_coefficient_types of the two involved polynomials. // (Again, this is generalized if one of the involved types is just a scalar // type) // Though the coercion type is clear, the problem is how to match the // variables. The recursive definition of Polynomial suggest that // the coercion type of two polynomial types Polynomial and Polynomial // is defined as Polynomial, where C is the coercion type. // However, this is not in line with the fact that a Polynomial // is interoperable with its coefficient type A, that is, if A is a polynomial // the variables of A should not be moved outward while casting A to // Polynomial. #include namespace CGAL { namespace internal{ // A has less variables than B template struct Coercion_traits_for_polynomial_comp_d :public Coercion_traits_for_polynomial_comp_d< B, A , false >{}; // Polynomial has more variables than B template struct Coercion_traits_for_polynomial_comp_d< Polynomial, B , false>{ typedef Coercion_traits CT; typedef CGAL::Tag_true Are_explicit_interoperable; typedef CGAL::Tag_false Are_implicit_interoperable; typedef Polynomial Type; struct Cast{ typedef Type result_type; Type operator()(const Polynomial& poly) const { typename CT::Cast cast; return Type(::boost::make_transform_iterator(poly.begin(),cast), ::boost::make_transform_iterator(poly.end() ,cast)); } Type operator()(const B& x) const { typename CT::Cast cast; return Type(cast(x)); } }; }; // number of variables is different template struct Coercion_traits_for_polynomial_equal_d :public Coercion_traits_for_polynomial_comp_d {}; // number of variables is equal and at least one. template struct Coercion_traits_for_polynomial_equal_d, Polynomial, d, d >{ typedef Coercion_traits CT; typedef CGAL::Tag_true Are_explicit_interoperable; typedef CGAL::Tag_false Are_implicit_interoperable; typedef Polynomial Type; struct Cast{ typedef Type result_type; Type operator()(const Polynomial& poly) const { typename CT::Cast cast; return Type(::boost::make_transform_iterator(poly.begin(),cast), ::boost::make_transform_iterator(poly.end() ,cast)); } Type operator()(const Polynomial& poly) const { typename CT::Cast cast; return Type(::boost::make_transform_iterator(poly.begin(),cast), ::boost::make_transform_iterator(poly.end() ,cast)); } }; }; // determine number of variables in each polynomial template struct Coercion_traits_for_polynomial : public Coercion_traits_for_polynomial_equal_d < A , B , Dimension::value, Dimension::value >{}; }// namespace internal template struct Coercion_traits_for_level< Polynomial , Polynomial, CTL_POLYNOMIAL > :public internal::Coercion_traits_for_polynomial< Polynomial, Polynomial > {}; template struct Coercion_traits_for_level< Polynomial , B , CTL_POLYNOMIAL > :public internal::Coercion_traits_for_polynomial< Polynomial, B > {}; template struct Coercion_traits_for_level< A , Polynomial , CTL_POLYNOMIAL > :public internal::Coercion_traits_for_polynomial< A , Polynomial > {}; #if 0 // COERCION_TRAITS BEGIN //Coercion_traits_polynomial----------------------------------- // If there is a Polynomial_traits, valid for more than one Polynomial // class this part should be adapted, using a Polynomial_traits // and the nesting_depth template struct Coercion_traits_for_level, Polynomial, CTL_POLYNOMIAL >{ typedef Coercion_traits CT; typedef CGAL::Tag_true Are_explicit_interoperable; typedef CGAL::Tag_false Are_implicit_interoperable; typedef Polynomial Type; struct Cast{ typedef Type result_type; Type operator()(const Polynomial& poly) const { typename CT::Cast cast; return Type(::boost::make_transform_iterator(poly.begin(),cast), ::boost::make_transform_iterator(poly.end() ,cast)); } Type operator()(const Polynomial& poly) const { typename CT::Cast cast; return Type(::boost::make_transform_iterator(poly.begin(),cast), ::boost::make_transform_iterator(poly.end() ,cast)); } }; }; template struct Coercion_traits_for_level,B ,CTL_POLYNOMIAL >{ typedef Coercion_traits CT; typedef CGAL::Tag_true Are_explicit_interoperable; typedef CGAL::Tag_false Are_implicit_interoperable; typedef Polynomial Type; struct Cast{ typedef Type result_type; Type operator()(const Polynomial& poly) const { typename CT::Cast cast; return Type(::boost::make_transform_iterator(poly.begin(),cast), ::boost::make_transform_iterator(poly.end() ,cast)); } Type operator()(const B& x) const { typename CT::Cast cast; return Type(cast(x)); } }; }; template struct Coercion_traits_for_level,CTL_POLYNOMIAL > :public Coercion_traits_for_level,B,CTL_POLYNOMIAL > {}; #endif // 0 // COERCION_TRAITS END } //namespace CGAL #endif // CGAL_POLYNOMIAL_COERCION_TRAITS_H