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