ISIS Core Library 0.7.2 (api 3.0.0)
|
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