last update 20 Sep 2009 |
00001 /* 00002 * Copyright (C) 1998-2004 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * 00006 * This file is part of the Computer Vision and Robotics Library (CVR-Lib) 00007 * 00008 * The CVR-Lib is free software; you can redistribute it and/or 00009 * modify it under the terms of the BSD License. 00010 * 00011 * All rights reserved. 00012 * 00013 * Redistribution and use in source and binary forms, with or without 00014 * modification, are permitted provided that the following conditions are met: 00015 * 00016 * 1. Redistributions of source code must retain the above copyright notice, 00017 * this list of conditions and the following disclaimer. 00018 * 00019 * 2. Redistributions in binary form must reproduce the above copyright notice, 00020 * this list of conditions and the following disclaimer in the documentation 00021 * and/or other materials provided with the distribution. 00022 * 00023 * 3. Neither the name of the authors nor the names of its contributors may be 00024 * used to endorse or promote products derived from this software without 00025 * specific prior written permission. 00026 * 00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00028 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00029 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00030 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00031 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00032 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00033 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00034 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00035 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00036 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00037 * POSSIBILITY OF SUCH DAMAGE. 00038 */ 00039 00040 00041 00042 /** 00043 * \file cvrTypeInfo.h 00044 * Definition of some template functions that give information 00045 * about its template type. 00046 * \author Pablo Alvarado 00047 * \date 16.05.2001 00048 * 00049 * $Id: cvrTypeInfo.h,v 1.6 2007/10/14 20:25:38 alvarado Exp $ 00050 */ 00051 00052 #ifndef _CVR_TYPE_INFO_H_ 00053 #define _CVR_TYPE_INFO_H_ 00054 00055 #include "cvrTypes.h" 00056 #include "cvrClassName.h" 00057 #include <limits> 00058 #include <typeinfo> 00059 00060 // Visual define these as macros 00061 #undef min 00062 #undef max 00063 00064 namespace cvr { 00065 00066 /** 00067 * This class allows to ask some information required in the 00068 * CVR-Libfor some types. 00069 * Note that the members are static, and you do not need any 00070 * instance of the class to get the type information. 00071 * 00072 * For more information about a type you can also use the 00073 * std::numeric_limits type of the Standard Template Library. 00074 * 00075 * Example: 00076 * \code 00077 * if (typeInfo<dreal>::isFloatingPointType()) { 00078 * cout << "dreal is a floating point type" << endl; 00079 * } else { 00080 * cout << "this is a really weird case!" << endl; 00081 * } 00082 * \endcode 00083 */ 00084 template<class T> 00085 class typeInfo { 00086 public: 00087 /** 00088 * Alias for contained type. 00089 * 00090 * For usual C++ types (int, float, etc.), this is exactly as T, but 00091 * for compound type (complex<T>, point<T>, etc.) this corresponds to the 00092 * type of the components 00093 */ 00094 typedef T value_type; 00095 00096 /** 00097 * Type suggested for accumulation of current type elements 00098 * (for example int for ubyte). 00099 */ 00100 typedef T accumulation_type; 00101 00102 /** 00103 * Type suggested to accumulate the square of values of the current 00104 * type 00105 */ 00106 typedef T square_accumulation_type; 00107 00108 /** 00109 * Suggest a norm for the given type. 00110 * Usually 255 is used for ubyte, 127 for byte, 65535 for all other 00111 * integer types and 1.0 for the floating point types. 00112 */ 00113 static T suggestedNorm() throw() {return 65535;} 00114 00115 /** 00116 * Return true if the type T is a floating point type. 00117 */ 00118 static bool isFloatingPointType() throw() {return false;} 00119 00120 /** 00121 * Return a const char* with the name of the type 00122 */ 00123 static const char* name() throw() {return "";} 00124 00125 /** 00126 * The difference of this minimum with the std::numeric_limits<T>::min() is 00127 * that here the minimum value is returned for floating point types and 00128 * fixed point types. The STL method returns for floating point values 00129 * the minimal representable value above zero. For max() you can use 00130 * the standard version 00131 */ 00132 static T min() throw() {return std::numeric_limits<T>::min();} 00133 00134 private: 00135 /** 00136 * Disable creation of instances of this class. 00137 */ 00138 typeInfo() {}; 00139 }; 00140 00141 // ------------------------ 00142 // template specializations 00143 // ------------------------ 00144 00145 template<> 00146 class typeInfo<ubyte> { 00147 public: 00148 typedef ubyte value_type; 00149 typedef int32 accumulation_type; 00150 typedef int32 square_accumulation_type; 00151 static ubyte suggestedNorm() throw() {return 255;} 00152 static bool isFloatingPointType() throw() {return false;} 00153 static const char* name() throw() {return "cvr::ubyte";}; 00154 static ubyte min() throw() {return std::numeric_limits<ubyte>::min();} 00155 private: 00156 typeInfo() {}; 00157 }; 00158 00159 template<> 00160 class typeInfo<byte> { 00161 public: 00162 typedef byte value_type; 00163 typedef int32 accumulation_type; 00164 typedef int32 square_accumulation_type; 00165 static byte suggestedNorm() throw() {return 127;} 00166 static bool isFloatingPointType() throw() {return false;} 00167 static const char* name() throw() {return "cvr::byte";} 00168 static byte min() throw() {return std::numeric_limits<byte>::min();} 00169 private: 00170 typeInfo() {}; 00171 }; 00172 00173 template<> 00174 class typeInfo<int16> { 00175 public: 00176 typedef int16 value_type; 00177 typedef int32 accumulation_type; 00178 typedef dreal square_accumulation_type; 00179 static int16 suggestedNorm() throw() {return 255;} 00180 static bool isFloatingPointType() throw() {return false;} 00181 static const char* name() throw() {return "cvr::int16";} 00182 static short int min() throw() { 00183 return std::numeric_limits<int16>::min(); 00184 } 00185 private: 00186 typeInfo() {}; 00187 }; 00188 00189 template<> 00190 class typeInfo<uint16> { 00191 public: 00192 typedef uint16 value_type; 00193 typedef int32 accumulation_type; 00194 typedef dreal square_accumulation_type; 00195 static uint16 suggestedNorm() throw() {return 255;} 00196 static bool isFloatingPointType() throw() {return false;} 00197 static const char* name() throw() {return "cvr::uint16";} 00198 static uint16 min() throw() { 00199 return std::numeric_limits<uint16>::min(); 00200 } 00201 private: 00202 typeInfo() {}; 00203 }; 00204 00205 template<> 00206 class typeInfo<int32> { 00207 public: 00208 typedef int32 value_type; 00209 typedef int32 accumulation_type; 00210 typedef dreal square_accumulation_type; 00211 static int32 suggestedNorm() throw() {return 65535;} 00212 static bool isFloatingPointType() throw() {return false;} 00213 static const char* name() throw() {return "cvr::int32";} 00214 static int32 min() throw() {return std::numeric_limits<int32>::min();} 00215 private: 00216 typeInfo() {}; 00217 }; 00218 00219 template<> 00220 class typeInfo<uint32> { 00221 public: 00222 typedef uint32 value_type; 00223 typedef int32 accumulation_type; 00224 typedef dreal square_accumulation_type; 00225 static uint32 suggestedNorm() throw() {return 65535;} 00226 static bool isFloatingPointType() throw() {return false;} 00227 static const char* name() throw() {return "cvr::uint32";} 00228 static uint32 min() throw() { 00229 return std::numeric_limits<uint32>::min(); 00230 } 00231 private: 00232 typeInfo() {}; 00233 }; 00234 00235 template<> 00236 class typeInfo<sreal> { 00237 public: 00238 typedef sreal value_type; 00239 typedef sreal accumulation_type; 00240 typedef dreal square_accumulation_type; 00241 static sreal suggestedNorm() throw() {return static_cast<sreal>(1);} 00242 static bool isFloatingPointType() throw() {return true;} 00243 static const char* name() throw() {return "cvr::sreal";}; 00244 static float min() throw() {return -std::numeric_limits<sreal>::max();} 00245 private: 00246 typeInfo() {}; 00247 }; 00248 00249 template<> 00250 class typeInfo<dreal> { 00251 public: 00252 typedef dreal value_type; 00253 typedef dreal accumulation_type; 00254 typedef dreal square_accumulation_type; 00255 static dreal suggestedNorm() throw() {return static_cast<dreal>(1);} 00256 static bool isFloatingPointType() throw() {return true;} 00257 static const char* name() throw() {return "cvr::dreal";}; 00258 static dreal min() throw() {return -std::numeric_limits<dreal>::max();} 00259 private: 00260 typeInfo() {}; 00261 }; 00262 00263 /** 00264 * This tricky specialization lets the typeInfo of any template class with a 00265 * single template parameter make use of the typeInfo of its template 00266 * parameter. 00267 */ 00268 template<typename T, template <class> class U> 00269 class typeInfo< U<T> > { 00270 public: 00271 typedef typename typeInfo<T>::value_type value_type; 00272 typedef U< typename typeInfo<T>::accumulation_type > accumulation_type; 00273 typedef U< typename typeInfo<T>::square_accumulation_type > 00274 square_accumulation_type; 00275 00276 // Let us hope that this trick way works in all cases: 00277 static U<T> suggestedNorm() throw() { 00278 return U<T>(typeInfo<T>::suggestedNorm()); 00279 } 00280 00281 // no container is a pure floating point type! 00282 static bool isFloatingPointType() throw() {return false;} 00283 00284 // 00285 static const char* name() throw() { 00286 static const std::string theName = 00287 className::demangle(typeid(U<T>()).name()); 00288 return theName.c_str(); 00289 } 00290 00291 // this class has no minimum, as it does not make much sense here. 00292 private: 00293 typeInfo() {}; 00294 }; 00295 } 00296 00297 #endif 00298