liuxiaolong
2021-07-20 58d904a328c0d849769b483e901a0be9426b8209
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
 
//  See http://www.boost.org/libs/test for the library home page.
//
//  Description : contains definition for all test tools in test toolbox
// ***************************************************************************
 
#ifndef BOOST_TEST_UTILS_LAZY_OSTREAM_HPP
#define BOOST_TEST_UTILS_LAZY_OSTREAM_HPP
 
// Boost.Test
#include <boost/test/detail/config.hpp>
 
// STL
#include <iosfwd>
 
#include <boost/test/detail/suppress_warnings.hpp>
 
//____________________________________________________________________________//
 
// ************************************************************************** //
// **************                  lazy_ostream                ************** //
// ************************************************************************** //
 
namespace boost {
namespace unit_test {
 
class BOOST_TEST_DECL lazy_ostream {
public:
    virtual                 ~lazy_ostream()                                         {}
 
    static lazy_ostream&    instance()                                              { return inst; }
 
    #if !defined(BOOST_EMBTC)
      
    friend std::ostream&    operator<<( std::ostream& ostr, lazy_ostream const& o ) { return o( ostr ); }
 
    #else
      
    friend std::ostream&    operator<<( std::ostream& ostr, lazy_ostream const& o );
 
    #endif
      
    // access method
    bool                    empty() const                                           { return m_empty; }
 
    // actual printing interface; to be accessed only by this class and children
    virtual std::ostream&   operator()( std::ostream& ostr ) const                  { return ostr; }
protected:
    explicit                lazy_ostream( bool p_empty = true ) : m_empty( p_empty )    {}
 
private:
    // Data members
    bool                    m_empty;
    static lazy_ostream     inst;
};
 
#if defined(BOOST_EMBTC)
 
    inline std::ostream&    operator<<( std::ostream& ostr, lazy_ostream const& o ) { return o( ostr ); }
 
#endif
    
//____________________________________________________________________________//
 
template<typename PrevType, typename T, typename StorageT=T const&>
class lazy_ostream_impl : public lazy_ostream {
public:
    lazy_ostream_impl( PrevType const& prev, T const& value )
    : lazy_ostream( false )
    , m_prev( prev )
    , m_value( value )
    {
    }
 
    std::ostream&   operator()( std::ostream& ostr ) const BOOST_OVERRIDE
    {
        return m_prev(ostr) << m_value;
    }
private:
    // Data members
    PrevType const&         m_prev;
    StorageT                m_value;
};
 
//____________________________________________________________________________//
 
template<typename T>
inline lazy_ostream_impl<lazy_ostream,T>
operator<<( lazy_ostream const& prev, T const& v )
{
    return lazy_ostream_impl<lazy_ostream,T>( prev, v );
}
 
//____________________________________________________________________________//
 
template<typename PrevPrevType, typename TPrev, typename T>
inline lazy_ostream_impl<lazy_ostream_impl<PrevPrevType,TPrev>,T>
operator<<( lazy_ostream_impl<PrevPrevType,TPrev> const& prev, T const& v )
{
    typedef lazy_ostream_impl<PrevPrevType,TPrev> PrevType;
    return lazy_ostream_impl<PrevType,T>( prev, v );
}
 
//____________________________________________________________________________//
 
#if BOOST_TEST_USE_STD_LOCALE
 
template<typename R,typename S>
inline lazy_ostream_impl<lazy_ostream,R& (BOOST_TEST_CALL_DECL *)(S&),R& (BOOST_TEST_CALL_DECL *)(S&)>
operator<<( lazy_ostream const& prev, R& (BOOST_TEST_CALL_DECL *man)(S&) )
{
    typedef R& (BOOST_TEST_CALL_DECL * ManipType)(S&);
 
    return lazy_ostream_impl<lazy_ostream,ManipType,ManipType>( prev, man );
}
 
//____________________________________________________________________________//
 
template<typename PrevPrevType, typename TPrev,typename R,typename S>
inline lazy_ostream_impl<lazy_ostream_impl<PrevPrevType,TPrev>,R& (BOOST_TEST_CALL_DECL *)(S&),R& (BOOST_TEST_CALL_DECL *)(S&)>
operator<<( lazy_ostream_impl<PrevPrevType,TPrev> const& prev, R& (BOOST_TEST_CALL_DECL *man)(S&) )
{
    typedef R& (BOOST_TEST_CALL_DECL * ManipType)(S&);
 
    return lazy_ostream_impl<lazy_ostream_impl<PrevPrevType,TPrev>,ManipType,ManipType>( prev, man );
}
 
//____________________________________________________________________________//
 
#endif
 
#define BOOST_TEST_LAZY_MSG( M ) (::boost::unit_test::lazy_ostream::instance() << M)
 
} // namespace unit_test
} // namespace boost
 
#include <boost/test/detail/enable_warnings.hpp>
 
#endif // BOOST_TEST_UTILS_LAZY_OSTREAM_HPP