// Copyright (c) 2006-2008 Max-Planck-Institute Saarbruecken (Germany). // 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) : Michael Hemmer #ifndef CGAL_SQRT_EXTENSION_COERCION_TRAITS_H #define CGAL_SQRT_EXTENSION_COERCION_TRAITS_H #include #define CGAL_int(T) typename First_if_different::Type namespace CGAL { /////////// COERCION_TRAITS BEGIN // and vice versa template struct Coercion_traits_for_level,CGAL_int(COEFF),CTL_SQRT_EXT>{ public: typedef Sqrt_extension Type; typedef CGAL::Tag_true Are_explicit_interoperable; typedef CGAL::Tag_true Are_implicit_interoperable; struct Cast{ typedef Type result_type; Type operator()(const Type& x) const { return x;} Type operator()(int x) const { return Type(x);} }; }; template struct Coercion_traits_for_level,CTL_SQRT_EXT> : public Coercion_traits_for_level,CGAL_int(COEFF),CTL_SQRT_EXT>{}; template struct Coercion_traits_for_level,COEFF,CTL_SQRT_EXT>{ public: typedef Sqrt_extension Type; typedef CGAL::Tag_true Are_explicit_interoperable; typedef CGAL::Tag_true Are_implicit_interoperable; struct Cast{ typedef Type result_type; Type operator()(const Type& x) const { return x;} Type operator()(COEFF x) const { return Type(x);} }; }; template struct Coercion_traits_for_level,CTL_SQRT_EXT> : public Coercion_traits_for_level,COEFF,CTL_SQRT_EXT>{}; // template struct Coercion_traits_for_level, Sqrt_extension, CTL_SQRT_EXT>{ private: typedef Coercion_traits CT; typedef Sqrt_extension A; typedef Sqrt_extension B; public: typedef CGAL::Tag_true Are_explicit_interoperable; typedef CGAL::Tag_false Are_implicit_interoperable; typedef Sqrt_extension Type; struct Cast{ private: inline Type cast(const Type& x) const{ return x; } template inline Type cast(const T& x) const{ typename CT::Cast cast; if (x.is_extended()) { return result_type(cast(x.a0()),cast(x.a1()),x.root()); } else { return result_type(cast(x.a0())); } } public: typedef Type result_type; // this is in order to allow A and B only Type operator()(const A& x) const { return cast(x);} Type operator()(const B& x) const { return cast(x);} }; }; template struct Coercion_traits_for_level,ROOT_2,ACDE_TAG,FP_TAG>, Sqrt_extension, CTL_SQRT_EXT>{ private: typedef Sqrt_extension, ROOT_2,ACDE_TAG,FP_TAG> A; typedef Sqrt_extension B; public: typedef CGAL::Tag_true Are_explicit_interoperable; typedef CGAL::Tag_true Are_implicit_interoperable; // Type = A typedef Sqrt_extension, ROOT_2,ACDE_TAG,FP_TAG> Type; struct Cast{ typedef Type result_type; Type operator()(const A& x) const { return x;} Type operator()(const B& x) const { return Type(x);} }; }; template struct Coercion_traits_for_level < Sqrt_extension, Sqrt_extension, ROOT_2, ACDE_TAG,FP_TAG> ,CTL_SQRT_EXT> :public Coercion_traits_for_level < Sqrt_extension, ROOT_2, ACDE_TAG,FP_TAG>, Sqrt_extension ,CTL_SQRT_EXT> {}; template struct Coercion_traits_for_level < Sqrt_extension, ROOT_1, ACDE_TAG,FP_TAG>, Sqrt_extension ,CTL_SQRT_EXT>{ private: typedef Sqrt_extension, ROOT_1,ACDE_TAG,FP_TAG> A; typedef Sqrt_extension B; public: typedef CGAL::Tag_true Are_explicit_interoperable; typedef CGAL::Tag_true Are_implicit_interoperable; typedef Sqrt_extension, ROOT_1, ACDE_TAG,FP_TAG> Type; struct Cast{ typedef Type result_type; Type operator()(const A& x) const { return x;} Type operator()(const B& x) const { return Type(x);} }; }; template struct Coercion_traits_for_level < Sqrt_extension, Sqrt_extension, ROOT_1,ACDE_TAG,FP_TAG> ,CTL_SQRT_EXT> :public Coercion_traits_for_level < Sqrt_extension, ROOT_1,ACDE_TAG,FP_TAG>, Sqrt_extension ,CTL_SQRT_EXT> {}; namespace INTERN_CT{ // Coercion_traits for Sqrt_extenison to FieldWithSqrt template struct CT_ext_to_fwsqrt; // Coercion_traits for Sqrt_extenison not with FieldWithSqrt template struct CT_ext_not_to_fwsqrt; } // namespace INTERN_CT // template struct Coercion_traits_for_level, B , CTL_SQRT_EXT> :public ::boost::mpl::if_c< // if B is fwsqrt ::boost::is_base_and_derived< Field_with_sqrt_tag, typename Algebraic_structure_traits::Algebraic_category >::value || ::boost::is_same< Field_with_sqrt_tag, typename Algebraic_structure_traits::Algebraic_category >::value , //then take Intern::Coercion_traits for fwsqrt INTERN_CT::CT_ext_to_fwsqrt, B> , //else take Intern::Coercion_traits not for fwsqrt INTERN_CT::CT_ext_not_to_fwsqrt< Sqrt_extension ,B> >::type {}; // template struct Coercion_traits_for_level ,CTL_SQRT_EXT > :public Coercion_traits_for_level,B,CTL_SQRT_EXT> {}; namespace INTERN_CT{ // EXT coercion with FieldWithSqrt template struct CT_ext_to_fwsqrt, FieldWithSqrt>{ private: typedef Sqrt_extension A; typedef FieldWithSqrt B; public: typedef CGAL::Tag_true Are_explicit_interoperable; typedef CGAL::Tag_false Are_implicit_interoperable; typedef FieldWithSqrt Type; struct Cast{ typedef Type result_type; Type operator()(const A& x) const { typedef Coercion_traits CT_coeff; typedef Coercion_traits CT_root; typename CT_coeff::Cast coeff_cast; typename CT_root::Cast root_cast; if (x.is_extended()) { typename CGAL::Algebraic_structure_traits< typename CT_root::Type>::Sqrt sqrt; return // a0+a1*sqrt(root) coeff_cast(x.a0())+ coeff_cast(x.a1())* sqrt(root_cast(x.root())); } else { return coeff_cast(x.a0()); } } Type operator()(const B& x) const { return x;} }; }; // EXT coercion not with FieldWithSqrt template struct CT_ext_not_to_fwsqrt, B_>{ private: typedef Sqrt_extension A; typedef B_ B; typedef Coercion_traits CT; public: typedef CGAL::Tag_true Are_explicit_interoperable; typedef CGAL::Tag_false Are_implicit_interoperable; typedef Sqrt_extension Type; struct Cast{ typedef Type result_type; Type operator()(const A& x) const { typename CT::Cast cast; if (x.is_extended()) { return Type(cast(x.a0()),cast(x.a1()),x.root()); } else { return Type(cast(x.a0())); } } Type operator()(const B& x) const { typename CT::Cast cast; return Type(cast(x)); } }; }; } // namespace INTERN_CT /////////// COERCION_TRAITS END } //namespace CGAL #undef CGAL_int #endif