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 00031 #ifndef IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP 00032 #define IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP 00033 00034 // Macros are be used only because this file is full of repeated definitions. 00035 // they are undefined after the definitions are made. Therefore they are 00036 // temporary and they do not affect the developpers code who include ivl. 00037 #ifdef UD 00038 #define IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UD UD 00039 #undef UD 00040 #endif 00041 #ifdef UD_AR 00042 #define IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UD_AR UD_AR 00043 #undef UD_AR 00044 #endif 00045 #ifdef UO 00046 #define IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UO UO 00047 #undef UO 00048 #endif 00049 #ifdef UO_AR 00050 #define IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UO_AR UO_AR 00051 #undef UO_AR 00052 #endif 00053 00054 namespace ivl { 00055 00062 namespace array_details { 00063 00064 template <class T, class J, class T_IS_IVL_ARRAY> 00065 struct cast_class_details { }; 00066 00067 // allows cast to create arrays with 1 element instead of elements. 00068 // this may be helpful for changing the structure type of some arrays 00069 template <class T, class J> 00070 struct cast_class_details<T, J, types::t_true> 00071 { 00072 typedef types::number<12> cost; 00073 static inline T elem_op(const J& elem1) 00074 { 00075 return T(1, math::cast<typename T::elem_type>(elem1)); 00076 } 00077 }; 00078 00079 template <class T, class J> 00080 struct cast_class_details<T, J, types::t_false> 00081 { 00082 typedef types::number<2> cost; 00083 static inline T elem_op(const J& elem1) 00084 { 00085 return math::cast<T>(elem1); 00086 } 00087 }; 00088 00089 } /* namespace array_details */ 00090 00091 template<class T, class J> 00092 struct cast_class 00093 : public array_details::cast_class_details<T, J, typename 00094 types::is_ivl_array<T>::type> 00095 { 00096 }; 00097 00098 template<class R, class A> 00099 inline 00100 typename unary_elem_func_result< 00101 typename types::change_data_class_set_rec<data::fixed<1>, R>::type, 00102 cast_class, A>::type cast(const A& in) 00103 { 00104 return unary_elem_func_result< 00105 typename types::change_data_class_set_rec<data::fixed<1>, R>::type, 00106 cast_class, A>::from(in); 00107 } 00108 00109 00110 /* 00111 template<class T, class S> 00112 struct cast_class 00113 { 00114 static inline T elem_op(const S& elem) { return cast<T>(elem); }; 00115 }; 00116 00118 template<class R, class T, class S, class K> 00119 inline 00120 elem_func_unary<R, cast_class, array<T, S, K> > cast(const array<T, S, K>& a) 00121 { 00122 return elem_func_unary<R, cast_class, array<T, S, K> >(a); 00123 }; 00124 */ 00125 00126 00127 #define UD(rtype, name, costval) \ 00128 \ 00129 template<class T, class J> \ 00130 struct name ## _unary_class \ 00131 { \ 00132 typedef types::number<costval> cost; \ 00133 typedef typename types::t_if<types::t_eq<rtype, types::term>, \ 00134 J, rtype>::type default_ret_type; \ 00135 typedef typename types::t_if<types::t_eq<T, types::term>, \ 00136 default_ret_type, T>::type func_ret_type; \ 00137 static inline func_ret_type elem_op(const J& elem1) \ 00138 { \ 00139 return math::name(elem1); \ 00140 } \ 00141 }; \ 00142 \ 00143 template<class A> \ 00144 inline \ 00145 typename unary_elem_func_result< \ 00146 typename name ## _unary_class< \ 00147 types::term, typename types::get_value<A>::type>\ 00148 ::default_ret_type, \ 00149 name ## _unary_class, A>::type name( \ 00150 const A& in) \ 00151 { \ 00152 return unary_elem_func_result< \ 00153 typename name ## _unary_class< \ 00154 types::term, typename types::get_value<A>::type>\ 00155 ::default_ret_type, \ 00156 name ## _unary_class, A>::from(in); \ 00157 } 00158 00159 00160 #define UD_AR(rtype, name, costval) \ 00161 \ 00162 template<class T, class J> \ 00163 struct name ## _unary_class \ 00164 { \ 00165 typedef types::number<costval> cost; \ 00166 typedef typename types::t_if<types::t_eq<rtype, types::term>, \ 00167 J, rtype>::type default_ret_type; \ 00168 typedef typename types::t_if<types::t_eq<T, types::term>, \ 00169 default_ret_type, T>::type func_ret_type; \ 00170 static inline func_ret_type elem_op(const J& elem1) \ 00171 { \ 00172 return math::name(elem1); \ 00173 } \ 00174 }; \ 00175 \ 00176 template<class A> \ 00177 inline \ 00178 typename unary_elem_func_result< \ 00179 typename name ## _unary_class< \ 00180 types::term, typename types::get_value<A>::type>\ 00181 ::default_ret_type, \ 00182 name ## _unary_class, A>::type name( \ 00183 const array_common_base<A>& in) \ 00184 { \ 00185 return unary_elem_func_result< \ 00186 typename name ## _unary_class< \ 00187 types::term, typename types::get_value<A>::type>\ 00188 ::default_ret_type, \ 00189 name ## _unary_class, A>::from(in.to_current());\ 00190 } 00191 00192 00193 #define UO(oper, name) \ 00194 \ 00195 template <class A> \ 00196 inline \ 00197 typename unary_elem_func_result< \ 00198 typename name ## _unary_class< \ 00199 types::term, typename types::get_value<A>::type>\ 00200 ::default_ret_type, \ 00201 name ## _unary_class, A>::type operator oper ( \ 00202 const A& in) \ 00203 { \ 00204 return unary_elem_func_result< \ 00205 typename name ## _unary_class< \ 00206 types::term, typename types::get_value<A>::type>\ 00207 ::default_ret_type, \ 00208 name ## _unary_class, A>::from(in); \ 00209 } \ 00210 00211 #define UO_AR(oper, name) \ 00212 \ 00213 template <class T, class S, class K> \ 00214 inline \ 00215 typename unary_elem_func_result< \ 00216 typename name ## _unary_class< \ 00217 types::term, T>\ 00218 ::default_ret_type, \ 00219 name ## _unary_class, array<T, S, K> >::type \ 00220 operator oper ( \ 00221 const ivl::array<T, S, K>& in) \ 00222 { \ 00223 return unary_elem_func_result< \ 00224 typename name ## _unary_class< \ 00225 types::term, T>\ 00226 ::default_ret_type, \ 00227 name ## _unary_class, array<T, S, K> >::from(in);\ 00228 } \ 00229 00230 00231 // definitions for unary elem functions: 00232 00233 UD(J, uminus, 7) 00234 UD(J, uplus, 1) 00235 UD(J, bitcmp, 7) 00236 UD(bool, cnot, 7) 00237 00238 // dereference operator, only for arrays (not for other types) 00239 UD(typename types::deref_ptr<J>::type, dereference, 7) 00240 00241 00242 // trigonometric 00243 UD(J, cos, 150) 00244 UD(J, sin, 150) 00245 UD(J, tan, 150) 00246 UD(J, cosh, 150) 00247 UD(J, sinh, 150) 00248 UD(J, tanh, 150) 00249 UD(J, acos, 150) 00250 UD(J, asin, 150) 00251 UD(J, atan, 150) 00252 UD(J, acosh, 150) 00253 UD(J, asinh, 150) 00254 UD(J, atanh, 150) 00255 UD(J, cot, 150) 00256 UD(J, csc, 150) 00257 UD(J, sec, 150) 00258 UD(J, coth, 150) 00259 UD(J, csch, 150) 00260 UD(J, sech, 150) 00261 UD(J, acot, 150) 00262 UD(J, acsc, 150) 00263 UD(J, asec, 150) 00264 UD(J, acoth, 150) 00265 UD(J, acsch, 150) 00266 UD(J, asech, 150) 00267 00268 // unary functions 00269 UD(int, isinf, 12) 00270 UD(int, isnan, 12) 00271 UD(J, sign, 12) 00272 00273 UD(J, abs, 30) 00274 UD(J, sqrt, 120) 00275 UD(J, exp, 120) 00276 UD(J, floor, 40) 00277 UD(J, ceil, 40) 00278 UD(J, round, 40) 00279 UD(J, conj, 40) 00280 UD(J, sqr, 40) 00281 00282 UD(typename types::to_real<J>::type, angle, 150) 00283 00284 UD(J, fix, 150) 00285 UD(J, log, 150) 00286 UD(J, log2, 150) 00287 UD(J, log10, 150) 00288 UD(J, ln, 150) 00289 UD(J, nextpow2, 150) 00290 00291 00292 } // namespace ivl 00293 00294 #undef UD 00295 #undef UD_AR 00296 #undef UO 00297 #undef UO_AR 00298 00299 #ifdef IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UD_AR 00300 #define UD_AR IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UD_AR 00301 #undef IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UD_AR 00302 #endif 00303 #ifdef IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UD 00304 #define UD IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UD 00305 #undef IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UD 00306 #endif 00307 #ifdef IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UO 00308 #define UO IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UO 00309 #undef IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UO 00310 #endif 00311 #ifdef IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UO_AR 00312 #define UO_AR IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UO_AR 00313 #undef IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP_SAVE_UO_AR 00314 #endif 00315 00316 #endif // IVL_ARRAY_DETAILS_UNARY_ELEMENT_FUNCTIONS_HPP