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_TYPES_EVOLUTION 00025 #define IVL_CORE_DETAILS_TYPES_EVOLUTION 00026 00027 namespace ivl { 00028 namespace types { 00029 00030 00031 /* These structs allow the compile-time translation from one 00032 * template type to another. Or otherwise said, they perform 00033 ** type promotion for template types */ 00034 00035 //-------------------------------------------------------------- 00036 00037 // -------------------------- TODO : style ------------- 00038 00039 //-------------------------------------------------------------- 00040 00041 00052 template <class KEY, class FROM = bool> struct to_type 00053 { 00054 typedef KEY type; 00055 }; 00056 00057 template <class KEY> 00058 struct to_type<KEY, term> 00059 { 00060 typedef term type; 00061 }; 00062 00063 template <class KEY, template<typename> class D, class T> 00064 struct to_type<KEY, D<T> > 00065 { 00066 typedef D<KEY> type; 00067 }; 00068 00069 // spec param class 00070 // todo: make a is_ivl_array check to further specialize 00071 template <class KEY, template<typename, typename> class D, class T, class DS> 00072 struct to_type<KEY, D<T, DS> > 00073 { 00074 typedef D<KEY, typename DS::template change_derived_param< 00075 typename to_type<KEY, typename DS::derived_param>::type>::type> type; 00076 }; 00077 00078 // note: to_type should only be used for creating new types, which will have 'term' as DERINFO 00079 // any other intermediate types would be illegal, since directly casting one class from one type 00080 // to another type of elements is an unsupported practice. 00081 // A reinterpret cast should take care to not only cast the D<T, ..> to D<KEY, ..> but also 00082 // D<T, A, DERINFO> type; to D<T, A, typename to_type<KEY, DERINFO>::type > type; 00083 00084 //-------------------------------------------------------------- 00085 00086 00087 template <class X> struct to_bool : public to_type<bool, X> {}; 00088 00130 template <class T> struct promote : public 00131 t_if<is_ivl_array<T>, 00132 to_type<typename promote<typename subtype<T>::type>::type, T>, 00133 to_type<T> >::type { }; 00134 00135 template<> struct promote<term> { typedef bool type; }; 00136 00137 #include "platform_specific/promote_int_impl.hpp" 00138 00139 template <class Z> struct promote<std::complex<Z> > : 00140 public to_type<typename std::complex<typename promote<Z>::type> > { }; 00141 00149 template <class T> struct to_real : public 00150 t_if<is_ivl_array<T>, 00151 to_type<typename to_real<typename subtype<T>::type>::type, T>, 00152 to_type<T> >::type { }; 00153 00154 template<> struct to_real<term> { typedef bool type; }; 00155 00156 template<class T> 00157 struct to_real<std::complex<T> > : public to_type<T> { }; 00158 00166 template <class T> struct to_complex : public 00167 t_if<is_ivl_array<T>, 00168 to_type<typename to_complex<typename subtype<T>::type>::type, T>, 00169 to_type<std::complex<T> > >::type { }; 00170 00171 template<> struct to_complex<term> { typedef bool type; }; 00172 00173 template<class T> 00174 struct to_complex<std::complex<T> > : public to_type<std::complex<T> > { }; 00175 00180 template <class T> struct to_floating : public 00181 t_if<is_ivl_array<T>, 00182 to_type<typename to_floating<typename subtype<T>::type>::type, T>, 00183 to_type<double> >::type { }; 00184 00185 template<> struct to_floating<term> { typedef bool type; }; 00186 00187 template<> 00188 struct to_floating<float> : public to_type<float> { }; 00189 00190 template <class Z> struct to_floating<std::complex<Z> > : 00191 public to_type<std::complex<typename to_floating<Z>::type> > { }; 00192 00197 template <class T> struct to_real_floating : public 00198 t_if<is_ivl_array<T>, 00199 to_type<typename to_real_floating<typename 00200 subtype<T>::type>::type, T>, 00201 to_type<double> >::type { }; 00202 00203 template<> struct to_real_floating<term> { typedef bool type; }; 00204 00205 template<> 00206 struct to_real_floating<float> : public to_type<float> { }; 00207 00208 template <class Z> struct to_real_floating<std::complex<Z> > : 00209 public to_real_floating<Z> { }; 00210 00215 template <class T> struct to_signed : public 00216 t_if<is_ivl_array<T>, 00217 to_type<typename to_signed<typename 00218 subtype<T>::type>::type, T>, 00219 to_type<int> >::type { }; 00220 00221 template<> struct to_signed<term> { typedef bool type; }; 00222 00223 template <> 00224 struct to_signed<float> : public to_type<float> { }; 00225 00226 template <> 00227 struct to_signed<double> : public to_type<double> { }; 00228 00229 template <class Z> struct to_signed<std::complex<Z> > : 00230 public to_type<std::complex<typename to_signed<Z>::type> > { }; 00231 00236 template <class T> struct to_unsigned : public 00237 t_if<is_ivl_array<T>, 00238 to_type<typename to_unsigned<typename 00239 subtype<T>::type>::type, T>, 00240 to_type<unsigned> >::type { }; 00241 00242 template<> struct to_unsigned<term> { typedef bool type; }; 00243 00244 template <> 00245 struct to_unsigned<float> : public to_type<float> { }; 00246 00247 template <> 00248 struct to_unsigned<double> : public to_type<double> { }; 00249 00250 template <class Z> struct to_unsigned<std::complex<Z> > : 00251 public to_type<std::complex<typename to_unsigned<Z>::type> > { }; 00252 00253 #include "platform_specific/signed_impl.hpp" 00254 00255 } /* namespace types */ 00256 } /* namespace ivl */ 00257 00258 #endif // IVL_CORE_DETAILS_TYPES_EVOLUTION