diff options
Diffstat (limited to 'cxxtest/StdValueTraits.h')
-rw-r--r-- | cxxtest/StdValueTraits.h | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/cxxtest/StdValueTraits.h b/cxxtest/StdValueTraits.h new file mode 100644 index 0000000..036796b --- /dev/null +++ b/cxxtest/StdValueTraits.h @@ -0,0 +1,229 @@ +#ifndef __cxxtest_StdValueTraits_h__ +#define __cxxtest_StdValueTraits_h__ + +// +// This file defines ValueTraits for std:: stuff. +// It is #included by <cxxtest/ValueTraits.h> if you +// define CXXTEST_HAVE_STD +// + +#include <cxxtest/ValueTraits.h> +#include <cxxtest/StdHeaders.h> + +#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 Char, class Traits, class Allocator> + // class ValueTraits< std::basic_string<Char, Traits, Allocator> > {}; + // 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<const CXXTEST_STD(string)> : 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<const CXXTEST_STD(basic_string<wchar_t>)> : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(basic_string<wchar_t>) &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<wchar_t>) ); +#endif // _CXXTEST_OLD_STD + + // + // Convert a range defined by iterators to a string + // This is useful for almost all STL containers + // + template<class Stream, class Iterator> + 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 First, class Second> + class ValueTraits< CXXTEST_STD(pair)<First, Second> > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(pair)<First, Second> &p ) + { + *this << "<" << TS_AS_STRING( p.first ) << ", " << TS_AS_STRING( p.second ) << ">"; + } + }; + + // + // std::vector + // + template<class Element> + class ValueTraits< CXXTEST_STD(vector)<Element> > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(vector)<Element> &v ) + { + dumpRange( *this, v.begin(), v.end() ); + } + }; + + // + // std::list + // + template<class Element> + class ValueTraits< CXXTEST_STD(list)<Element> > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(list)<Element> &l ) + { + dumpRange( *this, l.begin(), l.end() ); + } + }; + + // + // std::set + // + template<class Element> + class ValueTraits< CXXTEST_STD(set)<Element> > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(set)<Element> &s ) + { + dumpRange( *this, s.begin(), s.end() ); + } + }; + + // + // std::map + // + template<class Key, class Value> + class ValueTraits< CXXTEST_STD(map)<Key, Value> > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(map)<Key, Value> &m ) + { + dumpRange( *this, m.begin(), m.end() ); + } + }; + + // + // std::deque + // + template<class Element> + class ValueTraits< CXXTEST_STD(deque)<Element> > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(deque)<Element> &d ) + { + dumpRange( *this, d.begin(), d.end() ); + } + }; + + // + // std::multiset + // + template<class Element> + class ValueTraits< CXXTEST_STD(multiset)<Element> > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(multiset)<Element> &ms ) + { + dumpRange( *this, ms.begin(), ms.end() ); + } + }; + + // + // std::multimap + // + template<class Key, class Value> + class ValueTraits< CXXTEST_STD(multimap)<Key, Value> > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(multimap)<Key, Value> &mm ) + { + dumpRange( *this, mm.begin(), mm.end() ); + } + }; + + // + // std::complex + // + template<class Number> + class ValueTraits< CXXTEST_STD(complex)<Number> > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(complex)<Number> &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__ |