• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Copyright 2003 Daryle Walker
3 
4 Copyright 2019 Glen Joseph Fernandes
5 (glenjofe@gmail.com)
6 
7 Distributed under the Boost Software License, Version 1.0.
8 (http://www.boost.org/LICENSE_1_0.txt)
9 */
10 #include <boost/io/ios_state.hpp>
11 #include <boost/core/lightweight_test.hpp>
12 #include <boost/config.hpp>
13 #include <iomanip>
14 #include <ios>
15 #include <iostream>
16 #include <istream>
17 #include <locale>
18 #if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB))
19 #include <stdexcept>
20 #endif
21 #include <sstream>
22 #include <cstddef>
23 
24 class backward_bool_names
25     : public std::numpunct<char> {
26     typedef std::numpunct<char> base_type;
27 
28 public:
backward_bool_names(std::size_t refs=0)29     explicit backward_bool_names(std::size_t refs = 0)
30         : base_type(refs) { }
31 
32 protected:
~backward_bool_names()33     ~backward_bool_names() { }
34 
do_truename() const35     base_type::string_type do_truename() const {
36         return "eurt";
37     }
38 
do_falsename() const39     base_type::string_type do_falsename() const {
40         return "eslaf";
41     }
42 };
43 
44 void
ios_flags_saver_unit_test()45 ios_flags_saver_unit_test()
46 {
47     std::stringstream ss;
48     BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
49     {
50         boost::io::ios_flags_saver ifs(ss);
51         BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
52         ss << std::noskipws << std::fixed << std::boolalpha;
53         BOOST_TEST_EQ(std::ios_base::boolalpha |
54             std::ios_base::dec |
55             std::ios_base::fixed, ss.flags());
56     }
57     BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
58     {
59         boost::io::ios_flags_saver ifs(ss,
60             std::ios_base::showbase | std::ios_base::internal);
61         BOOST_TEST_EQ(std::ios_base::showbase |
62             std::ios_base::internal, ss.flags());
63         ss << std::setiosflags(std::ios_base::unitbuf);
64         BOOST_TEST_EQ(std::ios_base::showbase |
65             std::ios_base::internal |
66             std::ios_base::unitbuf, ss.flags());
67     }
68     BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
69 }
70 
71 void
ios_precision_saver_unit_test()72 ios_precision_saver_unit_test()
73 {
74     std::stringstream ss;
75     BOOST_TEST_EQ(6, ss.precision());
76     {
77         boost::io::ios_precision_saver ips(ss);
78         BOOST_TEST_EQ(6, ss.precision());
79         ss << std::setprecision(4);
80         BOOST_TEST_EQ(4, ss.precision());
81     }
82     BOOST_TEST_EQ(6, ss.precision());
83     {
84         boost::io::ios_precision_saver ips(ss, 8);
85         BOOST_TEST_EQ(8, ss.precision());
86         ss << std::setprecision(10);
87         BOOST_TEST_EQ(10, ss.precision());
88     }
89     BOOST_TEST_EQ(6, ss.precision());
90 }
91 
92 void
ios_width_saver_unit_test()93 ios_width_saver_unit_test()
94 {
95     std::stringstream ss;
96     BOOST_TEST_EQ(0, ss.width());
97     {
98         boost::io::ios_width_saver iws(ss);
99         BOOST_TEST_EQ(0, ss.width());
100         ss << std::setw(4);
101         BOOST_TEST_EQ(4, ss.width());
102     }
103     BOOST_TEST_EQ(0, ss.width());
104     {
105         boost::io::ios_width_saver iws(ss, 8);
106         BOOST_TEST_EQ(8, ss.width());
107         ss << std::setw(10);
108         BOOST_TEST_EQ(10, ss.width());
109     }
110     BOOST_TEST_EQ(0, ss.width());
111 }
112 
113 void
ios_iostate_saver_unit_test()114 ios_iostate_saver_unit_test()
115 {
116     std::stringstream ss;
117     BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
118     BOOST_TEST(ss.good());
119     {
120         boost::io::ios_iostate_saver iis(ss);
121         char c;
122         BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
123         BOOST_TEST(ss.good());
124         ss >> c;
125         BOOST_TEST_EQ(std::ios_base::eofbit | std::ios_base::failbit,
126             ss.rdstate());
127         BOOST_TEST(ss.eof());
128         BOOST_TEST(ss.fail());
129         BOOST_TEST(!ss.bad());
130     }
131     BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
132     BOOST_TEST(ss.good());
133     {
134         boost::io::ios_iostate_saver iis(ss, std::ios_base::eofbit);
135         BOOST_TEST_EQ(std::ios_base::eofbit, ss.rdstate());
136         BOOST_TEST(ss.eof());
137         ss.setstate(std::ios_base::badbit);
138         BOOST_TEST_EQ(std::ios_base::eofbit | std::ios_base::badbit,
139             ss.rdstate());
140         BOOST_TEST(ss.eof());
141         BOOST_TEST(ss.fail());
142         BOOST_TEST(ss.bad());
143     }
144     BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
145     BOOST_TEST(ss.good());
146 }
147 
148 void
ios_exception_saver_unit_test()149 ios_exception_saver_unit_test()
150 {
151     std::stringstream ss;
152     BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
153     {
154         boost::io::ios_exception_saver ies(ss);
155         BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
156         ss.exceptions(std::ios_base::failbit);
157         BOOST_TEST_EQ(std::ios_base::failbit, ss.exceptions());
158         {
159             boost::io::ios_iostate_saver iis(ss);
160             ss.exceptions(std::ios_base::failbit | std::ios_base::badbit);
161             char c;
162 #if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB))
163             BOOST_TEST_THROWS(ss >> c, std::exception);
164 #else
165             BOOST_TEST_THROWS(ss >> c, std::ios_base::failure);
166 #endif
167         }
168     }
169     BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
170     {
171         boost::io::ios_exception_saver ies(ss, std::ios_base::eofbit);
172         BOOST_TEST_EQ(std::ios_base::eofbit, ss.exceptions());
173         ss.exceptions(std::ios_base::badbit);
174         BOOST_TEST_EQ(std::ios_base::badbit, ss.exceptions());
175         {
176             boost::io::ios_iostate_saver iis(ss);
177             char c;
178             BOOST_TEST_NOT(ss >> c);
179         }
180     }
181     BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
182 }
183 
184 void
ios_tie_saver_unit_test()185 ios_tie_saver_unit_test()
186 {
187     BOOST_TEST(NULL == std::cout.tie());
188     {
189         boost::io::ios_tie_saver its(std::cout);
190         BOOST_TEST(NULL == std::cout.tie());
191         std::cout.tie(&std::clog);
192         BOOST_TEST_EQ(&std::clog, std::cout.tie());
193     }
194     BOOST_TEST(NULL == std::cout.tie());
195     {
196         boost::io::ios_tie_saver its(std::cout, &std::clog);
197         BOOST_TEST_EQ(&std::clog, std::cout.tie());
198         std::cout.tie(&std::cerr);
199         BOOST_TEST_EQ(&std::cerr, std::cout.tie());
200     }
201     BOOST_TEST(NULL == std::cout.tie());
202 }
203 
204 void
ios_rdbuf_saver_unit_test()205 ios_rdbuf_saver_unit_test()
206 {
207     std::iostream s(NULL);
208     BOOST_TEST(NULL == s.rdbuf());
209     {
210         std::stringbuf sb;
211         boost::io::ios_rdbuf_saver irs(s);
212         BOOST_TEST(NULL == s.rdbuf());
213         s.rdbuf(&sb);
214         BOOST_TEST_EQ(&sb, s.rdbuf());
215     }
216     BOOST_TEST(NULL == s.rdbuf());
217     {
218         std::stringbuf sb1, sb2("Hi there");
219         boost::io::ios_rdbuf_saver irs(s, &sb1);
220         BOOST_TEST_EQ(&sb1, s.rdbuf());
221         s.rdbuf(&sb2);
222         BOOST_TEST_EQ(&sb2, s.rdbuf());
223     }
224     BOOST_TEST(NULL == s.rdbuf());
225 }
226 
227 void
ios_fill_saver_unit_test()228 ios_fill_saver_unit_test()
229 {
230     std::stringstream ss;
231     BOOST_TEST_EQ(' ',  ss.fill());
232     {
233         boost::io::ios_fill_saver ifs(ss);
234         BOOST_TEST_EQ(' ', ss.fill());
235         ss.fill('x');
236         BOOST_TEST_EQ('x', ss.fill());
237     }
238     BOOST_TEST_EQ(' ', ss.fill());
239     {
240         boost::io::ios_fill_saver ifs(ss, '3');
241         BOOST_TEST_EQ('3', ss.fill());
242         ss.fill('+');
243         BOOST_TEST_EQ('+', ss.fill());
244     }
245     BOOST_TEST_EQ(' ', ss.fill());
246 }
247 
248 void
ios_locale_saver_unit_test()249 ios_locale_saver_unit_test()
250 {
251     typedef std::numpunct<char> npc_type;
252     std::stringstream ss;
253     BOOST_TEST(std::locale() == ss.getloc());
254     BOOST_TEST(!std::has_facet<npc_type>(ss.getloc()) ||
255         !dynamic_cast<const backward_bool_names*>(&
256         std::use_facet<npc_type>(ss.getloc())));
257     {
258         boost::io::ios_locale_saver ils(ss);
259         BOOST_TEST(std::locale() == ss.getloc());
260         ss.imbue(std::locale::classic());
261         BOOST_TEST(std::locale::classic() == ss.getloc());
262     }
263     BOOST_TEST(std::locale() == ss.getloc());
264     BOOST_TEST(!std::has_facet<npc_type>(ss.getloc()) ||
265         !dynamic_cast<const backward_bool_names*>(&
266         std::use_facet<npc_type>(ss.getloc())));
267     {
268         boost::io::ios_locale_saver ils(ss, std::locale::classic());
269         BOOST_TEST(std::locale::classic() == ss.getloc());
270         BOOST_TEST(!std::has_facet<npc_type>(ss.getloc()) ||
271             !dynamic_cast<const backward_bool_names*>(&
272             std::use_facet<npc_type>(ss.getloc())));
273         ss.imbue(std::locale(std::locale::classic(), new backward_bool_names));
274         BOOST_TEST(std::locale::classic() != ss.getloc());
275         BOOST_TEST(std::has_facet<npc_type>(ss.getloc()) &&
276             dynamic_cast<const backward_bool_names*>(&
277             std::use_facet<npc_type>(ss.getloc())));
278     }
279     BOOST_TEST(std::locale() == ss.getloc());
280     BOOST_TEST(!std::has_facet<npc_type>(ss.getloc()) ||
281         !dynamic_cast<const backward_bool_names*>(&
282         std::use_facet<npc_type>(ss.getloc())));
283 }
284 
285 void
ios_iword_saver_unit_test(int index)286 ios_iword_saver_unit_test(int index)
287 {
288     std::stringstream ss;
289     BOOST_TEST_EQ(0, ss.iword(index));
290     {
291         boost::io::ios_iword_saver iis(ss, index);
292         BOOST_TEST_EQ(0, ss.iword(index));
293         ss.iword(index) = 6;
294         BOOST_TEST_EQ(6, ss.iword(index));
295     }
296     BOOST_TEST_EQ(0, ss.iword(index));
297     {
298         boost::io::ios_iword_saver iis(ss, index, 100);
299         BOOST_TEST_EQ(100, ss.iword(index));
300         ss.iword(index) = -2000;
301         BOOST_TEST_EQ(-2000, ss.iword(index));
302     }
303     BOOST_TEST_EQ(0, ss.iword(index));
304 }
305 
306 void
ios_pword_saver_unit_test(int index)307 ios_pword_saver_unit_test(int index)
308 {
309     std::stringstream ss;
310     BOOST_TEST(NULL == ss.pword(index));
311     {
312         boost::io::ios_pword_saver ips(ss, index);
313         BOOST_TEST(NULL == ss.pword(index));
314         ss.pword(index) = &ss;
315         BOOST_TEST_EQ(&ss, ss.pword(index));
316     }
317     BOOST_TEST(NULL == ss.pword(index));
318     {
319         boost::io::ios_pword_saver ips(ss, index, ss.rdbuf());
320         BOOST_TEST_EQ(ss.rdbuf(), ss.pword(index));
321         ss.pword(index) = &ss;
322         BOOST_TEST_EQ(&ss, ss.pword(index));
323     }
324     BOOST_TEST(NULL == ss.pword(index));
325 }
326 
327 void
ios_base_all_saver_unit_test()328 ios_base_all_saver_unit_test()
329 {
330     std::stringstream ss;
331     BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
332     BOOST_TEST_EQ(6, ss.precision());
333     BOOST_TEST_EQ(0, ss.width());
334     {
335         boost::io::ios_base_all_saver ibas(ss);
336         BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
337         BOOST_TEST_EQ(6, ss.precision());
338         BOOST_TEST_EQ(0, ss.width());
339         ss << std::hex << std::unitbuf << std::setprecision(5) << std::setw(7);
340         BOOST_TEST_EQ(std::ios_base::unitbuf |
341             std::ios_base::hex |
342             std::ios_base::skipws, ss.flags());
343         BOOST_TEST_EQ(5, ss.precision());
344         BOOST_TEST_EQ(7, ss.width());
345     }
346     BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
347     BOOST_TEST_EQ(6, ss.precision());
348     BOOST_TEST_EQ(0, ss.width());
349 }
350 
351 void
ios_all_saver_unit_test()352 ios_all_saver_unit_test()
353 {
354     typedef std::numpunct<char> npc_type;
355     std::stringbuf sb;
356     std::iostream ss(&sb);
357     BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
358     BOOST_TEST_EQ(6, ss.precision());
359     BOOST_TEST_EQ(0, ss.width());
360     BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
361     BOOST_TEST(ss.good());
362     BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
363     BOOST_TEST(NULL == ss.tie());
364     BOOST_TEST(&sb == ss.rdbuf());
365     BOOST_TEST_EQ(' ',  ss.fill());
366     BOOST_TEST(std::locale() == ss.getloc());
367     {
368         boost::io::ios_all_saver ias(ss);
369         BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
370         BOOST_TEST_EQ(6, ss.precision());
371         BOOST_TEST_EQ(0, ss.width());
372         BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
373         BOOST_TEST(ss.good());
374         BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
375         BOOST_TEST(NULL == ss.tie());
376         BOOST_TEST(&sb == ss.rdbuf());
377         BOOST_TEST_EQ(' ', ss.fill());
378         BOOST_TEST(std::locale() == ss.getloc());
379         ss << std::oct << std::showpos << std::noskipws;
380         BOOST_TEST_EQ(std::ios_base::showpos | std::ios_base::oct, ss.flags());
381         ss << std::setprecision(3);
382         BOOST_TEST_EQ(3, ss.precision());
383         ss << std::setw(9);
384         BOOST_TEST_EQ(9, ss.width());
385         ss.setstate(std::ios_base::eofbit);
386         BOOST_TEST_EQ(std::ios_base::eofbit, ss.rdstate());
387         BOOST_TEST(ss.eof());
388         ss.exceptions(std::ios_base::failbit);
389         BOOST_TEST_EQ(std::ios_base::failbit, ss.exceptions());
390         {
391             boost::io::ios_iostate_saver iis(ss);
392             ss.exceptions(std::ios_base::failbit | std::ios_base::badbit);
393             char c;
394 #if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB))
395             BOOST_TEST_THROWS(ss >> c, std::exception);
396 #else
397             BOOST_TEST_THROWS(ss >> c, std::ios_base::failure);
398 #endif
399         }
400         ss.tie(&std::clog);
401         BOOST_TEST_EQ(&std::clog, ss.tie());
402         ss.rdbuf(std::cerr.rdbuf());
403         BOOST_TEST_EQ(std::cerr.rdbuf(), ss.rdbuf());
404         ss << std::setfill('x');
405         BOOST_TEST_EQ('x', ss.fill());
406         ss.imbue(std::locale(std::locale::classic(), new backward_bool_names));
407         BOOST_TEST(std::locale() != ss.getloc());
408         BOOST_TEST(std::has_facet<npc_type>(ss.getloc()) &&
409             dynamic_cast<const backward_bool_names*>(&
410             std::use_facet<npc_type>(ss.getloc())));
411     }
412     BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
413     BOOST_TEST_EQ(6, ss.precision());
414     BOOST_TEST_EQ(0, ss.width());
415     BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
416     BOOST_TEST(ss.good());
417     BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
418     BOOST_TEST(NULL == ss.tie());
419     BOOST_TEST(&sb == ss.rdbuf());
420     BOOST_TEST_EQ(' ', ss.fill());
421     BOOST_TEST(std::locale() == ss.getloc());
422 }
423 
424 void
ios_word_saver_unit_test(int index)425 ios_word_saver_unit_test(int index)
426 {
427     std::stringstream ss;
428     BOOST_TEST_EQ(0, ss.iword(index));
429     BOOST_TEST(NULL == ss.pword(index));
430     {
431         boost::io::ios_all_word_saver iaws(ss, index);
432         BOOST_TEST_EQ(0, ss.iword(index));
433         BOOST_TEST(NULL == ss.pword(index));
434         ss.iword(index) = -11;
435         ss.pword(index) = ss.rdbuf();
436         BOOST_TEST_EQ(-11, ss.iword(index));
437         BOOST_TEST_EQ(ss.rdbuf(), ss.pword(index));
438     }
439     BOOST_TEST_EQ(0, ss.iword(index));
440     BOOST_TEST(NULL == ss.pword(index));
441 }
442 
main()443 int main()
444 {
445     int index = std::ios_base::xalloc();
446     ios_flags_saver_unit_test();
447     ios_precision_saver_unit_test();
448     ios_width_saver_unit_test();
449     ios_iostate_saver_unit_test();
450     ios_exception_saver_unit_test();
451     ios_tie_saver_unit_test();
452     ios_rdbuf_saver_unit_test();
453     ios_fill_saver_unit_test();
454     ios_locale_saver_unit_test();
455     ios_iword_saver_unit_test(index);
456     ios_pword_saver_unit_test(index);
457     ios_base_all_saver_unit_test();
458     ios_all_saver_unit_test();
459     ios_word_saver_unit_test(index);
460     return boost::report_errors();
461 }
462