File indexing completed on 2025-07-05 08:49:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef BOOST_TEST_TEST_TOOLS_IPP_012205GER
0016 #define BOOST_TEST_TEST_TOOLS_IPP_012205GER
0017
0018
0019 #include <boost/test/test_tools.hpp>
0020 #include <boost/test/unit_test_log.hpp>
0021 #include <boost/test/tools/context.hpp>
0022 #include <boost/test/tools/output_test_stream.hpp>
0023
0024 #include <boost/test/tools/detail/fwd.hpp>
0025 #include <boost/test/tools/detail/print_helper.hpp>
0026
0027 #include <boost/test/framework.hpp>
0028 #include <boost/test/tree/test_unit.hpp>
0029 #include <boost/test/execution_monitor.hpp> // execution_aborted
0030
0031 #include <boost/test/detail/throw_exception.hpp>
0032
0033 #include <boost/test/utils/algorithm.hpp>
0034
0035
0036 #include <boost/config.hpp>
0037
0038
0039 #include <fstream>
0040 #include <string>
0041 #include <cstring>
0042 #include <cctype>
0043 #include <cwchar>
0044 #include <stdexcept>
0045 #include <vector>
0046 #include <utility>
0047 #include <ios>
0048
0049
0050 #include <stdarg.h>
0051
0052 #include <boost/test/detail/suppress_warnings.hpp>
0053
0054
0055
0056 # ifdef BOOST_NO_STDC_NAMESPACE
0057 namespace std { using ::strcmp; using ::strlen; using ::isprint; }
0058 #if !defined( BOOST_NO_CWCHAR )
0059 namespace std { using ::wcscmp; }
0060 #endif
0061 # endif
0062
0063
0064 namespace boost {
0065 namespace unit_test {
0066
0067 lazy_ostream lazy_ostream::inst = lazy_ostream();
0068 }}
0069
0070 namespace boost {
0071 namespace test_tools {
0072 namespace tt_detail {
0073
0074
0075
0076
0077
0078 void
0079 print_log_value<bool>::operator()( std::ostream& ostr, bool t )
0080 {
0081 ostr << std::boolalpha << t;
0082 }
0083
0084 void
0085 print_log_value<char>::operator()( std::ostream& ostr, char t )
0086 {
0087 if( (std::isprint)( static_cast<unsigned char>(t) ) )
0088 ostr << '\'' << t << '\'';
0089 else
0090 ostr << std::hex
0091 #if BOOST_TEST_USE_STD_LOCALE
0092 << std::showbase
0093 #else
0094 << "0x"
0095 #endif
0096 << static_cast<int>(t);
0097 }
0098
0099
0100
0101 void
0102 print_log_value<unsigned char>::operator()( std::ostream& ostr, unsigned char t )
0103 {
0104 ostr << std::hex
0105
0106 #if BOOST_TEST_USE_STD_LOCALE
0107 << std::showbase
0108 #else
0109 << "0x"
0110 #endif
0111 << static_cast<int>(t);
0112 }
0113
0114
0115
0116 void
0117 print_log_value<wchar_t>::operator()( std::ostream& ostr, wchar_t r )
0118 {
0119 std::mbstate_t state;
0120 std::string mb(MB_CUR_MAX, '\0');
0121 std::size_t ret = std::wcrtomb(&mb[0], r, &state);
0122 if( ret > 0) {
0123 ostr << mb;
0124 }
0125 else {
0126 ostr << "(wchar_t unable to convert)";
0127 }
0128 }
0129
0130
0131
0132 void
0133 print_log_value<char const*>::operator()( std::ostream& ostr, char const* t )
0134 {
0135 ostr << ( t ? t : "null string" );
0136 }
0137
0138
0139
0140 void
0141 print_log_value<wchar_t const*>::operator()( std::ostream& ostr, wchar_t const* t )
0142 {
0143 if(t) {
0144 ostr << static_cast<const void*>(t);
0145 }
0146 else {
0147 ostr << "null w-string";
0148 }
0149 }
0150
0151
0152
0153
0154
0155
0156
0157 using ::boost::unit_test::lazy_ostream;
0158
0159 static char const* check_str [] = { " == ", " != ", " < " , " <= ", " > " , " >= " };
0160 static char const* rever_str [] = { " != ", " == ", " >= ", " > " , " <= ", " < " };
0161
0162 template<typename OutStream>
0163 void
0164 format_report( OutStream& os, assertion_result const& pr, unit_test::lazy_ostream const& assertion_descr,
0165 tool_level tl, check_type ct,
0166 std::size_t num_args, va_list args,
0167 char const* prefix, char const* suffix )
0168 {
0169 using namespace unit_test;
0170
0171 switch( ct ) {
0172 case CHECK_PRED:
0173 os << prefix << assertion_descr << suffix;
0174
0175 if( !pr.has_empty_message() )
0176 os << ". " << pr.message();
0177 break;
0178
0179 case CHECK_BUILT_ASSERTION: {
0180 os << prefix << assertion_descr << suffix;
0181
0182 if( tl != PASS ) {
0183 const_string details_message = pr.message();
0184
0185 if( !details_message.is_empty() ) {
0186 os << details_message;
0187 }
0188 }
0189 break;
0190 }
0191
0192 case CHECK_MSG:
0193 if( tl == PASS )
0194 os << prefix << "'" << assertion_descr << "'" << suffix;
0195 else
0196 os << assertion_descr;
0197
0198 if( !pr.has_empty_message() )
0199 os << ". " << pr.message();
0200 break;
0201
0202 case CHECK_EQUAL:
0203 case CHECK_NE:
0204 case CHECK_LT:
0205 case CHECK_LE:
0206 case CHECK_GT:
0207 case CHECK_GE: {
0208 char const* arg1_descr = va_arg( args, char const* );
0209 lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
0210 char const* arg2_descr = va_arg( args, char const* );
0211 lazy_ostream const* arg2_val = va_arg( args, lazy_ostream const* );
0212
0213 os << prefix << arg1_descr << check_str[ct-CHECK_EQUAL] << arg2_descr << suffix;
0214
0215 if( tl != PASS )
0216 os << " [" << *arg1_val << rever_str[ct-CHECK_EQUAL] << *arg2_val << "]" ;
0217
0218 if( !pr.has_empty_message() )
0219 os << ". " << pr.message();
0220 break;
0221 }
0222
0223 case CHECK_CLOSE:
0224 case CHECK_CLOSE_FRACTION: {
0225 char const* arg1_descr = va_arg( args, char const* );
0226 lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
0227 char const* arg2_descr = va_arg( args, char const* );
0228 lazy_ostream const* arg2_val = va_arg( args, lazy_ostream const* );
0229 va_arg( args, char const* );
0230 lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* );
0231
0232 os << "difference{" << pr.message()
0233 << "} between " << arg1_descr << "{" << *arg1_val
0234 << "} and " << arg2_descr << "{" << *arg2_val
0235 << ( tl == PASS ? "} doesn't exceed " : "} exceeds " )
0236 << *toler_val;
0237 if( ct == CHECK_CLOSE )
0238 os << "%";
0239 break;
0240 }
0241 case CHECK_SMALL: {
0242 char const* arg1_descr = va_arg( args, char const* );
0243 lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
0244 va_arg( args, char const* );
0245 lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* );
0246
0247 os << "absolute value of " << arg1_descr << "{" << *arg1_val << "}"
0248 << ( tl == PASS ? " doesn't exceed " : " exceeds " )
0249 << *toler_val;
0250
0251 if( !pr.has_empty_message() )
0252 os << ". " << pr.message();
0253 break;
0254 }
0255
0256 case CHECK_PRED_WITH_ARGS: {
0257 std::vector< std::pair<char const*, lazy_ostream const*> > args_copy;
0258 args_copy.reserve( num_args );
0259 for( std::size_t i = 0; i < num_args; ++i ) {
0260 char const* desc = va_arg( args, char const* );
0261 lazy_ostream const* value = va_arg( args, lazy_ostream const* );
0262 args_copy.push_back( std::make_pair( desc, value ) );
0263 }
0264
0265 os << prefix << assertion_descr;
0266
0267
0268 os << "( ";
0269 for( std::size_t i = 0; i < num_args; ++i ) {
0270 os << args_copy[i].first;
0271
0272 if( i != num_args-1 )
0273 os << ", ";
0274 }
0275 os << " )" << suffix;
0276
0277 if( tl != PASS ) {
0278 os << " for ( ";
0279 for( std::size_t i = 0; i < num_args; ++i ) {
0280 os << *args_copy[i].second;
0281
0282 if( i != num_args-1 )
0283 os << ", ";
0284 }
0285 os << " )";
0286 }
0287
0288 if( !pr.has_empty_message() )
0289 os << ". " << pr.message();
0290 break;
0291 }
0292
0293 case CHECK_EQUAL_COLL: {
0294 char const* left_begin_descr = va_arg( args, char const* );
0295 char const* left_end_descr = va_arg( args, char const* );
0296 char const* right_begin_descr = va_arg( args, char const* );
0297 char const* right_end_descr = va_arg( args, char const* );
0298
0299 os << prefix << "{ " << left_begin_descr << ", " << left_end_descr << " } == { "
0300 << right_begin_descr << ", " << right_end_descr << " }"
0301 << suffix;
0302
0303 if( !pr.has_empty_message() )
0304 os << ". " << pr.message();
0305 break;
0306 }
0307
0308 case CHECK_BITWISE_EQUAL: {
0309 char const* left_descr = va_arg( args, char const* );
0310 char const* right_descr = va_arg( args, char const* );
0311
0312 os << prefix << left_descr << " =.= " << right_descr << suffix;
0313
0314 if( !pr.has_empty_message() )
0315 os << ". " << pr.message();
0316 break;
0317 }
0318 }
0319 }
0320
0321
0322
0323 #ifdef BOOST_MSVC
0324 #pragma warning(push)
0325 #pragma warning(disable : 4702)
0326 #endif
0327
0328 bool
0329 report_assertion( assertion_result const& ar,
0330 lazy_ostream const& assertion_descr,
0331 const_string file_name,
0332 std::size_t line_num,
0333 tool_level tl,
0334 check_type ct,
0335 std::size_t num_args, ... )
0336 {
0337 using namespace unit_test;
0338
0339 if( !framework::test_in_progress() ) {
0340
0341
0342
0343
0344
0345
0346
0347
0348 framework::test_aborted();
0349 return false;
0350 }
0351
0352
0353 if( !!ar )
0354 tl = PASS;
0355
0356 log_level ll;
0357 char const* prefix;
0358 char const* suffix;
0359
0360 switch( tl ) {
0361 case PASS:
0362 ll = log_successful_tests;
0363 prefix = "check ";
0364 suffix = " has passed";
0365 break;
0366 case WARN:
0367 ll = log_warnings;
0368 prefix = "condition ";
0369 suffix = " is not satisfied";
0370 break;
0371 case CHECK:
0372 ll = log_all_errors;
0373 prefix = "check ";
0374 suffix = " has failed";
0375 break;
0376 case REQUIRE:
0377 ll = log_fatal_errors;
0378 prefix = "critical check ";
0379 suffix = " has failed";
0380 break;
0381 default:
0382 return true;
0383 }
0384
0385 unit_test_log << unit_test::log::begin( file_name, line_num ) << ll;
0386 va_list args;
0387 va_start( args, num_args );
0388
0389 format_report( unit_test_log, ar, assertion_descr, tl, ct, num_args, args, prefix, suffix );
0390
0391 va_end( args );
0392 unit_test_log << unit_test::log::end();
0393
0394 switch( tl ) {
0395 case PASS:
0396 framework::assertion_result( AR_PASSED );
0397 return true;
0398
0399 case WARN:
0400 framework::assertion_result( AR_TRIGGERED );
0401 return false;
0402
0403 case CHECK:
0404 framework::assertion_result( AR_FAILED );
0405 return false;
0406
0407 case REQUIRE:
0408 framework::assertion_result( AR_FAILED );
0409 framework::test_unit_aborted( framework::current_test_unit() );
0410 BOOST_TEST_I_THROW( execution_aborted() );
0411
0412
0413 BOOST_TEST_UNREACHABLE_RETURN(false);
0414 }
0415
0416 return true;
0417 }
0418
0419 #ifdef BOOST_MSVC
0420 #pragma warning(pop)
0421 #endif
0422
0423
0424
0425 assertion_result
0426 format_assertion_result( const_string expr_val, const_string details )
0427 {
0428 assertion_result res(false);
0429
0430 bool starts_new_line = first_char( expr_val ) == '\n';
0431
0432 if( !starts_new_line && !expr_val.is_empty() )
0433 res.message().stream() << " [" << expr_val << "]";
0434
0435 if( !details.is_empty() ) {
0436 if( first_char(details) != '[' )
0437 res.message().stream() << ": ";
0438 else
0439 res.message().stream() << " ";
0440
0441 res.message().stream() << details;
0442 }
0443
0444 if( starts_new_line )
0445 res.message().stream() << "." << expr_val;
0446
0447 return res;
0448 }
0449
0450
0451
0452 BOOST_TEST_DECL std::string
0453 prod_report_format( assertion_result const& ar, unit_test::lazy_ostream const& assertion_descr, check_type ct, std::size_t num_args, ... )
0454 {
0455 std::ostringstream msg_buff;
0456
0457 va_list args;
0458 va_start( args, num_args );
0459
0460 format_report( msg_buff, ar, assertion_descr, CHECK, ct, num_args, args, "assertion ", " failed" );
0461
0462 va_end( args );
0463
0464 return msg_buff.str();
0465 }
0466
0467
0468
0469 assertion_result
0470 equal_impl( char const* left, char const* right )
0471 {
0472 return (left && right) ? std::strcmp( left, right ) == 0 : (left == right);
0473 }
0474
0475
0476
0477 #if !defined( BOOST_NO_CWCHAR )
0478
0479 assertion_result
0480 equal_impl( wchar_t const* left, wchar_t const* right )
0481 {
0482 return (left && right) ? std::wcscmp( left, right ) == 0 : (left == right);
0483 }
0484
0485 #endif
0486
0487
0488
0489 bool
0490 is_defined_impl( const_string symbol_name, const_string symbol_value )
0491 {
0492 symbol_value.trim_left( 2 );
0493 return symbol_name != symbol_value;
0494 }
0495
0496
0497
0498
0499
0500
0501
0502 context_frame::context_frame( ::boost::unit_test::lazy_ostream const& context_descr )
0503 : m_frame_id( unit_test::framework::add_context( context_descr, true ) )
0504 {
0505 }
0506
0507
0508
0509 context_frame::~context_frame()
0510 {
0511 unit_test::framework::clear_context( m_frame_id );
0512 }
0513
0514
0515
0516 context_frame::operator bool()
0517 {
0518 return true;
0519 }
0520
0521
0522
0523 }
0524
0525
0526
0527
0528
0529 struct output_test_stream::Impl
0530 {
0531 std::fstream m_pattern;
0532 bool m_match_or_save;
0533 bool m_text_or_binary;
0534 std::string m_synced_string;
0535
0536 char get_char()
0537 {
0538 char res = 0;
0539 do {
0540 m_pattern.get( res );
0541 } while( m_text_or_binary && res == '\r' && !m_pattern.fail() && !m_pattern.eof() );
0542
0543 return res;
0544 }
0545
0546 void check_and_fill( assertion_result& res )
0547 {
0548 if( !res.p_predicate_value )
0549 res.message() << "Output content: \"" << m_synced_string << '\"';
0550 }
0551 };
0552
0553
0554
0555 output_test_stream::output_test_stream( const_string pattern_file_name, bool match_or_save, bool text_or_binary )
0556 : m_pimpl( new Impl )
0557 {
0558 if( !pattern_file_name.is_empty() ) {
0559 std::ios::openmode m = match_or_save ? std::ios::in : std::ios::out;
0560 if( !text_or_binary )
0561 m |= std::ios::binary;
0562
0563 m_pimpl->m_pattern.open( pattern_file_name.begin(), m );
0564
0565 if( !m_pimpl->m_pattern.is_open() )
0566 BOOST_TEST_FRAMEWORK_MESSAGE( "Can't open pattern file " << pattern_file_name << " for " << (match_or_save ? "reading" : "writing") );
0567 }
0568
0569 m_pimpl->m_match_or_save = match_or_save;
0570 m_pimpl->m_text_or_binary = text_or_binary;
0571 }
0572
0573
0574
0575 output_test_stream::~output_test_stream()
0576 {
0577 delete m_pimpl;
0578 }
0579
0580
0581
0582 assertion_result
0583 output_test_stream::is_empty( bool flush_stream )
0584 {
0585 sync();
0586
0587 assertion_result res( m_pimpl->m_synced_string.empty() );
0588
0589 m_pimpl->check_and_fill( res );
0590
0591 if( flush_stream )
0592 flush();
0593
0594 return res;
0595 }
0596
0597
0598
0599 assertion_result
0600 output_test_stream::check_length( std::size_t length_, bool flush_stream )
0601 {
0602 sync();
0603
0604 assertion_result res( m_pimpl->m_synced_string.length() == length_ );
0605
0606 m_pimpl->check_and_fill( res );
0607
0608 if( flush_stream )
0609 flush();
0610
0611 return res;
0612 }
0613
0614
0615
0616 assertion_result
0617 output_test_stream::is_equal( const_string arg, bool flush_stream )
0618 {
0619 sync();
0620
0621 assertion_result res( const_string( m_pimpl->m_synced_string ) == arg );
0622
0623 m_pimpl->check_and_fill( res );
0624
0625 if( flush_stream )
0626 flush();
0627
0628 return res;
0629 }
0630
0631
0632
0633 std::string pretty_print_log(std::string str) {
0634
0635 static const std::string to_replace[] = { "\r", "\n" };
0636 static const std::string replacement[] = { "\\r", "\\n" };
0637
0638 return unit_test::utils::replace_all_occurrences_of(
0639 str,
0640 to_replace, to_replace + sizeof(to_replace)/sizeof(to_replace[0]),
0641 replacement, replacement + sizeof(replacement)/sizeof(replacement[0]));
0642 }
0643
0644 assertion_result
0645 output_test_stream::match_pattern( bool flush_stream )
0646 {
0647 const std::string::size_type n_chars_presuffix = 10;
0648 sync();
0649
0650 assertion_result result( true );
0651
0652 const std::string stream_string_repr = get_stream_string_representation();
0653
0654 if( !m_pimpl->m_pattern.is_open() ) {
0655 result = false;
0656 result.message() << "Pattern file can't be opened!";
0657 }
0658 else {
0659 if( m_pimpl->m_match_or_save ) {
0660
0661 int offset = 0;
0662 std::vector<char> last_elements;
0663 for ( std::string::size_type i = 0; static_cast<int>(i + offset) < static_cast<int>(stream_string_repr.length()); ++i ) {
0664
0665 char c = m_pimpl->get_char();
0666
0667 if( last_elements.size() <= n_chars_presuffix ) {
0668 last_elements.push_back( c );
0669 }
0670 else {
0671 last_elements[ i % last_elements.size() ] = c;
0672 }
0673
0674 bool is_same = !m_pimpl->m_pattern.fail() &&
0675 !m_pimpl->m_pattern.eof() &&
0676 (stream_string_repr[i+offset] == c);
0677
0678 if( !is_same ) {
0679
0680 result = false;
0681
0682 std::string::size_type prefix_size = (std::min)( i + offset, n_chars_presuffix );
0683
0684 std::string::size_type suffix_size = (std::min)( stream_string_repr.length() - i - offset,
0685 n_chars_presuffix );
0686
0687
0688 std::string substr = stream_string_repr.substr(0, i+offset);
0689 std::size_t line = std::count(substr.begin(), substr.end(), '\n');
0690 std::size_t column = i + offset - substr.rfind('\n');
0691
0692 result.message()
0693 << "Mismatch at position " << i
0694 << " (line " << line
0695 << ", column " << column
0696 << "): '" << pretty_print_log(std::string(1, stream_string_repr[i+offset])) << "' != '" << pretty_print_log(std::string(1, c)) << "' :\n";
0697
0698
0699
0700 std::string sub_str_prefix(pretty_print_log(stream_string_repr.substr( i + offset - prefix_size, prefix_size )));
0701
0702
0703 std::string sub_str_suffix(stream_string_repr.substr( i + offset, suffix_size));
0704 result.message() << "... " << sub_str_prefix + pretty_print_log(sub_str_suffix) << " ..." << '\n';
0705
0706 result.message() << "... ";
0707 for( std::size_t j = 0; j < last_elements.size() ; j++ )
0708 result.message() << pretty_print_log(std::string(1, last_elements[(i + j + 1) % last_elements.size()]));
0709
0710 std::vector<char> last_elements_ordered;
0711 last_elements_ordered.push_back(c);
0712 for( std::string::size_type counter = 0; counter < suffix_size - 1 ; counter++ ) {
0713 char c2 = m_pimpl->get_char();
0714
0715 if( m_pimpl->m_pattern.fail() || m_pimpl->m_pattern.eof() )
0716 break;
0717
0718 result.message() << pretty_print_log(std::string(1, c2));
0719
0720 last_elements_ordered.push_back(c2);
0721 }
0722
0723
0724
0725 std::size_t max_nb_char_in_common = 0;
0726 std::size_t best_pattern_start_index = 0;
0727 std::size_t best_stream_start_index = 0;
0728 for( std::size_t pattern_start_index = best_pattern_start_index;
0729 pattern_start_index < last_elements_ordered.size();
0730 pattern_start_index++ ) {
0731 for( std::size_t stream_start_index = best_stream_start_index;
0732 stream_start_index < sub_str_suffix.size();
0733 stream_start_index++ ) {
0734
0735 std::size_t max_size = (std::min)( last_elements_ordered.size() - pattern_start_index, sub_str_suffix.size() - stream_start_index );
0736 if( max_nb_char_in_common > max_size )
0737 break;
0738
0739 std::size_t nb_char_in_common = 0;
0740 for( std::size_t k = 0; k < max_size; k++) {
0741 if( last_elements_ordered[pattern_start_index + k] == sub_str_suffix[stream_start_index + k] )
0742 nb_char_in_common ++;
0743 else
0744 break;
0745 }
0746
0747 if( nb_char_in_common > max_nb_char_in_common ) {
0748 max_nb_char_in_common = nb_char_in_common;
0749 best_pattern_start_index = pattern_start_index;
0750 best_stream_start_index = stream_start_index;
0751 }
0752 }
0753 }
0754
0755
0756 result.message() << " ...\n... ";
0757 for( std::string::size_type j = 0; j < sub_str_prefix.size(); j++) {
0758 result.message() << ' ';
0759 }
0760
0761 result.message() << '~';
0762
0763 for( std::size_t k = 1; k < (std::max)(best_pattern_start_index, best_stream_start_index); k++ ) {
0764 std::string s1(pretty_print_log(std::string(1, last_elements_ordered[(std::min)(k, best_pattern_start_index)])));
0765 std::string s2(pretty_print_log(std::string(1, sub_str_suffix[(std::min)(k, best_stream_start_index)])));
0766 for( int h = static_cast<int>((std::max)(s1.size(), s2.size())); h > 0; h--)
0767 result.message() << "~";
0768 }
0769
0770 if( m_pimpl->m_pattern.eof() ) {
0771 result.message() << " (reference string shorter than current stream)";
0772 }
0773
0774 result.message() << "\n";
0775
0776
0777 if( m_pimpl->m_pattern.eof() ) {
0778 break;
0779 }
0780
0781
0782 for(std::string::size_type counter = 0; counter < last_elements_ordered.size() - 1 ; counter++)
0783 last_elements[ (i + 1 + counter) % last_elements.size() ] = last_elements_ordered[counter + 1];
0784
0785 i += last_elements_ordered.size()-1;
0786 offset += best_stream_start_index - best_pattern_start_index;
0787
0788 }
0789
0790 }
0791
0792
0793
0794
0795
0796
0797
0798
0799 }
0800 else {
0801 m_pimpl->m_pattern.write( stream_string_repr.c_str(),
0802 static_cast<std::streamsize>( stream_string_repr.length() ) );
0803 m_pimpl->m_pattern.flush();
0804 }
0805 }
0806
0807 if( flush_stream )
0808 flush();
0809
0810 return result;
0811 }
0812
0813
0814
0815 void
0816 output_test_stream::flush()
0817 {
0818 m_pimpl->m_synced_string.erase();
0819
0820 #ifndef BOOST_NO_STRINGSTREAM
0821 str( std::string() );
0822 #else
0823 seekp( 0, std::ios::beg );
0824 #endif
0825 }
0826
0827
0828 std::string
0829 output_test_stream::get_stream_string_representation() const {
0830 return m_pimpl->m_synced_string;
0831 }
0832
0833
0834
0835 std::size_t
0836 output_test_stream::length()
0837 {
0838 sync();
0839
0840 return m_pimpl->m_synced_string.length();
0841 }
0842
0843
0844
0845 void
0846 output_test_stream::sync()
0847 {
0848 #ifdef BOOST_NO_STRINGSTREAM
0849 m_pimpl->m_synced_string.assign( str(), pcount() );
0850 freeze( false );
0851 #else
0852 m_pimpl->m_synced_string = str();
0853 #endif
0854 }
0855
0856
0857
0858 }
0859 }
0860
0861 #include <boost/test/detail/enable_warnings.hpp>
0862
0863 #endif