ICRS Eurobot 2013
Dependencies: mbed mbed-rtos Servo QEI
TypePromotion.h
00001 /* 00002 * Tiny Vector Matrix Library 00003 * Dense Vector Matrix Libary of Tiny size using Expression Templates 00004 * 00005 * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net> 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 * 00021 * $Id: TypePromotion.h,v 1.10 2007-06-23 15:58:58 opetzold Exp $ 00022 */ 00023 00024 #ifndef TVMET_TYPE_PROMOTION_H 00025 #define TVMET_TYPE_PROMOTION_H 00026 00027 namespace tvmet { 00028 00029 00030 /** 00031 * \class PrecisionTraits TypePromotion.h "tvmet/TypePromotion.h" 00032 * \brief Declaring ranks of types to avoid specializing 00033 * 00034 * All possible promoted types. For example, bool=1, int=2, float=3, double=4, 00035 * etc. We can use a traits class to map from a type such as float onto its 00036 * "precision rank". We will promote to whichever type has a higher 00037 * "precision rank". f there is no "precision rank" for a type, we'll 00038 * promote to whichever type requires more storage space 00039 * (and hopefully more precision). 00040 */ 00041 template<class T> 00042 struct PrecisionTraits { 00043 enum { 00044 rank = 0, /**< the rank of type. */ 00045 known = 0 /**< true, if the rank is specialized = known. */ 00046 }; 00047 }; 00048 00049 00050 #define TVMET_PRECISION(T,R) \ 00051 template<> \ 00052 struct PrecisionTraits< T > { \ 00053 enum { \ 00054 rank = R, \ 00055 known = 1 \ 00056 }; \ 00057 }; 00058 00059 00060 /* 00061 * pod types 00062 */ 00063 TVMET_PRECISION(int, 100) 00064 TVMET_PRECISION(unsigned int, 200) 00065 TVMET_PRECISION(long, 300) 00066 TVMET_PRECISION(unsigned long, 400) 00067 00068 #if defined(TVMET_HAVE_LONG_LONG) 00069 TVMET_PRECISION(long long, 500) 00070 TVMET_PRECISION(unsigned long long, 600) 00071 #endif // defined(TVMET_HAVE_LONG_LONG) 00072 00073 TVMET_PRECISION(float, 700) 00074 TVMET_PRECISION(double, 800) 00075 00076 #if defined(TVMET_HAVE_LONG_DOUBLE) 00077 TVMET_PRECISION(long double, 900) 00078 #endif // defined(TVMET_HAVE_LONG_DOUBLE) 00079 00080 00081 /* 00082 * complex types 00083 */ 00084 #if defined(TVMET_HAVE_COMPLEX) 00085 TVMET_PRECISION(std::complex<int>, 1000) 00086 TVMET_PRECISION(std::complex<unsigned int>, 1100) 00087 TVMET_PRECISION(std::complex<long>, 1200) 00088 TVMET_PRECISION(std::complex<unsigned long>, 1300) 00089 00090 #if defined(TVMET_HAVE_LONG_LONG) 00091 TVMET_PRECISION(std::complex<long long>, 1400) 00092 TVMET_PRECISION(std::complex<unsigned long long>, 1500) 00093 #endif // defined(TVMET_HAVE_LONG_LONG) 00094 00095 TVMET_PRECISION(std::complex<float>, 1600) 00096 TVMET_PRECISION(std::complex<double>, 1700) 00097 00098 #if defined(TVMET_HAVE_LONG_DOUBLE) 00099 TVMET_PRECISION(std::complex<long double>, 1800) 00100 #endif // defined(TVMET_HAVE_LONG_DOUBLE) 00101 00102 #endif // defined(TVMET_HAVE_COMPLEX) 00103 00104 00105 /** \class PrecisionTraits<int> TypePromotion.h "tvmet/TypePromotion.h" */ 00106 /** \class PrecisionTraits<unsigned int> TypePromotion.h "tvmet/TypePromotion.h" */ 00107 /** \class PrecisionTraits<long> TypePromotion.h "tvmet/TypePromotion.h" */ 00108 /** \class PrecisionTraits<unsigned long> TypePromotion.h "tvmet/TypePromotion.h" */ 00109 /** \class PrecisionTraits<long long> TypePromotion.h "tvmet/TypePromotion.h" */ 00110 /** \class PrecisionTraits<unsigned long long> TypePromotion.h "tvmet/TypePromotion.h" */ 00111 /** \class PrecisionTraits<float> TypePromotion.h "tvmet/TypePromotion.h" */ 00112 /** \class PrecisionTraits<double> TypePromotion.h "tvmet/TypePromotion.h" */ 00113 /** \class PrecisionTraits<long double> TypePromotion.h "tvmet/TypePromotion.h" */ 00114 /** \class PrecisionTraits< std::complex<int> > TypePromotion.h "tvmet/TypePromotion.h" */ 00115 /** \class PrecisionTraits< std::complex<unsigned int> > TypePromotion.h "tvmet/TypePromotion.h" */ 00116 /** \class PrecisionTraits< std::complex<long> > TypePromotion.h "tvmet/TypePromotion.h" */ 00117 /** \class PrecisionTraits< std::complex<unsigned long> > TypePromotion.h "tvmet/TypePromotion.h" */ 00118 /** \class PrecisionTraits< std::complex<long long> > TypePromotion.h "tvmet/TypePromotion.h" */ 00119 /** \class PrecisionTraits< std::complex<unsigned long long> > TypePromotion.h "tvmet/TypePromotion.h" */ 00120 /** \class PrecisionTraits< std::complex<float> > TypePromotion.h "tvmet/TypePromotion.h" */ 00121 /** \class PrecisionTraits< std::complex<double> > TypePromotion.h "tvmet/TypePromotion.h" */ 00122 /** \class PrecisionTraits< std::complex<long double> > TypePromotion.h "tvmet/TypePromotion.h" */ 00123 00124 #undef TVMET_PRECISION 00125 00126 00127 /** 00128 * \class AutopromoteTraits TypePromotion.h "tvmet/TypePromotion.h" 00129 * \brief The promoted types traits. 00130 */ 00131 template<class T> 00132 struct AutopromoteTraits { 00133 typedef T value_type; 00134 }; 00135 00136 00137 /* 00138 * Defines a macro for specializing/defining 00139 * the promotion traits. bool, char, unsigned char, short int, etc. will 00140 * be autopromote to int, as in C and C++. 00141 */ 00142 #define TVMET_AUTOPROMOTE(T1,T2) \ 00143 template<> \ 00144 struct AutopromoteTraits<T1> { \ 00145 typedef T2 value_type; \ 00146 }; 00147 00148 TVMET_AUTOPROMOTE(bool, int) 00149 TVMET_AUTOPROMOTE(char, int) 00150 TVMET_AUTOPROMOTE(unsigned char, int) 00151 TVMET_AUTOPROMOTE(short int, int) 00152 TVMET_AUTOPROMOTE(short unsigned int, unsigned int) 00153 00154 /** \class AutopromoteTraits<bool> TypePromotion.h "tvmet/TypePromotion.h" */ 00155 /** \class AutopromoteTraits<char> TypePromotion.h "tvmet/TypePromotion.h" */ 00156 /** \class AutopromoteTraits<unsigned char> TypePromotion.h "tvmet/TypePromotion.h" */ 00157 /** \class AutopromoteTraits<short int> TypePromotion.h "tvmet/TypePromotion.h" */ 00158 /** \class AutopromoteTraits<short unsigned int> TypePromotion.h "tvmet/TypePromotion.h" */ 00159 00160 #undef TVMET_AUTOPROMOTE 00161 00162 00163 /** 00164 * \class promoteTo TypePromotion.h "tvmet/TypePromotion.h" 00165 * \brief Promote to T1. 00166 */ 00167 template<class T1, class T2, int promoteToT1> 00168 struct promoteTo { 00169 typedef T1 value_type; 00170 }; 00171 00172 00173 /** 00174 * \class promoteTo<T1,T2,0> TypePromotion.h "tvmet/TypePromotion.h" 00175 * \brief Promote to T2 00176 */ 00177 template<class T1, class T2> 00178 struct promoteTo<T1,T2,0> { 00179 typedef T2 value_type; 00180 }; 00181 00182 00183 /** 00184 * \class PromoteTraits TypePromotion.h "tvmet/TypePromotion.h" 00185 * \brief Promote type traits 00186 */ 00187 template<class T1org, class T2org> 00188 class PromoteTraits { 00189 // Handle promotion of small integers to int/unsigned int 00190 typedef typename AutopromoteTraits<T1org>::value_type T1; 00191 typedef typename AutopromoteTraits<T2org>::value_type T2; 00192 00193 enum { 00194 // True if T1 is higher ranked 00195 T1IsBetter = int(PrecisionTraits<T1>::rank) > int(PrecisionTraits<T2>::rank), 00196 00197 // True if we know ranks for both T1 and T2 00198 knowBothRanks = PrecisionTraits<T1>::known && PrecisionTraits<T2>::known, 00199 00200 // True if we know T1 but not T2 00201 knowT1butNotT2 = PrecisionTraits<T1>::known && !(PrecisionTraits<T2>::known), 00202 00203 // True if we know T2 but not T1 00204 knowT2butNotT1 = PrecisionTraits<T2>::known && !(PrecisionTraits<T1>::known), 00205 00206 // True if T1 is bigger than T2 00207 T1IsLarger = sizeof(T1) >= sizeof(T2), 00208 00209 // We know T1 but not T2: true 00210 // We know T2 but not T1: false 00211 // Otherwise, if T1 is bigger than T2: true 00212 defaultPromotion = knowT1butNotT2 ? false : (knowT2butNotT1 ? true : T1IsLarger), 00213 00214 // If we have both ranks, then use them. 00215 // If we have only one rank, then use the unknown type. 00216 // If we have neither rank, then promote to the larger type. 00217 promoteToT1 = (knowBothRanks ? T1IsBetter : defaultPromotion) ? 1 : 0 00218 }; 00219 00220 public: 00221 typedef typename promoteTo<T1,T2,promoteToT1>::value_type value_type; 00222 }; 00223 00224 00225 } // namespace tvmet 00226 00227 #endif // TVMET_TYPE_PROMOTION_H 00228 00229 // Local Variables: 00230 // mode:C++ 00231 // tab-width:8 00232 // End:
Generated on Wed Jul 13 2022 18:28:37 by 1.7.2