Util.hpp

Go to the documentation of this file.
00001 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00002 //
00003 //        This file is part of E-Cell Simulation Environment package
00004 //
00005 //                Copyright (C) 1996-2002 Keio University
00006 //
00007 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00008 //
00009 //
00010 // E-Cell is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2 of the License, or (at your option) any later version.
00014 // 
00015 // E-Cell 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
00021 // License along with E-Cell -- see the file COPYING.
00022 // If not, write to the Free Software Foundation, Inc.,
00023 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00024 // 
00025 //END_HEADER
00026 //
00027 // written by Koichi Takahashi <shafi@e-cell.org>,
00028 // E-Cell Project.
00029 //
00030 
00031 #ifndef __UTIL_HPP
00032 #define __UTIL_HPP
00033 #include <stdlib.h>
00034 #include <sstream>
00035 #include <functional>
00036 #include <limits>
00037 
00038 #include <boost/version.hpp>
00039 
00040 #if BOOST_VERSION >= 103200  // for boost-1.32.0 or later.
00041 #    include <boost/numeric/conversion/cast.hpp>
00042 #else                        // use this instead for boost-1.31 or earlier.
00043 #    include <boost/cast.hpp>
00044 #endif
00045 
00046 
00047 #include <boost/lexical_cast.hpp>
00048 #include <boost/static_assert.hpp>
00049 #include <boost/type_traits.hpp>
00050 
00051 #include "libecs.hpp"
00052 #include "Exceptions.hpp"
00053 
00054 namespace libecs
00055 {
00056 
00057   /** @addtogroup util The Utilities.
00058    Utilities.
00059 
00060    @ingroup libecs
00061    @{ 
00062    */ 
00063 
00064   /** @file */
00065 
00066   /** 
00067       A universal to String / from String converter.
00068 
00069       Two usages:
00070       - stringCast( VALUE )        -- convert VALUE to a string.
00071       - stringCast<TYPE>( STRING ) -- convert STRING to a TYPE object.
00072 
00073       This is a thin wrapper over boost::lexical_cast.
00074       This stringCast template function has some specializations for
00075       common numeric types such as Real and Integer are defined, and
00076       use of this instead of boost::lexical_cast for those types
00077       can reduce resulting binary size.
00078   */
00079 
00080   template< typename NEW, typename GIVEN >
00081   const NEW stringCast( const GIVEN& aValue )
00082   {
00083     BOOST_STATIC_ASSERT( ( boost::is_same<String,GIVEN>::value ||
00084                            boost::is_same<String,NEW>::value ) );
00085 
00086     return boost::lexical_cast<NEW>( aValue );
00087   }
00088 
00089 
00090   ///@internal
00091   template< typename GIVEN >
00092   const String stringCast( const GIVEN& aValue )
00093   {
00094     return stringCast<String,GIVEN>( aValue );
00095   }
00096 
00097 #define __STRINGCAST_SPECIALIZATION_DECL( NEW, GIVEN )\
00098   template<> ECELL_API const NEW stringCast<NEW,GIVEN>( const GIVEN& )
00099 
00100   __STRINGCAST_SPECIALIZATION_DECL( String, Real );
00101   __STRINGCAST_SPECIALIZATION_DECL( String, HighReal );
00102   __STRINGCAST_SPECIALIZATION_DECL( String, Integer );
00103   __STRINGCAST_SPECIALIZATION_DECL( String, UnsignedInteger );
00104   __STRINGCAST_SPECIALIZATION_DECL( Real, String );
00105   __STRINGCAST_SPECIALIZATION_DECL( HighReal, String );
00106   __STRINGCAST_SPECIALIZATION_DECL( Integer, String );
00107   __STRINGCAST_SPECIALIZATION_DECL( UnsignedInteger, String );
00108   // __STRINGCAST_SPECIALIZATION_DECL( String, String );
00109 
00110 #undef __STRINGCAST_SPECIALIZATION_DECL
00111 
00112 
00113 
00114   /**
00115      Erase white space characters ( ' ', '\t', and '\n' ) from a string
00116   */
00117   void eraseWhiteSpaces( StringRef str );
00118 
00119   template < class T >
00120   struct PtrGreater
00121   {
00122     bool operator()( T x, T y ) const { return *y < *x; }
00123   };
00124 
00125 
00126   template < class T >
00127   struct PtrLess
00128   {
00129     bool operator()( T x, T y ) const { return *y > *x; }
00130   };
00131 
00132 
00133 
00134   /**
00135      Check if aSequence's size() is within [ aMin, aMax ].  
00136 
00137      If not, throw a RangeError exception.
00138 
00139   */
00140 
00141   template <class Sequence>
00142   void checkSequenceSize( const Sequence& aSequence, 
00143                           const typename Sequence::size_type aMin, 
00144                           const typename Sequence::size_type aMax )
00145   {
00146     const typename Sequence::size_type aSize( aSequence.size() );
00147     if( aSize < aMin || aSize > aMax )
00148       {
00149         throwSequenceSizeError( aSize, aMin, aMax );
00150       }
00151   }
00152 
00153 
00154   /**
00155      Check if aSequence's size() is at least aMin.
00156 
00157      If not, throw a RangeError exception.
00158 
00159   */
00160 
00161   template <class Sequence>
00162   void checkSequenceSize( const Sequence& aSequence, 
00163                           const typename Sequence::size_type aMin )
00164   {
00165     const typename Sequence::size_type aSize( aSequence.size() );
00166     if( aSize < aMin )
00167       {
00168         throwSequenceSizeError( aSize, aMin );
00169       }
00170   }
00171 
00172 
00173   ///@internal
00174   void throwSequenceSizeError( const int aSize, 
00175                                const int aMin, const int aMax );
00176 
00177   ///@internal
00178   ECELL_API void throwSequenceSizeError( const int aSize, const int aMin );
00179 
00180 
00181   /**
00182      Form a 'for' loop over a STL sequence.
00183 
00184      Use this like:
00185 
00186      FOR_ALL( std::vector<int>, anIntVector )
00187      {
00188        int anInt( *i ); // the iterator is 'i'.
00189        ...
00190      }
00191 
00192      @arg SEQCLASS the classname of the STL sequence. 
00193      @arg SEQ the STL sequence.
00194   */
00195 
00196 #define FOR_ALL( SEQCLASS, SEQ )\
00197   for( SEQCLASS ::const_iterator i( (SEQ) .begin() ) ;\
00198       i != (SEQ) .end() ; ++i )
00199 
00200 
00201 
00202   /**
00203      For each 'second' member of element in a sequence, call a given method.
00204 
00205      @note This will be deprecated.  Use select2nd instead.
00206 
00207      @arg SEQCLASS the classname of the STL sequence. 
00208      @arg SEQ the STL sequence.
00209      @arg METHOD the name of the method.
00210      
00211      @see FOR_ALL
00212   */
00213 
00214 #define FOR_ALL_SECOND( SEQCLASS, SEQ, METHOD )\
00215   FOR_ALL( SEQCLASS, SEQ )\
00216     { (*i).second-> METHOD (); }
00217 
00218 
00219 
00220 
00221   template< typename T >
00222   inline const T nullValue()
00223   {
00224     return 0;
00225   }
00226 
00227   template<>
00228   inline const Real nullValue()
00229   {
00230     return 0.0;
00231   }
00232 
00233   template<>
00234   inline const String nullValue()
00235   {
00236     return String();
00237   }
00238 
00239   template< class NEW, class GIVEN >
00240   class StaticCaster
00241     :
00242     std::unary_function< GIVEN, NEW >
00243   {
00244   public:
00245     inline NEW operator()( const GIVEN& aValue )
00246     {
00247       BOOST_STATIC_ASSERT( ( boost::is_convertible<GIVEN,NEW>::value ) );
00248       return static_cast<NEW>( aValue );
00249     }
00250   };
00251 
00252   template< class NEW, class GIVEN >
00253   class DynamicCaster
00254     :
00255     std::unary_function< GIVEN, NEW >
00256   {
00257   public:
00258     NEW operator()( const GIVEN& aPtr )
00259     {
00260       NEW aNew( dynamic_cast<NEW>( aPtr ) );
00261       if( aNew != NULLPTR )
00262         {
00263           return aNew;
00264         }
00265       else
00266         {
00267           THROW_EXCEPTION( TypeError, "dynamic cast failed." );
00268         }
00269     }
00270   };
00271 
00272   template< class NEW, class GIVEN >
00273   class LexicalCaster
00274     :
00275     std::unary_function< GIVEN, NEW >
00276   {
00277   public:
00278     const NEW operator()( const GIVEN& aValue )
00279     {
00280       return stringCast<NEW>( aValue );
00281     }
00282   };
00283 
00284 
00285 
00286 
00287   template< class NEW, class GIVEN >
00288   class NumericCaster
00289     :
00290     std::unary_function< GIVEN, NEW >
00291   {
00292   public:
00293     inline NEW operator()( GIVEN aValue )
00294     {
00295       return boost::numeric_cast<NEW>( aValue );
00296     }
00297   };
00298 
00299 
00300 
00301   /**
00302      These functions are prepared for ExpressionFluxProcess
00303      and are used in it. asinh, acosh and atanh are not available in 
00304      MS Windows (MinGW).
00305   */
00306 
00307 
00308   template <typename T>
00309   Real real_not( T n )
00310   {
00311     if( n == 0 )
00312       {
00313         return 1.0;
00314       }
00315     else
00316       {
00317         return 0.0;
00318       }
00319   }
00320 
00321   template <typename T>
00322   Real real_eq( T n1, T n2 )
00323   {
00324     if( n1 == n2 )
00325       {
00326         return 1.0;
00327       }
00328     else
00329       {
00330         return 0.0;
00331       }
00332   }
00333 
00334   template <typename T>
00335   Real real_neq( T n1, T n2 )
00336   {
00337     if( n1 == n2 )
00338       {
00339         return 0.0;
00340       }
00341     else
00342       {
00343         return 1.0;
00344       }
00345   }
00346 
00347   template <typename T>
00348   Real real_gt( T n1, T n2 )
00349   {
00350     if( n1 > n2 )
00351       {
00352         return 1.0;
00353       }
00354     else
00355       {
00356         return 0.0;
00357       }
00358   }
00359 
00360   template <typename T>
00361   Real real_lt( T n1, T n2 )
00362   {
00363     if( n1 < n2 )
00364       {
00365         return 1.0;
00366       }
00367     else
00368       {
00369         return 0.0;
00370       }
00371   }
00372 
00373   template <typename T>
00374   Real real_geq( T n1, T n2 )
00375   {
00376     if( n1 >= n2 )
00377       {
00378         return 1.0;
00379       }
00380     else
00381       {
00382         return 0.0;
00383       }
00384   }
00385 
00386   template <typename T>
00387   Real real_leq( T n1, T n2 )
00388   {
00389     if( n1 <= n2 )
00390       {
00391         return 1.0;
00392       }
00393     else
00394       {
00395         return 0.0;
00396       }
00397   }
00398 
00399   template <typename T>
00400   Real real_and( T n1, T n2 )
00401   {
00402     if( ( n1 != 0 ) && ( n2 != 0 ) )
00403       {
00404         return 1.0;
00405       }
00406     else
00407       {
00408         return 0.0;
00409       }
00410   }
00411 
00412   template <typename T>
00413   Real real_or( T n1, T n2 )
00414   {
00415     if( ( n1 != 0 ) || ( n2 != 0 ) )
00416       {
00417         return 1.0;
00418       }
00419     else
00420       {
00421         return 0.0;
00422       }
00423   }
00424 
00425   template <typename T>
00426   Real real_xor( T n1, T n2 )
00427   {
00428     if( ( n1 != 0 ) && !( n2 != 0 ) )
00429       {
00430         return 1.0;
00431       }
00432     else
00433       {
00434         return 0.0;
00435       }
00436   }
00437 
00438   template <typename T>
00439   T asinh( T n )
00440   {
00441     return log( n + sqrt( n * n + 1 ) );
00442   }
00443 
00444   template <typename T>
00445   T acosh( T n )
00446   {
00447     return log( n - sqrt( n * n - 1 ) );
00448   }
00449 
00450   template <typename T>
00451   T atanh( T n )
00452   {
00453     return 0.5 * log( ( 1 + n ) / ( 1 - n ) );
00454   }
00455 
00456   template <typename T>
00457   T sec( T n )
00458   {
00459     return 1 / cos( n );
00460   }
00461 
00462   template <typename T>
00463   T csc( T n )
00464   {
00465     return 1 / sin( n );
00466   }
00467 
00468   template <typename T>
00469   T cot( T n )
00470   {
00471     return 1 / tan( n );
00472   }
00473 
00474   template <typename T>
00475   T asec( T n )
00476   {
00477     return 1 / acos( n );
00478   }
00479 
00480   template <typename T>
00481   T acsc( T n )
00482   {
00483     return 1 / asin( n );
00484   }
00485 
00486   template <typename T>
00487   T acot( T n )
00488   {
00489     return 1 / atan( n );
00490   }
00491 
00492   template <typename T>
00493   T sech( T n )
00494   {
00495     return 1 / cosh( n );
00496   }
00497   
00498   template <typename T>
00499   T csch( T n )
00500   {
00501     return 1 / sinh( n );
00502   }
00503   
00504   template <typename T>
00505   T coth( T n )
00506   {
00507     return 1 / tanh( n );
00508   }
00509   
00510   template <typename T>
00511   T asech( T n )
00512   {
00513     return 1 / acosh( n );
00514   }
00515 
00516   template <typename T>
00517   T acsch( T n )
00518   {
00519     return 1 / asinh( n );
00520   }
00521 
00522   template <typename T>
00523   T acoth( T n )
00524   {
00525     return 1 / atanh( n );
00526   }
00527 
00528   template <typename T>
00529   T fact( T n )
00530   {
00531     if( n <= 1 )
00532       return 1;
00533     else
00534       return n * fact( n-1 );
00535   }
00536   
00537   const Polymorph convertStringMapToPolymorph( StringMapCref aMap );
00538 
00539 
00540   //@}
00541 
00542 } // namespace libecs
00543 
00544 
00545 #endif /* __UTIL_HPP */
00546 
00547 
00548 /*
00549   Do not modify
00550   $Author: sachiboo $
00551   $Revision: 2627 $
00552   $Date: 2006-11-24 13:44:30 +0100 (Fri, 24 Nov 2006) $
00553   $Locker$
00554 */
00555 

Generated on Fri Aug 31 18:42:39 2007 for E-CELL C++ libraries (libecs and libemc) 3.1.105 by  doxygen 1.5.3