#ifndef __cxxtest_StdValueTraits_h__ #define __cxxtest_StdValueTraits_h__ // // This file defines ValueTraits for std:: stuff. // It is #included by if you // define CXXTEST_HAVE_STD // #include #include #ifdef _CXXTEST_OLD_STD # define CXXTEST_STD(x) x #else // !_CXXTEST_OLD_STD # define CXXTEST_STD(x) std::x #endif // _CXXTEST_OLD_STD #ifndef CXXTEST_USER_VALUE_TRAITS namespace CxxTest { // // NOTE: This should have been // template // class ValueTraits< std::basic_string > {}; // But MSVC doesn't support it (yet). // // // If we have std::string, we might as well use it // class StdTraitsBase { public: StdTraitsBase &operator<<( const CXXTEST_STD(string) &s ) { _s += s; return *this; } const char *asString() const { return _s.c_str(); } private: CXXTEST_STD(string) _s; }; // // std::string // CXXTEST_TEMPLATE_INSTANTIATION class ValueTraits : public StdTraitsBase { public: ValueTraits( const CXXTEST_STD(string) &s ) { *this << "\""; for ( unsigned i = 0; i < s.length(); ++ i ) { char c[sizeof("\\xXX")]; charToString( s[i], c ); *this << c; } *this << "\""; } }; CXXTEST_COPY_CONST_TRAITS( CXXTEST_STD(string) ); #ifndef _CXXTEST_OLD_STD // // std::wstring // CXXTEST_TEMPLATE_INSTANTIATION class ValueTraits)> : public StdTraitsBase { public: ValueTraits( const CXXTEST_STD(basic_string) &s ) { *this << "L\""; for ( unsigned i = 0; i < s.length(); ++ i ) { char c[sizeof("\\x12345678")]; charToString( (unsigned long)s[i], c ); *this << c; } *this << "\""; } }; CXXTEST_COPY_CONST_TRAITS( CXXTEST_STD(basic_string) ); #endif // _CXXTEST_OLD_STD // // Convert a range defined by iterators to a string // This is useful for almost all STL containers // template void dumpRange( Stream &s, Iterator first, Iterator last ) { s << "{ "; while ( first != last ) { s << TS_AS_STRING(*first); ++ first; s << ((first == last) ? " }" : ", "); } } #ifdef _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION // // std::pair // template class ValueTraits< CXXTEST_STD(pair) > : public StdTraitsBase { public: ValueTraits( const CXXTEST_STD(pair) &p ) { *this << "<" << TS_AS_STRING( p.first ) << ", " << TS_AS_STRING( p.second ) << ">"; } }; // // std::vector // template class ValueTraits< CXXTEST_STD(vector) > : public StdTraitsBase { public: ValueTraits( const CXXTEST_STD(vector) &v ) { dumpRange( *this, v.begin(), v.end() ); } }; // // std::list // template class ValueTraits< CXXTEST_STD(list) > : public StdTraitsBase { public: ValueTraits( const CXXTEST_STD(list) &l ) { dumpRange( *this, l.begin(), l.end() ); } }; // // std::set // template class ValueTraits< CXXTEST_STD(set) > : public StdTraitsBase { public: ValueTraits( const CXXTEST_STD(set) &s ) { dumpRange( *this, s.begin(), s.end() ); } }; // // std::map // template class ValueTraits< CXXTEST_STD(map) > : public StdTraitsBase { public: ValueTraits( const CXXTEST_STD(map) &m ) { dumpRange( *this, m.begin(), m.end() ); } }; // // std::deque // template class ValueTraits< CXXTEST_STD(deque) > : public StdTraitsBase { public: ValueTraits( const CXXTEST_STD(deque) &d ) { dumpRange( *this, d.begin(), d.end() ); } }; // // std::multiset // template class ValueTraits< CXXTEST_STD(multiset) > : public StdTraitsBase { public: ValueTraits( const CXXTEST_STD(multiset) &ms ) { dumpRange( *this, ms.begin(), ms.end() ); } }; // // std::multimap // template class ValueTraits< CXXTEST_STD(multimap) > : public StdTraitsBase { public: ValueTraits( const CXXTEST_STD(multimap) &mm ) { dumpRange( *this, mm.begin(), mm.end() ); } }; // // std::complex // template class ValueTraits< CXXTEST_STD(complex) > : public StdTraitsBase { public: ValueTraits( const CXXTEST_STD(complex) &c ) { if ( !c.imag() ) *this << TS_AS_STRING(c.real()); else if ( !c.real() ) *this << "(" << TS_AS_STRING(c.imag()) << " * i)"; else *this << "(" << TS_AS_STRING(c.real()) << " + " << TS_AS_STRING(c.imag()) << " * i)"; } }; #endif // _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION }; #endif // CXXTEST_USER_VALUE_TRAITS #endif // __cxxtest_StdValueTraits_h__