File: ios_state_test.cpp

package info (click to toggle)
boost1.35 1.35.0-5
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 203,856 kB
  • ctags: 337,867
  • sloc: cpp: 938,683; xml: 56,847; ansic: 41,589; python: 18,999; sh: 11,566; makefile: 664; perl: 494; yacc: 456; asm: 353; csh: 6
file content (256 lines) | stat: -rw-r--r-- 8,529 bytes parent folder | download | duplicates (8)
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
//  Boost ios_state_test.cpp test file  --------------------------------------//

//  Copyright 2002, 2003 Daryle Walker.  Use, modification, and distribution are
//  subject to the Boost Software License, Version 1.0.  (See accompanying file
//  LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)

//  See <http://www.boost.org/libs/io/> for the library's home page.

//  Revision History
//   15 Jun 2003  Adjust to changes in Boost.Test (Daryle Walker)
//   26 Feb 2002  Initial version (Daryle Walker)

#include <boost/test/minimal.hpp>  // main, BOOST_CHECK, etc.

#include <boost/cstdlib.hpp>       // for boost::exit_success
#include <boost/io/ios_state.hpp>  // for boost::io::ios_flags_saver, etc.

#include <cstddef>    // for std::size_t
#include <iomanip>    // for std::setw
#include <ios>        // for std::ios_base, std::streamsize, etc.
#include <iostream>   // for std::cout, etc.
#include <istream>    // for std::istream
#include <locale>     // for std::numpunct, std::locale
#include <ostream>    // for std::endl, std::ostream
#include <streambuf>  // for std::streambuf
#include <string>     // for std::string


// Facet with the bool names spelled backwards
class backward_bool_names
    : public std::numpunct<char>
{
    typedef std::numpunct<char>  base_type;

public:
    explicit  backward_bool_names( std::size_t refs = 0 )
        : base_type( refs )
        {}

protected:
    virtual ~backward_bool_names() {}

    virtual  base_type::string_type  do_truename() const
        { return "eurt"; }
    virtual  base_type::string_type  do_falsename() const
        { return "eslaf"; }
};


// Index to test custom storage
int const  my_index = std::ios_base::xalloc();

// Test data
char const    test_string[] = "Hello world";
int const     test_num1 = -16;
double const  test_num2 = 34.5678901234;
bool const    test_bool = true;


// Function prototypes
void  saver_tests_1( std::istream &input, std::ostream &output,
 std::ostream &err );
void  saver_tests_2( std::istream &input, std::ostream &output,
 std::ostream &err );


// Test program
int
test_main
(
    int         ,   // "argc" is unused
    char *      []  // "argv" is unused
)
{
    using std::cout;
    using std::ios_base;
    using std::streamsize;
    using std::cin;

    cout << "The original data is:\n";
    cout << '\t' << test_string << '\n';
    cout << '\t' << test_num1 << '\n';
    cout << '\t' << test_num2 << '\n';
    cout << '\t' << std::boolalpha << test_bool << std::endl;

    // Save states for comparison later
    ios_base::fmtflags const  cout_flags = cout.flags();
    streamsize const          cout_precision = cout.precision();
    streamsize const          cout_width = cout.width();
    ios_base::iostate const   cout_iostate = cout.rdstate();
    ios_base::iostate const   cout_exceptions = cout.exceptions();
    std::ostream * const      cin_tie = cin.tie();
    std::streambuf * const    cout_sb = cout.rdbuf();
    char const                cout_fill = cout.fill();
    std::locale const         cout_locale = cout.getloc();

    cout.iword( my_index ) = 42L;
    cout.pword( my_index ) = &cin;

    // Run saver tests with changing separate from saving
    saver_tests_1( cin, cout, std::cerr );

    // Check if states are back to normal
    BOOST_CHECK( &cin == cout.pword(my_index) );
    BOOST_CHECK( 42L == cout.iword(my_index) );
    BOOST_CHECK( cout_locale == cout.getloc() );
    BOOST_CHECK( cout_fill == cout.fill() );
    BOOST_CHECK( cout_sb == cout.rdbuf() );
    BOOST_CHECK( cin_tie == cin.tie() );
    BOOST_CHECK( cout_exceptions == cout.exceptions() );
    BOOST_CHECK( cout_iostate == cout.rdstate() );
    BOOST_CHECK( cout_width == cout.width() );
    BOOST_CHECK( cout_precision == cout.precision() );
    BOOST_CHECK( cout_flags == cout.flags() );

    // Run saver tests with combined saving and changing
    saver_tests_2( cin, cout, std::cerr );

    // Check if states are back to normal
    BOOST_CHECK( &cin == cout.pword(my_index) );
    BOOST_CHECK( 42L == cout.iword(my_index) );
    BOOST_CHECK( cout_locale == cout.getloc() );
    BOOST_CHECK( cout_fill == cout.fill() );
    BOOST_CHECK( cout_sb == cout.rdbuf() );
    BOOST_CHECK( cin_tie == cin.tie() );
    BOOST_CHECK( cout_exceptions == cout.exceptions() );
    BOOST_CHECK( cout_iostate == cout.rdstate() );
    BOOST_CHECK( cout_width == cout.width() );
    BOOST_CHECK( cout_precision == cout.precision() );
    BOOST_CHECK( cout_flags == cout.flags() );

    return boost::exit_success;
}

// Save, change, and restore stream properties
void
saver_tests_1
(
    std::istream &  input,
    std::ostream &  output,
    std::ostream &  err
)
{
    using std::locale;
    using std::ios_base;
    using std::setw;

    boost::io::ios_flags_saver const      ifls( output );
    boost::io::ios_precision_saver const  iprs( output );
    boost::io::ios_width_saver const      iws( output );
    boost::io::ios_tie_saver const        its( input );
    boost::io::ios_rdbuf_saver const      irs( output );
    boost::io::ios_fill_saver const       ifis( output );
    boost::io::ios_locale_saver const     ils( output );
    boost::io::ios_iword_saver const      iis( output, my_index );
    boost::io::ios_pword_saver const      ipws( output, my_index );

    locale  loc( locale::classic(), new backward_bool_names );

    input.tie( &err );
    output.rdbuf( err.rdbuf() );
    output.iword( my_index ) = 69L;
    output.pword( my_index ) = &err;

    output << "The data is (again):\n";
    output.setf( ios_base::showpos | ios_base::boolalpha );
    output.setf( ios_base::internal, ios_base::adjustfield );
    output.fill( '@' );
    output.precision( 9 );
    output << '\t' << test_string << '\n';
    output << '\t' << setw( 10 ) << test_num1 << '\n';
    output << '\t' << setw( 15 ) << test_num2 << '\n';
    output.imbue( loc );
    output << '\t' << test_bool << '\n';

    BOOST_CHECK( &err == output.pword(my_index) );
    BOOST_CHECK( 69L == output.iword(my_index) );

    try
    {
        boost::io::ios_exception_saver const  ies( output );
        boost::io::ios_iostate_saver const    iis( output );

        output.exceptions( ios_base::eofbit );
        output.setstate( ios_base::eofbit );
        BOOST_ERROR( "previous line should have thrown" );
    }
    catch ( ios_base::failure &f )
    {
        err << "Got the expected I/O failure: \"" << f.what() << "\".\n";
        BOOST_CHECK( output.exceptions() == ios_base::goodbit );
    }
    catch ( ... )
    {
        err << "Got an unknown error when doing exception test!\n";
        throw;
    }
}

// Save & change and restore stream properties
void
saver_tests_2
(
    std::istream &  input,
    std::ostream &  output,
    std::ostream &  err
)
{
    using std::locale;
    using std::ios_base;

    boost::io::ios_tie_saver const    its( input, &err );
    boost::io::ios_rdbuf_saver const  irs( output, err.rdbuf() );
    boost::io::ios_iword_saver const  iis( output, my_index, 69L );
    boost::io::ios_pword_saver const  ipws( output, my_index, &err );
    output << "The data is (a third time; adding the numbers):\n";

    boost::io::ios_flags_saver const      ifls( output, (output.flags()
     & ~ios_base::adjustfield) | ios_base::showpos | ios_base::boolalpha
     | (ios_base::internal & ios_base::adjustfield) );
    boost::io::ios_precision_saver const  iprs( output, 9 );
    boost::io::ios_fill_saver const       ifis( output, '@' );
    output << '\t' << test_string << '\n';

    boost::io::ios_width_saver const  iws( output, 12 );
    output.put( '\t' );
    output << test_num1 + test_num2;
    output.put( '\n' );

    locale                             loc( locale::classic(),
     new backward_bool_names );
    boost::io::ios_locale_saver const  ils( output, loc );
    output << '\t' << test_bool << '\n';

    BOOST_CHECK( &err == output.pword(my_index) );
    BOOST_CHECK( 69L == output.iword(my_index) );

    try
    {
        boost::io::ios_exception_saver const  ies( output, ios_base::eofbit  );
        boost::io::ios_iostate_saver const    iis( output, output.rdstate()
         | ios_base::eofbit );

        BOOST_ERROR( "previous line should have thrown" );
    }
    catch ( ios_base::failure &f )
    {
        err << "Got the expected I/O failure: \"" << f.what() << "\".\n";
        BOOST_CHECK( output.exceptions() == ios_base::goodbit );
    }
    catch ( ... )
    {
        err << "Got an unknown error when doing exception test!\n";
        throw;
    }
}