ISIS Core Library 0.7.2 (api 3.0.0)

/scr/tee1/isis/lib/Core/CoreUtils/common.hpp

Go to the documentation of this file.
00001 //
00002 // C++ Interface: common
00003 //
00004 // Description:
00005 //
00006 //
00007 // Author: Enrico Reimer<reimer@cbs.mpg.de>, (C) 2009
00008 //
00009 // Copyright: See COPYING file that comes with this distribution
00010 //
00011 //
00012 
00013 #ifndef CORE_COMMON_HPP
00014 #define CORE_COMMON_HPP
00015 
00016 #ifdef _MSC_VER
00017 #define NOMINMAX 1
00018 #endif
00019 
00020 #include <utility>
00021 #include <ostream>
00022 #include <map>
00023 #include <string>
00024 #include <sstream>
00025 #include <boost/regex.hpp>
00026 #include <boost/lexical_cast.hpp>
00027 #include <boost/mpl/assert.hpp>
00028 #include <set>
00029 #include <cmath>
00030 #include "log.hpp"
00031 #include "log_modules.hpp"
00032 #include "../config.hpp"
00033 
00034 #ifdef WIN32
00035 #include <Windows.h>
00036 #endif
00037 
00038 namespace isis
00039 {
00040 namespace util
00041 {
00042 
00043 std::string getLastSystemError();
00044 
00054 template<class InputIterator, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits> &
00055 listToOStream( InputIterator start, InputIterator end,
00056                std::basic_ostream<_CharT, _Traits> &o,
00057                const std::string delim = ",",
00058                const std::string prefix = "{", const std::string suffix = "}" )
00059 {
00060     o << prefix;
00061 
00062     if ( start != end ) {
00063         o << *start;
00064         start++;
00065     }
00066 
00067     for ( InputIterator i = start; i != end; i++ )
00068         o << delim << *i;
00069 
00070     o << suffix;
00071     return o;
00072 }
00073 
00074 // specialization to print char-list as number lists, not strings
00075 //@todo check if this works for VC
00076 template<typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits> &
00077 listToOStream( const unsigned char *start, const unsigned char *end,
00078                std::basic_ostream<_CharT, _Traits> &o,
00079                const std::string delim = ",",
00080                const std::string prefix = "{", const std::string suffix = "}" )
00081 {
00082     o << prefix;
00083 
00084     if ( start != end ) {
00085         o << ( unsigned short )*start;
00086         start++;
00087     }
00088 
00089     for ( const unsigned char *i = start; i != end; i++ )
00090         o << delim << ( unsigned short )*i;
00091 
00092     o << suffix;
00093     return o;
00094 }
00095 
00097 template<class InputIterator> std::string listToString(
00098     InputIterator start, InputIterator end,
00099     const std::string delim = ",",
00100     const std::string prefix = "{", const std::string suffix = "}" )
00101 {
00102     std::ostringstream ret;
00103     listToOStream( start, end, ret, delim, prefix, suffix );
00104     return ret.str();
00105 }
00107 template<typename T, typename InputIterator> std::list<T> listToList( InputIterator start, InputIterator end )
00108 {
00109     std::list<T> ret;
00110 
00111     for ( ; start != end; start++ )
00112         ret.push_back( boost::lexical_cast<T>( *start ) );
00113 
00114     return ret;
00115 }
00116 
00129 template<typename TARGET> std::list<TARGET> stringToList(
00130     std::string source, const boost::regex &separator,
00131     boost::regex prefix, boost::regex postfix )
00132 {
00133     std::list<TARGET> ret;
00134     assert( ! separator.empty() );
00135 
00136     if ( ! prefix.empty() ) {
00137         if ( prefix.str()[0] != '^' )
00138             prefix = boost::regex( std::string( "^" ) + prefix.str(), prefix.flags() );
00139 
00140         source = boost::regex_replace( source, prefix, "", boost::format_first_only | boost::match_default );
00141     }
00142 
00143     if ( ! postfix.empty() ) {
00144         if ( postfix.str()[postfix.size() - 1] != '$' )
00145             postfix = boost::regex( postfix.str() + "$", postfix.flags() );
00146 
00147         source = boost::regex_replace( source, postfix, "", boost::format_first_only | boost::match_default );
00148     }
00149 
00150     boost::sregex_token_iterator i = boost::make_regex_token_iterator( source, separator, -1 );
00151     const boost::sregex_token_iterator token_end;
00152 
00153     while ( i != token_end ) {
00154         ret.push_back( boost::lexical_cast<TARGET>( ( i++ )->str() ) );
00155     }
00156 
00157     return ret;
00158 }
00168 template<typename TARGET> std::list<TARGET> stringToList(
00169     std::string source,
00170     const boost::regex separator = boost::regex( "[[:space:]]" ) )
00171 {
00172     return stringToList<TARGET>( source, separator, separator, separator );
00173 }
00174 
00187 //@todo test
00188 template<typename TARGET, typename charT, typename traits> std::list<TARGET>
00189 stringToList( const std::basic_string<charT, traits> &source,  charT separator )
00190 {
00191     std::list<TARGET> ret;
00192 
00193     for (
00194         size_t next = source.find_first_not_of( separator );
00195         next != std::string::npos;
00196         next = source.find_first_not_of( separator, next )
00197     ) {
00198         const size_t start = next;
00199         next = source.find( separator, start );
00200         ret.push_back( boost::lexical_cast<TARGET>( source.substr( start, next - start ) ) );
00201     }
00202 
00203     return ret;
00204 }
00205 
00217 template<typename T> bool fuzzyEqual( T a, T b, unsigned short scale = 10 )
00218 {
00219     BOOST_MPL_ASSERT( ( boost::is_float<T> ) );
00220 
00221     const T epsilon = std::numeric_limits<T>::epsilon(); // get the distange between 1 and the next representable value
00222     T bigger, smaller;
00223 
00224     a = std::abs( a );
00225     b = std::abs( b );
00226 
00227     if( a < b ) {
00228         bigger = b;
00229         smaller = a;
00230     } else {
00231         smaller = b;
00232         bigger = a;
00233     }
00234 
00235     if( smaller == 0 )
00236         return bigger < std::numeric_limits<T>::min() * scale;
00237 
00238     const T factor = 1 / smaller; // scale smaller to that value
00239     return ( bigger * factor ) <= ( 1 + epsilon * scale ); //scaled bigger should be between 1 and the next representable value
00240 }
00241 
00242 typedef CoreDebug Debug;
00243 typedef CoreLog Runtime;
00244 
00253 template<typename HANDLE> void enableLog( LogLevel level )
00254 {
00255     ENABLE_LOG( CoreLog, HANDLE, level );
00256     ENABLE_LOG( CoreDebug, HANDLE, level );
00257 }
00258 }//util
00259 
00268 template<typename HANDLE> void enableLogGlobal( LogLevel level )
00269 {
00270     ENABLE_LOG( CoreLog, HANDLE, level );
00271     ENABLE_LOG( CoreDebug, HANDLE, level );
00272     ENABLE_LOG( ImageIoLog, HANDLE, level );
00273     ENABLE_LOG( ImageIoDebug, HANDLE, level );
00274     ENABLE_LOG( DataLog, HANDLE, level );
00275     ENABLE_LOG( DataDebug, HANDLE, level );
00276 }
00277 }//isis
00278 
00279 namespace std
00280 {
00282 template<typename charT, typename _FIRST, typename _SECOND > basic_ostream<charT, std::char_traits<charT> >&
00283 operator<<( basic_ostream<charT, std::char_traits<charT> > &out, const pair<_FIRST, _SECOND> &s )
00284 {
00285     return out << s.first << ":" << s.second;
00286 }
00287 
00289 template<typename charT, typename _Key, typename _Tp, typename _Compare, typename _Alloc >
00290 basic_ostream<charT, std::char_traits<charT> >& operator<<( basic_ostream<charT, std::char_traits<charT> > &out, const map<_Key, _Tp, _Compare, _Alloc>& s )
00291 {
00292     isis::util::listToOStream( s.begin(), s.end(), out, "\n", "", "" );
00293     return out;
00294 }
00295 
00297 template<typename charT, typename _Tp, typename _Compare, typename _Alloc >
00298 basic_ostream<charT, std::char_traits<charT> >& operator<<( basic_ostream<charT, std::char_traits<charT> > &out, const map<std::string, _Tp, _Compare, _Alloc>& s )
00299 {
00300     size_t key_len = 0;
00301     typedef typename map<std::string, _Tp, _Compare, _Alloc>::const_iterator m_iterator;
00302 
00303     for ( m_iterator i = s.begin(); i != s.end(); i++ )
00304         if ( key_len < i->first.length() )
00305             key_len = i->first.length();
00306 
00307     for ( m_iterator i = s.begin(); i != s.end(); ) {
00308         out << make_pair( i->first + std::string( key_len - i->first.length(), ' ' ), i->second );
00309 
00310         if ( ++i != s.end() )
00311             out << std::endl;
00312     }
00313 
00314     return out;
00315 }
00316 
00318 template<typename charT, typename _Tp, typename _Alloc >
00319 basic_ostream<charT, std::char_traits<charT> >& operator<<( basic_ostream<charT, std::char_traits<charT> > &out, const list<_Tp, _Alloc>& s )
00320 {
00321     isis::util::listToOStream( s.begin(), s.end(), out );
00322     return out;
00323 }
00325 template<typename charT, typename _Tp, typename _Alloc >
00326 basic_ostream<charT, std::char_traits<charT> >& operator<<( basic_ostream<charT, std::char_traits<charT> > &out, const set<_Tp, _Alloc>& s )
00327 {
00328     isis::util::listToOStream( s.begin(), s.end(), out );
00329     return out;
00330 }
00331 
00332 }
00333 #endif //CORE_COMMON_HPP