ivl 679
ivl/details/core/types/evolution.hpp
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations