CppUnit project page CppUnit home page

stringize.h

Go to the documentation of this file.
00001 // Defines the convertToString() & stringize() function use by assertions to output a value.
00002 #ifndef CPPUT_STRINGIZE_H_INCLUDED
00003 # define CPPUT_STRINGIZE_H_INCLUDED
00004 
00005 # include <cpput/config.h>
00006 # include <string>
00007 # include <cpptl/stringtools.h>
00008 
00009 /* How to:
00010  * - define a conversion function for a string type:
00011  *   overload the function std::string getStdString( MyStringType )
00012  *
00013  *   namespace CppUT { 
00014  *   inline std::string getStdString( const MyStringType &s ) {
00015  *      return s.str();
00016  *   } }
00017  *
00018  */
00019 
00020 
00021 
00022 // 1) Is it a string ?
00023 // std::string convertToString( ptr ) => Yes, convert to string & add quotes.
00024 // NoToStringConversion convertToString( .. )
00025 // stringize( impl::stringize( value, convertToString( ptr ) ) );
00026 // 2) Is there an overloaded toString() function for that type
00027 // std::string toString( ptr ); => Yes, convert to string using the function
00028 // NoToStringConversion toString( ... );
00029 // 3) Fall back DefaultStringizer.
00030 
00031 
00032 namespace CppUT {
00033 
00040    template<class ValueType>
00041    struct DefaultStringizer
00042    {
00043       std::string operator()( const ValueType &value ) const
00044       {
00045          return stringize( value );
00046       }
00047    };
00048 
00051    template<class ValueType>
00052    struct RefStringizer
00053    {
00054       std::string operator()( ValueType value ) const
00055       {
00056          return stringize( value );
00057       }
00058    };
00059 
00062    template<class ValueType>
00063    struct DerefStringizer
00064    {
00065       std::string operator()( ValueType value ) const
00066       {
00067          return stringize( *value );
00068       }
00069    };
00070 
00071 // ------------------- convertToString -------------------------------
00072 // User should overload getStdString() to support their own string types.
00073 //
00074 // IMPORTANT: to handle compiler that do not support function template ordering
00075 // (CPPTL_NO_FUNCTION_TEMPLATE_ORDERING), such as vc++ 6.0.
00076 // getStdString() must never be called with a 'by value' parameter.
00077 // Passing by value would result in undefined behavior for non string type parameter
00078 // 'eaten' by NotConvertibleToStdString convertToString( ... ).
00079 // In practice, this means that a templated function accepting const ref parameters
00080 // should be the caller. For example:
00081 //
00082 // template<class StringType1, class StringType2>
00083 // void checkRegExMatched( const StringType1 &pattern,   // <= the const ref here ensure that
00084 //                         const StringType2 &str )      // convertToString will only be passed reference.
00085 // {
00086 //    RegEx regex( CppUT::convertToString(&pattern ) );
00087 //    CppUT::checkTrue( regex.matched( CppUT::convertToString( &str ) ) );
00088 // }
00089 
00092    struct NotConvertibleToStdString {};
00093 
00096    inline std::string getStdString( const char *cstr )
00097    {
00098       return std::string( cstr );
00099    }
00100 
00103    inline std::string getStdString( const std::string &s )
00104    {
00105       return s;
00106    }
00107 
00110    inline std::string getStdString( const CppTL::ConstString &s )
00111    {
00112       return s.c_str();
00113    }
00114 
00115 #ifdef CPPTL_NO_FUNCTION_TEMPLATE_ORDERING
00116 
00118    inline NotConvertibleToStdString getStdString( ... )
00119    {
00120       return NotConvertibleToStdString();
00121    }
00122 #else
00123 
00125    template<class T>
00126    inline NotConvertibleToStdString getStdString( const T & )
00127    {
00128       return NotConvertibleToStdString();
00129    }
00130 #endif
00131 
00134    template <class StringType>
00135    inline std::string convertToString( const StringType &s )
00136    {
00137       return getStdString( s );  // if you get a compilation error on this call, then getStdString() has not been overloaded for your string type.
00138    }
00139 
00140 
00141 // ------------------- stringize -------------------------------
00142 // If CPPUT_NO_DEFAULT_STRINGIZE is defined, the user is expected 
00143 // to provide a function which accept the following types:
00144 // template<class T>
00145 // std::string defaultStringize( const T &value );
00146 
00147    struct NoToStringOverload {};
00148 
00149 #ifdef CPPTL_NO_FUNCTION_TEMPLATE_ORDERING
00150    inline NoToStringOverload toString( ... )
00151    {
00152       return NoToStringOverload();
00153    }
00154 #else
00155    template<class T>
00156    inline NoToStringOverload toString( const T & )
00157    {
00158       return NoToStringOverload();
00159    }
00160 #endif
00161 
00163    namespace Impl {
00164 
00165       template<typename ValueType>
00166       std::string toStringStringize( const ValueType &value, NoToStringOverload )
00167       {
00168          return defaultStringize( value );
00169       }
00170 
00171       template<typename ValueType>
00172       std::string toStringStringize( const ValueType &value, const std::string &str )
00173       {
00174          return str;
00175       }
00176 
00177       template<typename ValueType>
00178       std::string stringize( const ValueType &value, NotConvertibleToStdString )
00179       {
00180          return toStringStringize( value, toString( value ) );
00181       }
00182 
00183       template<typename ValueType>
00184       std::string stringize( const ValueType &value, const std::string &str )
00185       {
00186          return CppTL::quoteString( str ).c_str();
00187       }
00188 
00189    } // namespace Impl
00191 
00192 
00195    template<typename ValueType>
00196    std::string stringize( const ValueType &value )
00197    {
00198       return Impl::stringize( value, getStdString(&value) );
00199    }
00200 
00201 } // namespace CPPUT
00202 
00203 
00204 # ifndef CPPUT_NO_DEFAULT_STRINGIZE
00205 
00206 #  ifndef CPPTL_NO_SSTREAM
00207 #   include <sstream>
00208 #  else // standard stream are not available, use the deprecated one
00209 #   include <strstream>
00210 #  endif
00211 
00212 namespace CppUT {
00213 
00216    template<typename ValueType>
00217    std::string defaultStringize( const ValueType &value )
00218    {
00219 #  ifndef CPPTL_NO_SSTREAM
00220          std::ostringstream os;
00221          os  <<  value;
00222          return os.str();
00223 #  else // standard stream are not available, use the deprecated one
00224          std::ostrstream os;
00225          os  <<  value;
00226          return std::string( os.str(), os.pcount() );
00227 #  endif
00228    }
00229 
00230 } // namespace CPPUT
00231 
00232 # endif
00233 
00234 
00235 #endif // CPPUT_STRINGIZE_H_INCLUDED

SourceForge Logo hosts this site. Send comments to:
CppUnit Developers