Line data Source code
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 : 22 : // Boost 23 : #include <boost/mpl/or.hpp> 24 : #include <boost/static_assert.hpp> 25 : #include <boost/type_traits/is_array.hpp> 26 : #include <boost/type_traits/is_function.hpp> 27 : #include <boost/type_traits/is_abstract.hpp> 28 : #include <boost/type_traits/has_left_shift.hpp> 29 : 30 : #include <ios> 31 : #include <iostream> 32 : #include <limits> 33 : 34 : #if !defined(BOOST_NO_CXX11_NULLPTR) 35 : #include <cstddef> 36 : #endif 37 : 38 : #include <boost/test/detail/suppress_warnings.hpp> 39 : 40 : //____________________________________________________________________________// 41 : 42 : namespace boost { 43 : namespace test_tools { 44 : namespace tt_detail { 45 : 46 : // ************************************************************************** // 47 : // ************** boost_test_print_type ************** // 48 : // ************************************************************************** // 49 : 50 : namespace impl { 51 : template <class T> 52 227 : std::ostream& boost_test_print_type(std::ostream& ostr, T const& t) { 53 : BOOST_STATIC_ASSERT_MSG( (boost::has_left_shift<std::ostream,T>::value), 54 : "Type has to implement operator<< to be printable"); 55 227 : ostr << t; 56 227 : return ostr; 57 0 : } 58 : 59 : struct boost_test_print_type_impl { 60 : template <class R> 61 227 : std::ostream& operator()(std::ostream& ostr, R const& r) const { 62 227 : return boost_test_print_type(ostr, r); 63 : } 64 : }; 65 : } 66 : 67 : // To avoid ODR violations, see N4381 68 : template <class T> struct static_const { static const T value; }; 69 : template <class T> const T static_const<T>::value = T(); 70 : 71 : namespace { 72 : static const impl::boost_test_print_type_impl& boost_test_print_type = 73 : static_const<impl::boost_test_print_type_impl>::value; 74 : } 75 : 76 : 77 : // ************************************************************************** // 78 : // ************** print_log_value ************** // 79 : // ************************************************************************** // 80 : 81 : template<typename T> 82 : struct print_log_value { 83 227 : void operator()( std::ostream& ostr, T const& t ) 84 : { 85 : typedef typename mpl::or_<is_array<T>,is_function<T>,is_abstract<T> >::type cant_use_nl; 86 : 87 227 : std::streamsize old_precision = set_precision( ostr, cant_use_nl() ); 88 : 89 : //ostr << t; 90 : using boost::test_tools::tt_detail::boost_test_print_type; 91 227 : boost_test_print_type(ostr, t); 92 : 93 227 : if( old_precision != (std::streamsize)-1 ) 94 15 : ostr.precision( old_precision ); 95 227 : } 96 : 97 121 : std::streamsize set_precision( std::ostream& ostr, mpl::false_ ) 98 : { 99 : if( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 2 ) 100 15 : return ostr.precision( 2 + std::streamsize(std::numeric_limits<T>::digits) * 301/1000 ); 101 : else if ( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 10 ) { 102 : #ifdef BOOST_NO_CXX11_NUMERIC_LIMITS 103 : // (was BOOST_NO_NUMERIC_LIMITS_LOWEST but now deprecated). 104 : // No support for std::numeric_limits<double>::max_digits10, 105 : // so guess that a couple of guard digits more than digits10 will display any difference. 106 : return ostr.precision( 2 + std::numeric_limits<T>::digits10 ); 107 : #else 108 : // std::numeric_limits<double>::max_digits10; IS supported. 109 : // Any noisy or guard digits needed to display any difference are included in max_digits10. 110 : return ostr.precision( std::numeric_limits<T>::max_digits10 ); 111 : #endif 112 : } 113 : // else if T is not specialized for std::numeric_limits<>, 114 : // then will just get the default precision of 6 digits. 115 106 : return (std::streamsize)-1; 116 : } 117 : 118 106 : std::streamsize set_precision( std::ostream&, mpl::true_ ) { return (std::streamsize)-1; } 119 : }; 120 : 121 : //____________________________________________________________________________// 122 : 123 : #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) 124 : template<typename T, std::size_t N > 125 : struct print_log_value< T[N] > { 126 : void operator()( std::ostream& ostr, T const* t ) 127 : { 128 : ostr << t; 129 : } 130 : }; 131 : #endif 132 : 133 : //____________________________________________________________________________// 134 : 135 : template<> 136 : struct BOOST_TEST_DECL print_log_value<bool> { 137 : void operator()( std::ostream& ostr, bool t ); 138 : }; 139 : 140 : //____________________________________________________________________________// 141 : 142 : template<> 143 : struct BOOST_TEST_DECL print_log_value<char> { 144 : void operator()( std::ostream& ostr, char t ); 145 : }; 146 : 147 : //____________________________________________________________________________// 148 : 149 : template<> 150 : struct BOOST_TEST_DECL print_log_value<unsigned char> { 151 : void operator()( std::ostream& ostr, unsigned char t ); 152 : }; 153 : 154 : //____________________________________________________________________________// 155 : 156 : template<> 157 : struct BOOST_TEST_DECL print_log_value<wchar_t> { 158 : void operator()( std::ostream& ostr, wchar_t t ); 159 : }; 160 : 161 : //____________________________________________________________________________// 162 : 163 : template<> 164 : struct BOOST_TEST_DECL print_log_value<char const*> { 165 : void operator()( std::ostream& ostr, char const* t ); 166 : }; 167 : 168 : //____________________________________________________________________________// 169 : 170 : template<> 171 : struct BOOST_TEST_DECL print_log_value<wchar_t const*> { 172 : void operator()( std::ostream& ostr, wchar_t const* t ); 173 : }; 174 : 175 : #if !defined(BOOST_NO_CXX11_NULLPTR) 176 : template<> 177 : struct print_log_value<std::nullptr_t> { 178 : // declaration and definition is here because of #12969 https://svn.boost.org/trac10/ticket/12969 179 0 : void operator()( std::ostream& ostr, std::nullptr_t /*t*/ ) { 180 0 : ostr << "nullptr"; 181 0 : } 182 : }; 183 : #endif 184 : 185 : //____________________________________________________________________________// 186 : 187 : // ************************************************************************** // 188 : // ************** print_helper ************** // 189 : // ************************************************************************** // 190 : // Adds level of indirection to the output operation, allowing us to customize 191 : // it for types that do not support operator << directly or for any other reason 192 : 193 : template<typename T> 194 : struct print_helper_t { 195 8752578 : explicit print_helper_t( T const& t ) : m_t( t ) {} 196 : 197 : T const& m_t; 198 : }; 199 : 200 : //____________________________________________________________________________// 201 : 202 : #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) 203 : // Borland suffers premature pointer decay passing arrays by reference 204 : template<typename T, std::size_t N > 205 : struct print_helper_t< T[N] > { 206 : explicit print_helper_t( T const * t ) : m_t( t ) {} 207 : 208 : T const * m_t; 209 : }; 210 : #endif 211 : 212 : //____________________________________________________________________________// 213 : 214 : template<typename T> 215 : inline print_helper_t<T> 216 4376289 : print_helper( T const& t ) 217 : { 218 4376289 : return print_helper_t<T>( t ); 219 : } 220 : 221 : //____________________________________________________________________________// 222 : 223 : template<typename T> 224 : inline std::ostream& 225 227 : operator<<( std::ostream& ostr, print_helper_t<T> const& ph ) 226 : { 227 227 : print_log_value<T>()( ostr, ph.m_t ); 228 : 229 227 : return ostr; 230 : } 231 : 232 : //____________________________________________________________________________// 233 : 234 : } // namespace tt_detail 235 : 236 : // ************************************************************************** // 237 : // ************** BOOST_TEST_DONT_PRINT_LOG_VALUE ************** // 238 : // ************************************************************************** // 239 : 240 : #define BOOST_TEST_DONT_PRINT_LOG_VALUE( the_type ) \ 241 : namespace boost{ namespace test_tools{ namespace tt_detail{ \ 242 : template<> \ 243 : struct print_log_value<the_type > { \ 244 : void operator()( std::ostream&, the_type const& ) {} \ 245 : }; \ 246 : }}} \ 247 : /**/ 248 : 249 : } // namespace test_tools 250 : } // namespace boost 251 : 252 : #include <boost/test/detail/enable_warnings.hpp> 253 : 254 : #endif // BOOST_TEST_TOOLS_IMPL_COMMON_HPP_012705GER