blob: dbb6cb8d5d0c3b4b8f8ca844bf8cfc9f7b4d1baf [file] [log] [blame] [view]
Phil Nash27ce70c2014-12-09 18:54:35 +00001# String conversions
2
3Catch needs to be able to convert types you use in assertions and logging expressions into strings (for logging and reporting purposes).
Phil Nash605d8702015-05-20 18:12:40 +01004Most built-in or std types are supported out of the box but there are three ways that you can tell Catch how to convert your own types (or other, third-party types) into strings.
Phil Nash27ce70c2014-12-09 18:54:35 +00005
6## operator << overload for std::ostream
7
8This is the standard way of providing string conversions in C++ - and the chances are you may already provide this for your own purposes. If you're not familiar with this idiom it involves writing a free function of the form:
9
Phil Nash82754c12014-12-12 08:29:21 +000010```
11std::ostream& operator << ( std::ostream& os, T const& value ) {
Phil Nash27ce70c2014-12-09 18:54:35 +000012 os << convertMyTypeToString( value );
13 return os;
Phil Nash82754c12014-12-12 08:29:21 +000014}
15```
Phil Nash27ce70c2014-12-09 18:54:35 +000016
17(where ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable - it doesn't have to be in another function).
18
19You should put this function in the same namespace as your type.
20
21Alternatively you may prefer to write it as a member function:
22
Phil Nash82754c12014-12-12 08:29:21 +000023```
24std::ostream& T::operator << ( std::ostream& os ) const {
Phil Nash27ce70c2014-12-09 18:54:35 +000025 os << convertMyTypeToString( *this );
26 return os;
Phil Nash82754c12014-12-12 08:29:21 +000027}
28```
Phil Nash27ce70c2014-12-09 18:54:35 +000029
30## Catch::toString overload
31
32If you don't want to provide an ```operator <<``` overload, or you want to convert your type differently for testing purposes, you can provide an overload for ```Catch::toString()``` for your type.
33
Phil Nash82754c12014-12-12 08:29:21 +000034```
35namespace Catch {
Phil Nash27ce70c2014-12-09 18:54:35 +000036 std::string toString( T const& value ) {
37 return convertMyTypeToString( value );
38 }
39}
Phil Nash82754c12014-12-12 08:29:21 +000040```
Phil Nash27ce70c2014-12-09 18:54:35 +000041
42Again ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable. Note that the function must be in the Catch namespace, which itself must be in the global namespace.
43
Phil Nash605d8702015-05-20 18:12:40 +010044## Catch::StringMaker<T> specialisation
45
46There are some cases where overloading toString does not work as expected. Specialising StringMaker<T> gives you more precise, and reliable, control - but at the cost of slightly more code and complexity:
47
48```
49namespace Catch {
50 template<> struct StringMaker<T> {
51 static std::string convert( T const& value ) {
52 return convertMyTypeToString( value );
53 }
54 };
55}
56```
57
Phil Nasha49f0882015-11-18 08:39:21 +000058## Exceptions
59
60By default all exceptions deriving from `std::exception` will be translated to strings by calling the `what()` method. For exception types that do not derive from `std::exception` - or if `what()` does not return a suitable string - use `CATCH_TRANSLATE_EXCEPTION`. This defines a function that takes your exception type, by reference, and returns a string. It can appear anywhere in the code - it doesn't have to be in the same translation unit. For example:
61
62```
63CATCH_TRANSLATE_EXCEPTION( MyType& ex ) {
64 return ex.message();
65}
66```
67
Phil Nash27ce70c2014-12-09 18:54:35 +000068---
69
70[Home](Readme.md)