1 // Copyright (c) 2006-2007 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/Algebraic_foundations/include/CGAL/Coercion_traits.h $ 7 // $Id: Coercion_traits.h 26355e2 2020-06-25T12:31:21+02:00 Mael Rouxel-Labbé 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 15 /*! \file NiX/Coercion_traits.h 16 * \brief defines class NiX::Coercion_traits. 17 * 18 * Provides the general definition of the \c Coercion_traits<A,B> class, with 19 * specializations for the builtin number types. 20 */ 21 22 #ifndef CGAL_COERCION_TRAITS_H 23 #define CGAL_COERCION_TRAITS_H 1 24 25 #include <iterator> 26 27 #include <CGAL/boost/iterator/transform_iterator.hpp> 28 #include <boost/type_traits/is_same.hpp> 29 30 #include <CGAL/tags.h> 31 32 // Makro to define an additional operator for binary functors which takes 33 // two number types as parameters that are interoperable with the 34 // number type 35 #define CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR_WITH_RT( NT, Result_type ) \ 36 template < class CT_Type_1, class CT_Type_2 > \ 37 Result_type operator()( const CT_Type_1& x, const CT_Type_2& y ) const { \ 38 CGAL_static_assertion((::boost::is_same< \ 39 typename Coercion_traits< CT_Type_1, CT_Type_2 >::Type, NT \ 40 >::value)); \ 41 \ 42 typename Coercion_traits< CT_Type_1, CT_Type_2 >::Cast cast; \ 43 return operator()( cast(x), cast(y) ); \ 44 } 45 46 #define CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( NT ) \ 47 CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR_WITH_RT( NT, NT ) 48 49 #define CGAL_DEFINE_COERCION_TRAITS_FROM_TO(FROM,TO) \ 50 template <> \ 51 struct Coercion_traits< FROM , TO >{ \ 52 typedef Tag_true Are_explicit_interoperable; \ 53 typedef Tag_true Are_implicit_interoperable; \ 54 typedef TO Type; \ 55 struct Cast{ \ 56 typedef Type result_type; \ 57 Type operator()(const TO& x) const { return x;} \ 58 Type operator()(const FROM& x) const { \ 59 return Type(x);} \ 60 }; \ 61 }; \ 62 template <> \ 63 struct Coercion_traits< TO , FROM >{ \ 64 typedef Tag_true Are_explicit_interoperable; \ 65 typedef Tag_true Are_implicit_interoperable; \ 66 typedef TO Type; \ 67 struct Cast{ \ 68 typedef Type result_type; \ 69 Type operator()(const TO& x) const { return x;} \ 70 Type operator()(const FROM& x) const { \ 71 return Type(x);} \ 72 }; \ 73 }; 74 75 #define CGAL_DEFINE_COERCION_TRAITS_FROM_TO_TEM(FROM,TO,TEM) \ 76 template <TEM> \ 77 struct Coercion_traits< FROM , TO >{ \ 78 typedef Tag_true Are_explicit_interoperable; \ 79 typedef Tag_true Are_implicit_interoperable; \ 80 typedef TO Type; \ 81 struct Cast{ \ 82 typedef Type result_type; \ 83 Type operator()(const TO& x) const { return x;} \ 84 Type operator()(const FROM& x) const { \ 85 return Type(x);} \ 86 }; \ 87 }; \ 88 template <TEM> \ 89 struct Coercion_traits< TO , FROM >{ \ 90 typedef Tag_true Are_explicit_interoperable; \ 91 typedef Tag_true Are_implicit_interoperable; \ 92 typedef TO Type; \ 93 struct Cast{ \ 94 typedef Type result_type; \ 95 Type operator()(const TO& x) const { return x;} \ 96 Type operator()(const FROM& x) const { \ 97 return Type(x);} \ 98 }; \ 99 }; 100 101 102 103 #define CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(A) \ 104 template <> \ 105 struct Coercion_traits< A , A >{ \ 106 typedef Tag_true Are_explicit_interoperable; \ 107 typedef Tag_true Are_implicit_interoperable; \ 108 typedef A Type; \ 109 struct Cast{ \ 110 typedef Type result_type; \ 111 Type operator()(const A& x) const { return x;} \ 112 }; \ 113 }; 114 115 #define CGAL_DEFINE_COERCION_TRAITS_FOR_SELF_TEM(A,TEM) \ 116 template <TEM> \ 117 struct Coercion_traits< A , A >{ \ 118 typedef Tag_true Are_explicit_interoperable; \ 119 typedef Tag_true Are_implicit_interoperable; \ 120 typedef A Type; \ 121 struct Cast{ \ 122 typedef Type result_type; \ 123 Type operator()(const A& x) const {return x;} \ 124 }; \ 125 }; 126 127 namespace CGAL { 128 129 130 namespace INTERN_CT{ 131 template< class FROM, class TO >struct Cast_from_to{ 132 typedef TO result_type; operatorCast_from_to133 TO operator()(const TO& x) const {return x;} operatorCast_from_to134 TO operator()(const FROM& x) const {return TO(x);} 135 }; 136 template< class TO> 137 struct Cast_from_to<TO,TO>{ 138 typedef TO result_type; 139 TO operator()(const TO& x) const {return x;} 140 }; 141 } 142 143 144 template<class A , class B> struct Coercion_traits; 145 template<class A , class B, int > struct Coercion_traits_for_level; 146 147 148 149 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,int) 150 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,long) 151 #ifdef CGAL_USE_LONG_LONG 152 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,long long) 153 #endif 154 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,float) 155 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,double) 156 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,long double) 157 158 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,long) 159 #ifdef CGAL_USE_LONG_LONG 160 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,long long) 161 #endif 162 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,float) 163 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,double) 164 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,long double) 165 166 #ifdef CGAL_USE_LONG_LONG 167 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,long long) 168 #endif 169 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,float) 170 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,double) 171 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,long double) 172 173 #ifdef CGAL_USE_LONG_LONG 174 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,float) 175 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,double) 176 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,long double) 177 #endif 178 179 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(float,double) 180 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(float,long double) 181 182 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(double,long double) 183 184 //! Specialization for equal types. 185 template <class A> 186 struct Coercion_traits<A,A>{ 187 typedef Tag_true Are_explicit_interoperable; 188 typedef Tag_true Are_implicit_interoperable; 189 typedef A Type; 190 struct Cast{ 191 typedef Type result_type; 192 Type inline operator()(const A& x) const { 193 return x; 194 } 195 }; 196 }; 197 198 CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(short) 199 CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(int) 200 CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(long) 201 #ifdef CGAL_USE_LONG_LONG 202 CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(long long) 203 #endif 204 CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(float) 205 CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(double) 206 CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(long double) 207 208 enum COERCION_TRAITS_LEVEL { 209 CTL_TOP = 4, 210 CTL_POLYNOMIAL = 4, 211 CTL_COMPLEX = 3, 212 CTL_INTERVAL = 2, 213 CTL_SQRT_EXT = 1 214 }; 215 216 template <class A, class B, int i > 217 struct Coercion_traits_for_level: public Coercion_traits_for_level<A,B,i-1>{}; 218 219 template <class A, class B> 220 struct Coercion_traits_for_level<A,B,0> { 221 typedef Tag_false Are_explicit_interoperable; 222 typedef Tag_false Are_implicit_interoperable; 223 // typedef Null_type Type; 224 typedef Null_functor Cast; 225 }; 226 227 template<class A , class B> 228 struct Coercion_traits :public Coercion_traits_for_level<A,B,CTL_TOP>{}; 229 230 231 } //namespace CGAL 232 233 #endif //NiX_COERCION_TRAITS_H 234