1 /*
2  *  Created by Phil Nash on 1/2/2013.
3  *  Copyright 2013 Two Blue Cubes Ltd. All rights reserved.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 #ifndef TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
9 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
10 
11 #include "catch_result_type.h"
12 #include "catch_common.h"
13 #include "catch_stream.h"
14 #include "catch_interfaces_capture.h"
15 #include "catch_tostring.h"
16 
17 #include <string>
18 #include <vector>
19 
20 namespace Catch {
21 
22     struct MessageInfo {
23         MessageInfo(    StringRef const& _macroName,
24                         SourceLineInfo const& _lineInfo,
25                         ResultWas::OfType _type );
26 
27         StringRef macroName;
28         std::string message;
29         SourceLineInfo lineInfo;
30         ResultWas::OfType type;
31         unsigned int sequence;
32 
33         bool operator == ( MessageInfo const& other ) const;
34         bool operator < ( MessageInfo const& other ) const;
35     private:
36         static unsigned int globalCount;
37     };
38 
39     struct MessageStream {
40 
41         template<typename T>
42         MessageStream& operator << ( T const& value ) {
43             m_stream << value;
44             return *this;
45         }
46 
47         ReusableStringStream m_stream;
48     };
49 
50     struct MessageBuilder : MessageStream {
51         MessageBuilder( StringRef const& macroName,
52                         SourceLineInfo const& lineInfo,
53                         ResultWas::OfType type );
54 
55         template<typename T>
56         MessageBuilder& operator << ( T const& value ) {
57             m_stream << value;
58             return *this;
59         }
60 
61         MessageInfo m_info;
62     };
63 
64     class ScopedMessage {
65     public:
66         explicit ScopedMessage( MessageBuilder const& builder );
67         ScopedMessage( ScopedMessage& duplicate ) = delete;
68         ScopedMessage( ScopedMessage&& old );
69         ~ScopedMessage();
70 
71         MessageInfo m_info;
72         bool m_moved;
73     };
74 
75     class Capturer {
76         std::vector<MessageInfo> m_messages;
77         IResultCapture& m_resultCapture = getResultCapture();
78         size_t m_captured = 0;
79     public:
80         Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
81         ~Capturer();
82 
83         void captureValue( size_t index, std::string const& value );
84 
85         template<typename T>
captureValues(size_t index,T const & value)86         void captureValues( size_t index, T const& value ) {
87             captureValue( index, Catch::Detail::stringify( value ) );
88         }
89 
90         template<typename T, typename... Ts>
captureValues(size_t index,T const & value,Ts const &...values)91         void captureValues( size_t index, T const& value, Ts const&... values ) {
92             captureValue( index, Catch::Detail::stringify(value) );
93             captureValues( index+1, values... );
94         }
95     };
96 
97 } // end namespace Catch
98 
99 #endif // TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
100