1 #ifndef __cxxtest_StdValueTraits_h__
2 #define __cxxtest_StdValueTraits_h__
4 //
5 // This file defines ValueTraits for std:: stuff.
6 // It is #included by <cxxtest/ValueTraits.h> if you
7 // define CXXTEST_HAVE_STD
8 //
10 #include <cxxtest/ValueTraits.h>
11 #include <cxxtest/StdHeaders.h>
13 #ifdef _CXXTEST_OLD_STD
14 # define CXXTEST_STD(x) x
15 #else // !_CXXTEST_OLD_STD
16 # define CXXTEST_STD(x) std::x
17 #endif // _CXXTEST_OLD_STD
19 #ifndef CXXTEST_USER_VALUE_TRAITS
21 namespace CxxTest
22 {
23 //
24 // NOTE: This should have been
25 // template<class Char, class Traits, class Allocator>
26 // class ValueTraits< std::basic_string<Char, Traits, Allocator> > {};
27 // But MSVC doesn't support it (yet).
28 //
30 //
31 // If we have std::string, we might as well use it
32 //
33 class StdTraitsBase
34 {
35 public:
36 StdTraitsBase &operator<<( const CXXTEST_STD(string) &s ) { _s += s; return *this; }
37 const char *asString() const { return _s.c_str(); }
39 private:
40 CXXTEST_STD(string) _s;
41 };
43 //
44 // std::string
45 //
46 CXXTEST_TEMPLATE_INSTANTIATION
47 class ValueTraits<const CXXTEST_STD(string)> : public StdTraitsBase
48 {
49 public:
50 ValueTraits( const CXXTEST_STD(string) &s )
51 {
52 *this << "\"";
53 for ( unsigned i = 0; i < s.length(); ++ i ) {
54 char c[sizeof("\\xXX")];
55 charToString( s[i], c );
56 *this << c;
57 }
58 *this << "\"";
59 }
60 };
62 CXXTEST_COPY_CONST_TRAITS( CXXTEST_STD(string) );
64 #ifndef _CXXTEST_OLD_STD
65 //
66 // std::wstring
67 //
68 CXXTEST_TEMPLATE_INSTANTIATION
69 class ValueTraits<const CXXTEST_STD(basic_string<wchar_t>)> : public StdTraitsBase
70 {
71 public:
72 ValueTraits( const CXXTEST_STD(basic_string<wchar_t>) &s )
73 {
74 *this << "L\"";
75 for ( unsigned i = 0; i < s.length(); ++ i ) {
76 char c[sizeof("\\x12345678")];
77 charToString( (unsigned long)s[i], c );
78 *this << c;
79 }
80 *this << "\"";
81 }
82 };
84 CXXTEST_COPY_CONST_TRAITS( CXXTEST_STD(basic_string<wchar_t>) );
85 #endif // _CXXTEST_OLD_STD
87 //
88 // Convert a range defined by iterators to a string
89 // This is useful for almost all STL containers
90 //
91 template<class Stream, class Iterator>
92 void dumpRange( Stream &s, Iterator first, Iterator last )
93 {
94 s << "{ ";
95 while ( first != last ) {
96 s << TS_AS_STRING(*first);
97 ++ first;
98 s << ((first == last) ? " }" : ", ");
99 }
100 }
102 #ifdef _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION
103 //
104 // std::pair
105 //
106 template<class First, class Second>
107 class ValueTraits< CXXTEST_STD(pair)<First, Second> > : public StdTraitsBase
108 {
109 public:
110 ValueTraits( const CXXTEST_STD(pair)<First, Second> &p )
111 {
112 *this << "<" << TS_AS_STRING( p.first ) << ", " << TS_AS_STRING( p.second ) << ">";
113 }
114 };
116 //
117 // std::vector
118 //
119 template<class Element>
120 class ValueTraits< CXXTEST_STD(vector)<Element> > : public StdTraitsBase
121 {
122 public:
123 ValueTraits( const CXXTEST_STD(vector)<Element> &v )
124 {
125 dumpRange( *this, v.begin(), v.end() );
126 }
127 };
129 //
130 // std::list
131 //
132 template<class Element>
133 class ValueTraits< CXXTEST_STD(list)<Element> > : public StdTraitsBase
134 {
135 public:
136 ValueTraits( const CXXTEST_STD(list)<Element> &l )
137 {
138 dumpRange( *this, l.begin(), l.end() );
139 }
140 };
142 //
143 // std::set
144 //
145 template<class Element>
146 class ValueTraits< CXXTEST_STD(set)<Element> > : public StdTraitsBase
147 {
148 public:
149 ValueTraits( const CXXTEST_STD(set)<Element> &s )
150 {
151 dumpRange( *this, s.begin(), s.end() );
152 }
153 };
155 //
156 // std::map
157 //
158 template<class Key, class Value>
159 class ValueTraits< CXXTEST_STD(map)<Key, Value> > : public StdTraitsBase
160 {
161 public:
162 ValueTraits( const CXXTEST_STD(map)<Key, Value> &m )
163 {
164 dumpRange( *this, m.begin(), m.end() );
165 }
166 };
168 //
169 // std::deque
170 //
171 template<class Element>
172 class ValueTraits< CXXTEST_STD(deque)<Element> > : public StdTraitsBase
173 {
174 public:
175 ValueTraits( const CXXTEST_STD(deque)<Element> &d )
176 {
177 dumpRange( *this, d.begin(), d.end() );
178 }
179 };
181 //
182 // std::multiset
183 //
184 template<class Element>
185 class ValueTraits< CXXTEST_STD(multiset)<Element> > : public StdTraitsBase
186 {
187 public:
188 ValueTraits( const CXXTEST_STD(multiset)<Element> &ms )
189 {
190 dumpRange( *this, ms.begin(), ms.end() );
191 }
192 };
194 //
195 // std::multimap
196 //
197 template<class Key, class Value>
198 class ValueTraits< CXXTEST_STD(multimap)<Key, Value> > : public StdTraitsBase
199 {
200 public:
201 ValueTraits( const CXXTEST_STD(multimap)<Key, Value> &mm )
202 {
203 dumpRange( *this, mm.begin(), mm.end() );
204 }
205 };
207 //
208 // std::complex
209 //
210 template<class Number>
211 class ValueTraits< CXXTEST_STD(complex)<Number> > : public StdTraitsBase
212 {
213 public:
214 ValueTraits( const CXXTEST_STD(complex)<Number> &c )
215 {
216 if ( !c.imag() )
217 *this << TS_AS_STRING(c.real());
218 else if ( !c.real() )
219 *this << "(" << TS_AS_STRING(c.imag()) << " * i)";
220 else
221 *this << "(" << TS_AS_STRING(c.real()) << " + " << TS_AS_STRING(c.imag()) << " * i)";
222 }
223 };
224 #endif // _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION
225 };
227 #endif // CXXTEST_USER_VALUE_TRAITS
229 #endif // __cxxtest_StdValueTraits_h__