Code

Mnemonics in "Fill and stroke", "Align and distribute", and "Transform" dialogs ...
[inkscape.git] / cxxtest / cxxtest / ValueTraits.h
1 #ifndef __cxxtest__ValueTraits_h__
2 #define __cxxtest__ValueTraits_h__
4 //
5 // ValueTraits are used by CxxTest to convert arbitrary
6 // values used in TS_ASSERT_EQUALS() to a string representation.
7 // 
8 // This header file contains value traits for builtin integral types.
9 // To declare value traits for new types you should instantiate the class
10 // ValueTraits<YourClass>.
11 //
13 #include <cxxtest/Flags.h>
15 #ifdef _CXXTEST_OLD_TEMPLATE_SYNTAX
16 #   define CXXTEST_TEMPLATE_INSTANTIATION
17 #else // !_CXXTEST_OLD_TEMPLATE_SYNTAX
18 #   define CXXTEST_TEMPLATE_INSTANTIATION template<>
19 #endif // _CXXTEST_OLD_TEMPLATE_SYNTAX
21 namespace CxxTest 
22 {
23     //
24     // This is how we use the value traits
25     //
26 #   define TS_AS_STRING(x) CxxTest::traits(x).asString()
28     //
29     // Char representation of a digit
30     //
31     char digitToChar( unsigned digit );
33     //
34     // Convert byte value to hex digits
35     // Returns pointer to internal buffer
36     //
37     const char *byteToHex( unsigned char byte );
39     //
40     // Convert byte values to string
41     // Returns one past the copied data
42     //
43     char *bytesToString( const unsigned char *bytes, unsigned numBytes, unsigned maxBytes, char *s );
45     //
46     // Copy a string.
47     // Returns one past the end of the destination string
48     // Remember -- we can't use the standard library!
49     //
50     char *copyString( char *dst, const char *src );
52     //
53     // Compare two strings.
54     // Remember -- we can't use the standard library!
55     //
56     bool stringsEqual( const char *s1, const char *s2 );
58     //
59     // Represent a character value as a string
60     // Returns one past the end of the string
61     // This will be the actual char if printable or '\xXXXX' otherwise
62     //
63     char *charToString( unsigned long c, char *s );
65     //
66     // Prevent problems with negative (signed char)s
67     //
68     char *charToString( char c, char *s );
70     //
71     // The default ValueTraits class dumps up to 8 bytes as hex values
72     //
73     template <class T>
74     class ValueTraits
75     {
76         enum { MAX_BYTES = 8 };
77         char _asString[sizeof("{ ") + sizeof("XX ") * MAX_BYTES + sizeof("... }")];
78         
79     public:
80         ValueTraits( const T &t ) { bytesToString( (const unsigned char *)&t, sizeof(T), MAX_BYTES, _asString ); }
81         const char *asString( void ) const { return _asString; }
82     };    
84     //
85     // traits( T t )
86     // Creates an object of type ValueTraits<T>
87     //
88     template <class T>
89     inline ValueTraits<T> traits( T t )
90     {
91         return ValueTraits<T>( t );
92     }
94     //
95     // You can duplicate the implementation of an existing ValueTraits
96     //
97 #   define CXXTEST_COPY_TRAITS(CXXTEST_NEW_CLASS, CXXTEST_OLD_CLASS) \
98     CXXTEST_TEMPLATE_INSTANTIATION \
99     class ValueTraits< CXXTEST_NEW_CLASS > \
100     { \
101         ValueTraits< CXXTEST_OLD_CLASS > _old; \
102     public: \
103         ValueTraits( CXXTEST_NEW_CLASS n ) : _old( (CXXTEST_OLD_CLASS)n ) {} \
104         const char *asString( void ) const { return _old.asString(); } \
105     }
107     //
108     // Certain compilers need separate declarations for T and const T
109     //
110 #   ifdef _CXXTEST_NO_COPY_CONST
111 #       define CXXTEST_COPY_CONST_TRAITS(CXXTEST_CLASS)
112 #   else // !_CXXTEST_NO_COPY_CONST
113 #       define CXXTEST_COPY_CONST_TRAITS(CXXTEST_CLASS) CXXTEST_COPY_TRAITS(CXXTEST_CLASS, const CXXTEST_CLASS)
114 #   endif // _CXXTEST_NO_COPY_CONST
115     
116     //
117     // Avoid compiler warnings about unsigned types always >= 0
118     //
119     template<class N> inline bool negative( N n ) { return n < 0; }
120     template<class N> inline N abs( N n ) { return negative(n) ? -n : n; }
122 #   define CXXTEST_NON_NEGATIVE(Type) \
123     CXXTEST_TEMPLATE_INSTANTIATION \
124     inline bool negative<Type>( Type ) { return false; } \
125     CXXTEST_TEMPLATE_INSTANTIATION \
126     inline Type abs<Type>( Type value ) { return value; }
128     CXXTEST_NON_NEGATIVE( bool )
129     CXXTEST_NON_NEGATIVE( unsigned char )
130     CXXTEST_NON_NEGATIVE( unsigned short int )
131     CXXTEST_NON_NEGATIVE( unsigned int )
132     CXXTEST_NON_NEGATIVE( unsigned long int )
133 #   ifdef _CXXTEST_LONGLONG
134     CXXTEST_NON_NEGATIVE( unsigned _CXXTEST_LONGLONG )
135 #   endif // _CXXTEST_LONGLONG
137     //
138     // Represent (integral) number as a string
139     // Returns one past the end of the string
140     // Remember -- we can't use the standard library!
141     //
142     template<class N>
143     char *numberToString( N n, char *s,
144                           N base = 10,
145                           unsigned skipDigits = 0,
146                           unsigned maxDigits = (unsigned)-1 )
147     {
148         if ( negative(n) ) {
149             *s++ = '-';
150             n = abs(n);
151         }
152     
153         N digit = 1;
154         while ( digit <= (n / base) )
155             digit *= base;
156         N digitValue;
157         for ( ; digit >= 1 && skipDigits; n -= digit * digitValue, digit /= base, -- skipDigits )
158             digitValue = (unsigned)(n / digit);
159         for ( ; digit >= 1 && maxDigits; n -= digit * digitValue, digit /= base, -- maxDigits )
160             *s++ = digitToChar( (unsigned)(digitValue = (unsigned)(n / digit)) );
162         *s = '\0';
163         return s;
164     }
166     //
167     // All the specific ValueTraits follow.
168     // You can #define CXXTEST_USER_VALUE_TRAITS if you don't want them
169     //
170     
171 #ifndef CXXTEST_USER_VALUE_TRAITS
172     //
173     // ValueTraits: const char * const &
174     // This is used for printing strings, as in TS_FAIL( "Message" )
175     //
176     CXXTEST_TEMPLATE_INSTANTIATION
177     class ValueTraits<const char * const &>
178     {
179         ValueTraits &operator=( const ValueTraits & );
180         const char *_asString;
181         
182     public:
183         ValueTraits( const char * const &value ) : _asString( value ) {}
184         ValueTraits( const ValueTraits &other ) : _asString( other._asString ) {}
185         const char *asString( void ) const { return _asString; }
186     };
188     CXXTEST_COPY_TRAITS( const char *, const char * const & );
189     CXXTEST_COPY_TRAITS( char *, const char * const & );
191     //
192     // ValueTraits: bool
193     //    
194     CXXTEST_TEMPLATE_INSTANTIATION
195     class ValueTraits<const bool>
196     {
197         bool _value;
198         
199     public:
200         ValueTraits( const bool value ) : _value( value ) {}
201         const char *asString( void ) const { return _value ? "true" : "false"; }
202     };
204     CXXTEST_COPY_CONST_TRAITS( bool );
206 #   ifdef _CXXTEST_LONGLONG
207     //
208     // ValueTraits: signed long long
209     //
210     CXXTEST_TEMPLATE_INSTANTIATION
211     class ValueTraits<const signed _CXXTEST_LONGLONG>
212     {
213         typedef _CXXTEST_LONGLONG T;
214         char _asString[2 + 3 * sizeof(T)];
215     public:
216         ValueTraits( T t ) { numberToString<T>( t, _asString ); }
217         const char *asString( void ) const { return _asString; }
218     };
220     CXXTEST_COPY_CONST_TRAITS( signed _CXXTEST_LONGLONG );
222     //
223     // ValueTraits: unsigned long long
224     //
225     CXXTEST_TEMPLATE_INSTANTIATION
226     class ValueTraits<const unsigned _CXXTEST_LONGLONG>
227     {
228         typedef unsigned _CXXTEST_LONGLONG T;
229         char _asString[1 + 3 * sizeof(T)];
230     public:
231         ValueTraits( T t ) { numberToString<T>( t, _asString ); }
232         const char *asString( void ) const { return _asString; }
233     };
235     CXXTEST_COPY_CONST_TRAITS( unsigned _CXXTEST_LONGLONG );
236 #   endif // _CXXTEST_LONGLONG
238     //
239     // ValueTraits: signed long
240     //
241     CXXTEST_TEMPLATE_INSTANTIATION
242     class ValueTraits<const signed long int>
243     {
244         typedef signed long int T;
245         char _asString[2 + 3 * sizeof(T)];
246     public:
247         ValueTraits( T t ) { numberToString<T>( t, _asString ); }
248         const char *asString( void ) const { return _asString; }
249     };
251     CXXTEST_COPY_CONST_TRAITS( signed long int );
252     
253     //
254     // ValueTraits: unsigned long
255     //
256     CXXTEST_TEMPLATE_INSTANTIATION
257     class ValueTraits<const unsigned long int>
258     {
259         typedef unsigned long int T;
260         char _asString[1 + 3 * sizeof(T)];
261     public:
262         ValueTraits( T t ) { numberToString<T>( t, _asString ); }
263         const char *asString( void ) const { return _asString; }
264     };
266     CXXTEST_COPY_CONST_TRAITS( unsigned long int );
267     
268     //
269     // All decimals are the same as the long version
270     //
271     
272     CXXTEST_COPY_TRAITS( const signed int, const signed long int );
273     CXXTEST_COPY_TRAITS( const unsigned int, const unsigned long int );
274     CXXTEST_COPY_TRAITS( const signed short int, const signed long int );
275     CXXTEST_COPY_TRAITS( const unsigned short int, const unsigned long int );
276     CXXTEST_COPY_TRAITS( const unsigned char, const unsigned long int );
277     
278     CXXTEST_COPY_CONST_TRAITS( signed int );
279     CXXTEST_COPY_CONST_TRAITS( unsigned int );
280     CXXTEST_COPY_CONST_TRAITS( signed short int );
281     CXXTEST_COPY_CONST_TRAITS( unsigned short int );
282     CXXTEST_COPY_CONST_TRAITS( unsigned char );
284     //
285     // ValueTraits: char
286     // Returns 'x' for printable chars, '\x??' for others
287     //
288     CXXTEST_TEMPLATE_INSTANTIATION
289     class ValueTraits<const char>
290     {
291         char _asString[sizeof("'\\xXX'")];
292     public:
293         ValueTraits( char c ) { copyString( charToString( c, copyString( _asString, "'" ) ), "'" ); }
294         const char *asString( void ) const { return _asString; }
295     };
297     CXXTEST_COPY_CONST_TRAITS( char );
299     //
300     // ValueTraits: signed char
301     // Same as char, some compilers need it
302     //
303     CXXTEST_COPY_TRAITS( const signed char, const char );
304     CXXTEST_COPY_CONST_TRAITS( signed char );
306     //
307     // ValueTraits: double
308     //
309     CXXTEST_TEMPLATE_INSTANTIATION
310     class ValueTraits<const double>
311     {
312     public:
313         ValueTraits( double t ) 
314         {
315             ( requiredDigitsOnLeft( t ) > MAX_DIGITS_ON_LEFT ) ?
316                 hugeNumber( t ) :
317                 normalNumber( t );
318         }
320         const char *asString( void ) const { return _asString; }
321         
322     private:
323         enum { MAX_DIGITS_ON_LEFT = 24, DIGITS_ON_RIGHT = 4, BASE = 10 };
324         char _asString[1 + MAX_DIGITS_ON_LEFT + 1 + DIGITS_ON_RIGHT + 1];
326         static unsigned requiredDigitsOnLeft( double t );
327         char *doNegative( double &t );
328         void hugeNumber( double t );
329         void normalNumber( double t );
330         char *doubleToString( double t, char *s, unsigned skip = 0, unsigned max = (unsigned)-1 );
331     };
333     CXXTEST_COPY_CONST_TRAITS( double );
335     //
336     // ValueTraits: float
337     //
338     CXXTEST_COPY_TRAITS( const float, const double );
339     CXXTEST_COPY_CONST_TRAITS( float );
340 #endif // !CXXTEST_USER_VALUE_TRAITS
341 };
343 #ifdef _CXXTEST_HAVE_STD
344 #   include <cxxtest/StdValueTraits.h>
345 #endif // _CXXTEST_HAVE_STD
347 //
348 // CXXTEST_ENUM_TRAITS
349 //
350 #define CXXTEST_ENUM_TRAITS( TYPE, VALUES ) \
351     namespace CxxTest \
352     { \
353         CXXTEST_TEMPLATE_INSTANTIATION \
354         class ValueTraits<TYPE> \
355         { \
356             TYPE _value; \
357             char _fallback[sizeof("(" #TYPE ")") + 3 * sizeof(TYPE)]; \
358         public: \
359             ValueTraits( TYPE value ) { \
360                 _value = value; \
361                 numberToString<unsigned long int>( _value, copyString( _fallback, "(" #TYPE ")" ) ); \
362             } \
363             const char *asString( void ) const \
364             { \
365                 switch ( _value ) \
366                 { \
367                     VALUES \
368                     default: return _fallback; \
369                 } \
370             } \
371         }; \
372     }
374 #define CXXTEST_ENUM_MEMBER( MEMBER ) \
375     case MEMBER: return #MEMBER;
377 #endif // __cxxtest__ValueTraits_h__