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