📄 macros.hpp
字号:
/* * Open BEAGLE * Copyright (C) 2001-2005 by Christian Gagne and Marc Parizeau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact: * Laboratoire de Vision et Systemes Numeriques * Departement de genie electrique et de genie informatique * Universite Laval, Quebec, Canada, G1K 7P4 * http://vision.gel.ulaval.ca * *//*! * \file beagle/macros.hpp * \brief Contains some general Beagle macros and global functions. * \author Christian Gagne * \author Marc Parizeau * $Revision: 1.13 $ * $Date: 2005/10/04 16:25:10 $ *//*! * \defgroup Utils Utilities * \ingroup OOF * \brief Miscelaneous utility classes and functions, part of the Object Oriented Foundations. */#ifndef Beagle_macros_hpp#define Beagle_macros_hpp#include <cmath>#include <string>#include <vector>#include <iomanip>#include <iostream>#include <sstream>#include "beagle/config.hpp"#ifdef BEAGLE_HAVE_NUMERIC_LIMITS#include <limits>#endif // BEAGLE_HAVE_NUMERIC_LIMITS// An example on how to change the STL container allocator used.// #include <ext/new_allocator.h>// #define BEAGLE_STLALLOCATOR __gnu_cxx::new_allocator/* * Define a spare bool type if it is not defined by the compiler. */#ifndef BEAGLE_HAVE_BOOLenum boolvals {false=0, true=1};typedef enum boolvals bool;#endif // BEAGLE_HAVE_BOOL/* * Define an dumb explicit keyword if it is not defined by the compiler. */#ifndef BEAGLE_HAVE_EXPLICIT#define explicit#endif // BEAGLE_HAVE_EXPLICIT/*! * \def Beagle_MinM(X1,X2) * \brief Calculate the minimum between two values. * \param X1 First value to compare. * \param X2 Second value to compare. * \return Minimum of the two values. * \deprecated Use inline function minOf instead. */#define Beagle_MinM(X1,X2) ( ((X1)<(X2)) ? (X1) : (X2) )/*! * \def Beagle_MaxM(X1,X2) * \brief Calculate the maximum between two values. * \param X1 First value to compare. * \param X2 Second value to compare. * \return Maximum of the two values. * \deprecated Use inline function maxOf instead. */#define Beagle_MaxM(X1,X2) ( ((X1)>(X2)) ? (X1) : (X2) )/*! * \def Beagle_Pow2M(X1,X2) * \brief Calculate the square of a value. * \param X Value to compute the square. * \return Square of value. * \deprecated Use inline function pow2Of instead. */#define Beagle_Pow2M(X) ( (X)*(X) )namespace Beagle {/*! * \def BEAGLE_STLALLOCATOR * \brief STL allocator used to instanciate STL container elements. * * The STL allocator type can be redefined by defining the preprocessor flag * BEAGLE_STLALLOCATOR to the proper STL allocator. */#ifndef BEAGLE_STLALLOCATOR#define BEAGLE_STLALLOCATOR std::allocator#endif // BEAGLE_STLALLOCATOR/*! * \brief Typedef of the correct STL string to use. * * By default, if the the STL allocator is used unchanged (std::allocator), this type is a * synonym of the string type. */typedef std::basic_string< char, std::char_traits<char>, BEAGLE_STLALLOCATOR<char> > string;/*! * \brief Test if a floating-point number is in a not-a-number state. * \param inValue Value to evaluate not-a-number state. * \return True if the floating-point value is not-a-number, otherwise false. * \ingroup Utils */template <class T>inline bool isNaN(const T& inValue){ return ((inValue == inValue) == false);}/*! * \brief Test if a floating-point number is infinite. * \param inValue Value to evaluate finiteness. * \return True if the floating-point value is equal to infinity, otherwise false. * \ingroup Utils */template <class T>inline bool isInfinity(const T& inValue){#ifdef BEAGLE_HAVE_NUMERIC_LIMITS if(std::numeric_limits<T>::has_infinity) { return ((inValue == std::numeric_limits<T>::infinity()) || (inValue == -std::numeric_limits<T>::infinity())); }#endif // BEAGLE_HAVE_NUMERIC_LIMITS T lZero(0.0); T lInfinity(1.0 / lZero); return ((inValue == lInfinity) || (inValue == -lInfinity));}/*! * \brief Test if a floating-point number is finite, that is not NaN or infinite. * \param inValue Value to evaluate finiteness. * \return True if the floating-point value is finite, otherwise false. * \ingroup Utils */template <class T>inline bool isFinite(const T& inValue){ return ((isNaN<T>(inValue) == false) && (isInfinity(inValue) == false));}/*! * \brief Evaluate the maximum of two values. * \param inValue1 First value from which we want the maximum. * \param inValue2 Second value from which we want the maximum. * \return Maximum value between inValue1 and inValue2. * \ingroup Utils */template <class T>inline T maxOf(const T& inValue1, const T& inValue2){ if(isNaN(inValue1)) return inValue2; else if(isNaN(inValue2)) return inValue1; return ((inValue2 < inValue1) ? inValue1 : inValue2);}/*! * \brief Evaluate the minimum of two values. * \param inValue1 First value from which we want the minimum. * \param inValue2 Second value from which we want the minimum. * \return Minimum value between inValue1 and inValue2. * \ingroup Utils */template <class T>inline T minOf(const T& inValue1, const T& inValue2){ if(isNaN(inValue1)) return inValue2; else if(isNaN(inValue2)) return inValue1; return ((inValue1 < inValue2) ? inValue1 : inValue2);}/*! * \brief Evaluate square of a number (X^2). * \param inValue Value to evaluate the square. * \return Square of the value. * \ingroup Utils */template <class T>inline T pow2Of(const T& inValue){ return (inValue * inValue);}/*! * \brief Evaluate absolute value of a number. * \param inValue Value to evaluate the absolute value. * \return Absolute value of the input. * \ingroup Utils */template <class T>inline T absolute(const T& inValue){ return (inValue<0) ? -inValue : inValue;}/*! * \brief Evaluate absolute value of a double. * \param inValue Double to evaluate the absolute value. * \return Absolute value of the input. * \ingroup Utils */template <>inline double absolute(const double& inValue){ return std::fabs(inValue);}/*! * \brief Evaluate absolute value of a float. * \param inValue Float to evaluate the absolute value. * \return Absolute value of the input. * \ingroup Utils */template <>inline float absolute(const float& inValue){ return std::fabs(inValue);}/*! * \brief Evaluate absolute value of a long integer. * \param inValue Long integer to evaluate the absolute value. * \return Absolute value of the input. * \ingroup Utils */template <>inline long absolute(const long& inValue){ return std::labs(inValue);}/*! * \brief Evaluate absolute value of a int. * \param inValue Integer to evaluate the absolute value. * \return Absolute value of the input. * \ingroup Utils */template <>inline int absolute(const int& inValue){ return std::abs(inValue);}/*! * \brief Round double to the nearest integer, rounding half-way cases away from 0. * \param inValue Value to round * \return Rounded values to nearest integer. * \ingroup Utils */inline double round(double inValue){ return (inValue<0.0) ? std::ceil(inValue-0.5) : std::floor(inValue+0.5);}/*! * \brief Convert an integer into a string. * \param inInteger Integer to convert into a string. * \return string containing conversion of the integer. * \ingroup Utils */inline string int2str(long inInteger){ std::ostringstream lStringOS; lStringOS << inInteger; return lStringOS.str().c_str();}/*! * \brief Convert a string into a integer. * \param inString String to convert into an integer. * \return Long containing the conversion of the string. * \ingroup Utils */inline long str2int(const string& inString){ std::string lStr(inString.c_str()); std::istringstream lStringIS(lStr); long lInteger; lStringIS >> lInteger; return lInteger;}/*! * \brief Convert an unsigned integer into a string. * \param inInteger Integer to convert into a string. * \return string containing conversion of the integer. * \ingroup Utils */inline string uint2str(unsigned long inInteger){ std::ostringstream lStringOS; lStringOS << inInteger; return lStringOS.str().c_str();}/*! * \brief Convert a string into an unsigned integer. * \param inString String to convert into an integer. * \return Unsigned long containing the conversion of the string. * \ingroup Utils */inline unsigned long str2uint(const string& inString){ std::istringstream lStringIS(inString.c_str()); unsigned long lInteger; lStringIS >> lInteger; return lInteger;}/*! * \brief Convert a double into a string. * \param inDouble Double to convert into a string. * \return string containing conversion of the double. * \ingroup Utils */inline string dbl2str(double inDouble){ std::ostringstream lStringOS; if(isNaN(inDouble)) lStringOS << "nan"; else if(isInfinity(inDouble)) { if(inDouble < 0.0) lStringOS << "-inf"; else lStringOS << "inf"; } else lStringOS << inDouble; return lStringOS.str().c_str();}/*! * \brief Convert a double into a string. * \param inDouble Double to convert into a string. * \param inWidth Width of the written double. * \return string containing conversion of the double. * \ingroup Utils */inline string dbl2str(double inDouble, unsigned int inWidth){ using namespace std; ostringstream lStringOS; if(inWidth > 1) lStringOS.precision(inWidth-1); lStringOS.setf(ostringstream::left); lStringOS.width(inWidth); if(isNaN(inDouble)) lStringOS << "nan" << std::flush; else if(isInfinity(inDouble)) { if(inDouble < 0.0) lStringOS << "-inf" << std::flush; else lStringOS << "inf" << std::flush; } else lStringOS << inDouble << std::flush; string lString = lStringOS.str().c_str(); if(lString.size() > inWidth) { string::size_type lPosE = lString.find('e', 0); if(lPosE < lString.size()) { string lStringE(lString, lPosE, lString.size()); if(lStringE.size() < inWidth) lString.replace((inWidth-lStringE.size()), inWidth, lStringE); } } if(lString.size() != inWidth) lString.resize(inWidth, ' '); return lString;}/*! * \brief Convert a string into a double. * \param inString String to convert into a double. * \return Double containing the conversion of the string. * \ingroup Utils */inline double str2dbl(const string& inString){ if(inString == "nan") { double lZero(0.0); return (lZero / lZero); } else if(inString == "inf") {#ifdef BEAGLE_HAVE_NUMERIC_LIMITS if(std::numeric_limits<double>::has_infinity) { return std::numeric_limits<double>::infinity(); }#endif // BEAGLE_HAVE_NUMERIC_LIMITS double lZero(0.0); return (1.0 / lZero); } else if(inString == "-inf") {#ifdef BEAGLE_HAVE_NUMERIC_LIMITS if(std::numeric_limits<double>::has_infinity) { return -std::numeric_limits<double>::infinity(); }#endif // BEAGLE_HAVE_NUMERIC_LIMITS double lZero(0.0); return (-1.0 / lZero); } std::istringstream lStringIS(inString.c_str()); double lDouble; lStringIS >> lDouble; return lDouble;}/*! * \brief Convert a integer to its ordinal form , i.e. 1 -> 1st, 22 -> 22nd. * \param inNumber Integer to convert. * \return Ordinal form of the number. * \author Matthew Walker * \author Christian Gagne * \ingroup Utils */inline string uint2ordinal(unsigned int inNumber){ string lSuffix = "th"; switch(inNumber % 10) { case 1: {lSuffix = "st"; break;} case 2: {lSuffix = "nd"; break;} case 3: {lSuffix = "rd"; break;} } switch(inNumber % 100) { case 11: case 12: case 13: {lSuffix = "th"; break;} } std::ostringstream outStream; outStream << inNumber << lSuffix; return outStream.str().c_str();}/*! * \brief Wrap a string to fit a given line witdh. * \param ioString String to wrap. * \param inLineWidth Line width of the converted string. * \ingroup Utils */inline void wrapString(string& ioString, unsigned int inLineWidth=80){ // Can't do a line width of zero. (Setting to zero equates to turning off this algorithm.) if(inLineWidth==0) return; bool lBreakPointValid = false; bool lNewLine = true; unsigned int lBestBreakPoint = 0; unsigned int lFixed = 0; // Loop through all the characters in the string for (unsigned int i=0; i<ioString.size(); ++i) { // Find next character if this is a new line if(lNewLine) { // Find the next non-whitespace character to start the line. string::size_type lNextChar = ioString.find_first_not_of(" \t", i); if(lNextChar == string::npos) { // The rest of the string is just whitespace. Dump it. ioString.erase(i-1); return; } // Swallow one newline. if(ioString[lNextChar]=='\n') { ++lNextChar; } // Remove the whitespace. if(lNextChar > i) { ioString.erase(i,lNextChar-i); } lNewLine=false; } // Check if i has gone over line width (this shouldn't happen). if(i > lFixed+inLineWidth) return; // Check if i is at line width if(i == lFixed+inLineWidth) { if(!lBreakPointValid) { // Breaking in the middle of a word. ioString.insert(i,"\n"); lFixed = i+1; i = lFixed-1; // because at the continue i will be incremented lBreakPointValid = false; lNewLine = true; continue; } else { // Breakpoint valid if(ioString[lBestBreakPoint]==' ' || ioString[lBestBreakPoint]=='\t') { ioString[lBestBreakPoint] = '\n'; lFixed = lBestBreakPoint+1; i = lFixed-1; lBreakPointValid = false; lNewLine = true; continue; } } } // Check if current char is a newline const char lCurrentChar = ioString[i]; if(lCurrentChar == '\n') { lFixed = i+1; lBreakPointValid = false; lNewLine=true; continue; } // Look for whitespace to set breakpoints if(lCurrentChar==' ' || lCurrentChar=='\t') { lBestBreakPoint = i; lBreakPointValid = true; } }}}#endif // Beagle_macros_hpp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -