]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | // File : $RCSfile$ | |
9 | // | |
10 | // Version : $Revision: 74248 $ | |
11 | // | |
12 | // Description : defines level of indiration facilitating workarounds for non printable types | |
13 | // *************************************************************************** | |
14 | ||
15 | #ifndef BOOST_TEST_TOOLS_IMPL_COMMON_HPP_012705GER | |
16 | #define BOOST_TEST_TOOLS_IMPL_COMMON_HPP_012705GER | |
17 | ||
18 | // Boost.Test | |
19 | #include <boost/test/detail/config.hpp> | |
20 | #include <boost/test/detail/global_typedef.hpp> | |
21 | #include <boost/test/detail/workaround.hpp> | |
22 | ||
23 | // Boost | |
24 | #include <boost/mpl/or.hpp> | |
25 | #include <boost/static_assert.hpp> | |
26 | #include <boost/type_traits/is_array.hpp> | |
27 | #include <boost/type_traits/is_function.hpp> | |
28 | #include <boost/type_traits/is_abstract.hpp> | |
29 | #include <boost/type_traits/has_left_shift.hpp> | |
30 | ||
31 | #include <limits> | |
32 | ||
33 | #include <boost/test/detail/suppress_warnings.hpp> | |
34 | ||
35 | //____________________________________________________________________________// | |
36 | ||
37 | namespace boost { | |
38 | namespace test_tools { | |
39 | namespace tt_detail { | |
40 | ||
41 | // ************************************************************************** // | |
42 | // ************** print_log_value ************** // | |
43 | // ************************************************************************** // | |
44 | ||
45 | template<typename T> | |
46 | struct print_log_value { | |
47 | BOOST_STATIC_ASSERT_MSG( (boost::has_left_shift<std::ostream,T>::value), | |
48 | "Type has to implement operator<< to be printable"); | |
49 | ||
50 | void operator()( std::ostream& ostr, T const& t ) | |
51 | { | |
52 | typedef typename mpl::or_<is_array<T>,is_function<T>,is_abstract<T> >::type cant_use_nl; | |
53 | ||
54 | std::streamsize old_precision = set_precision( ostr, cant_use_nl() ); | |
55 | ||
56 | ostr << t; | |
57 | ||
58 | if( old_precision != (std::streamsize)-1 ) | |
59 | ostr.precision( old_precision ); | |
60 | } | |
61 | ||
62 | std::streamsize set_precision( std::ostream& ostr, mpl::false_ ) | |
63 | { | |
64 | if( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 2 ) | |
65 | return ostr.precision( 2 + std::numeric_limits<T>::digits * 301/1000 ); | |
66 | else if ( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 10 ) { | |
67 | #ifdef BOOST_NO_CXX11_NUMERIC_LIMITS | |
68 | // (was BOOST_NO_NUMERIC_LIMITS_LOWEST but now deprecated). | |
69 | // No support for std::numeric_limits<double>::max_digits10, | |
70 | // so guess that a couple of guard digits more than digits10 will display any difference. | |
71 | return ostr.precision( 2 + std::numeric_limits<T>::digits10 ); | |
72 | #else | |
73 | // std::numeric_limits<double>::max_digits10; IS supported. | |
74 | // Any noisy or guard digits needed to display any difference are included in max_digits10. | |
75 | return ostr.precision( std::numeric_limits<T>::max_digits10 ); | |
76 | #endif | |
77 | } | |
78 | // else if T is not specialized for std::numeric_limits<>, | |
79 | // then will just get the default precision of 6 digits. | |
80 | return (std::streamsize)-1; | |
81 | } | |
82 | ||
83 | std::streamsize set_precision( std::ostream&, mpl::true_ ) { return (std::streamsize)-1; } | |
84 | }; | |
85 | ||
86 | //____________________________________________________________________________// | |
87 | ||
88 | #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) | |
89 | template<typename T, std::size_t N > | |
90 | struct print_log_value< T[N] > { | |
91 | void operator()( std::ostream& ostr, T const* t ) | |
92 | { | |
93 | ostr << t; | |
94 | } | |
95 | }; | |
96 | #endif | |
97 | ||
98 | //____________________________________________________________________________// | |
99 | ||
100 | template<> | |
101 | struct BOOST_TEST_DECL print_log_value<bool> { | |
102 | void operator()( std::ostream& ostr, bool t ) | |
103 | { | |
104 | ostr << std::boolalpha << t; | |
105 | } | |
106 | }; | |
107 | ||
108 | //____________________________________________________________________________// | |
109 | ||
110 | template<> | |
111 | struct BOOST_TEST_DECL print_log_value<char> { | |
112 | void operator()( std::ostream& ostr, char t ); | |
113 | }; | |
114 | ||
115 | //____________________________________________________________________________// | |
116 | ||
117 | template<> | |
118 | struct BOOST_TEST_DECL print_log_value<unsigned char> { | |
119 | void operator()( std::ostream& ostr, unsigned char t ); | |
120 | }; | |
121 | ||
122 | //____________________________________________________________________________// | |
123 | ||
124 | template<> | |
125 | struct BOOST_TEST_DECL print_log_value<char const*> { | |
126 | void operator()( std::ostream& ostr, char const* t ); | |
127 | }; | |
128 | ||
129 | //____________________________________________________________________________// | |
130 | ||
131 | template<> | |
132 | struct BOOST_TEST_DECL print_log_value<wchar_t const*> { | |
133 | void operator()( std::ostream& ostr, wchar_t const* t ); | |
134 | }; | |
135 | ||
136 | //____________________________________________________________________________// | |
137 | ||
138 | // ************************************************************************** // | |
139 | // ************** print_helper ************** // | |
140 | // ************************************************************************** // | |
141 | // Adds level of indirection to the output operation, allowing us to customize | |
142 | // it for types that do not support operator << directly or for any other reason | |
143 | ||
144 | template<typename T> | |
145 | struct print_helper_t { | |
146 | explicit print_helper_t( T const& t ) : m_t( t ) {} | |
147 | ||
148 | T const& m_t; | |
149 | }; | |
150 | ||
151 | //____________________________________________________________________________// | |
152 | ||
153 | #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) | |
154 | // Borland suffers premature pointer decay passing arrays by reference | |
155 | template<typename T, std::size_t N > | |
156 | struct print_helper_t< T[N] > { | |
157 | explicit print_helper_t( T const * t ) : m_t( t ) {} | |
158 | ||
159 | T const * m_t; | |
160 | }; | |
161 | #endif | |
162 | ||
163 | //____________________________________________________________________________// | |
164 | ||
165 | template<typename T> | |
166 | inline print_helper_t<T> | |
167 | print_helper( T const& t ) | |
168 | { | |
169 | return print_helper_t<T>( t ); | |
170 | } | |
171 | ||
172 | //____________________________________________________________________________// | |
173 | ||
174 | template<typename T> | |
175 | inline std::ostream& | |
176 | operator<<( std::ostream& ostr, print_helper_t<T> const& ph ) | |
177 | { | |
178 | print_log_value<T>()( ostr, ph.m_t ); | |
179 | ||
180 | return ostr; | |
181 | } | |
182 | ||
183 | //____________________________________________________________________________// | |
184 | ||
185 | } // namespace tt_detail | |
186 | ||
187 | // ************************************************************************** // | |
188 | // ************** BOOST_TEST_DONT_PRINT_LOG_VALUE ************** // | |
189 | // ************************************************************************** // | |
190 | ||
191 | #define BOOST_TEST_DONT_PRINT_LOG_VALUE( the_type ) \ | |
192 | namespace boost{ namespace test_tools{ namespace tt_detail{ \ | |
193 | template<> \ | |
194 | struct print_log_value<the_type > { \ | |
195 | void operator()( std::ostream&, the_type const& ) {} \ | |
196 | }; \ | |
197 | }}} \ | |
198 | /**/ | |
199 | ||
200 | } // namespace test_tools | |
201 | } // namespace boost | |
202 | ||
203 | #include <boost/test/detail/enable_warnings.hpp> | |
204 | ||
205 | #endif // BOOST_TEST_TOOLS_IMPL_COMMON_HPP_012705GER |