ivl 679
|
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>. 00002 A C++ template library extending syntax towards mathematical notation. 00003 00004 Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr> 00005 Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr> 00006 00007 ivl is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU Lesser General Public License 00009 version 3 as published by the Free Software Foundation. 00010 00011 Alternatively, you can redistribute it and/or modify it under the terms 00012 of the GNU General Public License version 2 as published by the Free 00013 Software Foundation. 00014 00015 ivl is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00018 See the GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 and a copy of the GNU Lesser General Public License along 00022 with ivl. If not, see <http://www.gnu.org/licenses/>. */ 00023 00024 #ifndef IVL_CORE_DETAILS_MATH_CAST_HPP 00025 #define IVL_CORE_DETAILS_MATH_CAST_HPP 00026 00027 namespace ivl { 00028 00029 // ... unfortunately here we need forward declarations 00030 template <class J, class K> class cast_class; 00031 00032 template<class R, template<typename, typename> class F, class A> 00033 struct unary_elem_func_result; 00034 00035 /* TODO: this was there. uncomment to play. 00036 template<class R, class A> 00037 inline 00038 typename unary_elem_func_result< 00039 typename types::get_value<R>::type, cast_class, A>::type cast(const A& in); 00040 */ 00041 // ... 00042 /* 00043 template<class R, class A> 00044 inline 00045 typename unary_elem_func_result< 00046 typename types::get_value<R>::type, cast_class, A>::type cast(const A& in); 00047 */ 00048 00049 template<class R, class A> 00050 inline 00051 typename unary_elem_func_result< 00052 typename types::change_data_class_set_rec<data::fixed<1>, R>::type, 00053 cast_class, A>::type cast(const A& in); 00054 00055 00056 namespace math { 00057 namespace math_details { 00058 00059 // ----------------------------------------------------------- 00060 00061 template <class T, bool BUILTIN> 00062 struct spec_cast_complex_initializer { }; 00063 00064 // converting an integer or floating-point type to complex requires .real() 00065 template <class T> 00066 struct spec_cast_complex_initializer<T, true> 00067 { 00068 template <class S> 00069 static inline S from(const std::complex<S>& x) { return x.real(); } 00070 }; 00071 00072 // any other type should be implicitly converted if conversion is supported. 00073 template <class T> 00074 struct spec_cast_complex_initializer<T, false> 00075 { 00076 template <class S> 00077 static inline const std::complex<S>& from(const std::complex<S>& x) 00078 { return x; } 00079 }; 00080 00081 // conversion of complex to non-complex, not bool type, requires specialization 00082 template <class T> 00083 struct cast_complex_initializer 00084 : public spec_cast_complex_initializer<T, types::is_builtin<T>::value> 00085 { 00086 }; 00087 00088 // conversion of complex to bool returns true if .real() or .imag() is != 0 00089 template <> 00090 struct cast_complex_initializer<bool> 00091 { 00092 template <class S> 00093 static inline bool from(const std::complex<S>& x) 00094 { return x.real() || x.imag(); } 00095 }; 00096 00097 // ----------------------------------------------------------- 00098 00099 template <class T> 00100 struct cast_initializer : public cast_complex_initializer<T> 00101 { 00102 using cast_complex_initializer<T>::from; 00103 00104 template <class S> 00105 static inline const S& from(const S& x) { return x; } 00106 }; 00107 00108 template <class T> 00109 struct cast_initializer<std::complex<T> > 00110 { 00111 template <class S> 00112 static inline T from(const S& x) { return T(x); } 00113 00114 template <class S> 00115 static inline std::complex<T> from(const std::complex<S>& x) 00116 { return std::complex<T>(T(x.real()), T(x.imag())); } 00117 }; 00118 00119 // ----------------------------------------------------------- 00120 00121 } /* namespace math_details */ 00122 00123 template <class T, class S> 00124 inline 00125 T cast(const S& x) 00126 { 00127 return T(math_details::cast_initializer<T>::from(x)); 00128 } 00129 00130 // ----------------------------------------------------------- 00131 00132 namespace math_details { 00133 00134 template <class T, bool IS_ARRAY> 00135 struct spec_elem_cast_result 00136 { 00137 }; 00138 00139 template <class T> 00140 struct spec_elem_cast_result<T, false> 00141 { 00142 typedef T type; 00143 typedef T elem_type; 00144 template <class S> 00145 inline type from(const S& x) 00146 { 00147 return type(math_details::cast_initializer<T>::from(x)); 00148 } 00149 }; 00150 00151 template <class A> 00152 struct spec_elem_cast_result<A, true> 00153 { 00154 typedef typename A::derived_type type; 00155 typedef typename A::elem_type elem_type; 00156 template <class S> 00157 inline type from(const S& x) 00158 { 00159 // note: need to have ivl::cast predeclared. 00160 // (which is defined in unary_elem_functions) 00161 return type(ivl::cast<elem_type>(x)); 00162 } 00163 }; 00164 00165 /* 00166 // on : todo. 00167 // also decide like array<int> = array<double>; 00168 00169 template<class T> 00170 struct elem_cast_result 00171 : public spec_elem_cast_result<T, types::is_array<T>::value> 00172 { 00173 }; 00174 */ 00175 00176 } /* namespace math_details */ 00177 00178 /* 00179 // same as cast for simple elements 00180 template <class T, class S> 00181 inline 00182 typename types_details::elem_cast_result<T>::type elem_cast(const S& x) 00183 { 00184 return types_details::elem_cast_result<T>::from(x); 00185 } 00186 */ 00187 00188 00189 } /* namespace math */ 00190 } /* namespace ivl */ 00191 00192 #endif // IVL_CORE_DETAILS_MATH_CAST_HPP