Home | History | Annotate | Download | only in docs
      1 <a id="top"></a>
      2 # String conversions
      3 
      4 **Contents**<br>
      5 [operator << overload for std::ostream](#operator--overload-for-stdostream)<br>
      6 [Catch::StringMaker specialisation](#catchstringmaker-specialisation)<br>
      7 [Catch::is_range specialisation](#catchis_range-specialisation)<br>
      8 [Exceptions](#exceptions)<br>
      9 
     10 Catch needs to be able to convert types you use in assertions and logging expressions into strings (for logging and reporting purposes).
     11 Most built-in or std types are supported out of the box but there are two ways that you can tell Catch how to convert your own types (or other, third-party types) into strings.
     12 
     13 ## operator << overload for std::ostream
     14 
     15 This 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:
     16 
     17 ```
     18 std::ostream& operator << ( std::ostream& os, T const& value ) {
     19     os << convertMyTypeToString( value );
     20     return os;
     21 }
     22 ```
     23 
     24 (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).
     25 
     26 You should put this function in the same namespace as your type, or the global namespace, and have it declared before including Catch's header.
     27 
     28 ## Catch::StringMaker specialisation
     29 If you don't want to provide an ```operator <<``` overload, or you want to convert your type differently for testing purposes, you can provide a specialization for `Catch::StringMaker<T>`:
     30 
     31 ```
     32 namespace Catch {
     33     template<>
     34     struct StringMaker<T> {
     35         static std::string convert( T const& value ) {
     36             return convertMyTypeToString( value );
     37         }
     38     };
     39 }
     40 ```
     41 
     42 ## Catch::is_range specialisation
     43 As a fallback, Catch attempts to detect if the type can be iterated
     44 (`begin(T)` and `end(T)` are valid) and if it can be, it is stringified
     45 as a range. For certain types this can lead to infinite recursion, so
     46 it can be disabled by specializing `Catch::is_range` like so:
     47 
     48 ```cpp
     49 namespace Catch {
     50     template<>
     51     struct is_range<T> {
     52         static const bool value = false;
     53     };
     54 }
     55 
     56 ```
     57 
     58 
     59 ## Exceptions
     60 
     61 By 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:
     62 
     63 ```
     64 CATCH_TRANSLATE_EXCEPTION( MyType& ex ) {
     65     return ex.message();
     66 }
     67 ```
     68 
     69 ---
     70 
     71 [Home](Readme.md#top)
     72