1 /*
2 Copyright 2002, 2005 Daryle Walker
3 
4 Distributed under the Boost Software License, Version 1.0.
5 (http://www.boost.org/LICENSE_1_0.txt)
6 */
7 #ifndef BOOST_IO_IOS_STATE_HPP
8 #define BOOST_IO_IOS_STATE_HPP
9 
10 #include <boost/config.hpp>
11 #include <boost/io_fwd.hpp>
12 #include <ios>
13 #ifndef BOOST_NO_STD_LOCALE
14 #include <locale>
15 #endif
16 #include <ostream>
17 #include <streambuf>
18 #include <string>
19 
20 namespace boost {
21 namespace io {
22 
23 class ios_flags_saver {
24 public:
25     typedef std::ios_base state_type;
26     typedef std::ios_base::fmtflags aspect_type;
27 
ios_flags_saver(state_type & s)28     explicit ios_flags_saver(state_type& s)
29         : s_save_(s)
30         , a_save_(s.flags()) { }
31 
ios_flags_saver(state_type & s,aspect_type a)32     ios_flags_saver(state_type& s, aspect_type a)
33         : s_save_(s)
34         , a_save_(s.flags(a)) { }
35 
~ios_flags_saver()36     ~ios_flags_saver() {
37         this->restore();
38     }
39 
restore()40     void restore() {
41         s_save_.flags(a_save_);
42     }
43 
44 private:
45     ios_flags_saver(const ios_flags_saver&);
46     ios_flags_saver& operator=(const ios_flags_saver&);
47 
48     state_type& s_save_;
49     aspect_type a_save_;
50 };
51 
52 class ios_precision_saver {
53 public:
54     typedef std::ios_base state_type;
55     typedef std::streamsize aspect_type;
56 
ios_precision_saver(state_type & s)57     explicit ios_precision_saver(state_type& s)
58         : s_save_(s)
59         , a_save_(s.precision()) { }
60 
ios_precision_saver(state_type & s,aspect_type a)61     ios_precision_saver(state_type& s, aspect_type a)
62         : s_save_(s)
63         , a_save_(s.precision(a)) { }
64 
~ios_precision_saver()65     ~ios_precision_saver() {
66         this->restore();
67     }
68 
restore()69     void restore() {
70         s_save_.precision(a_save_);
71     }
72 
73 private:
74     ios_precision_saver(const ios_precision_saver&);
75     ios_precision_saver& operator=(const ios_precision_saver&);
76 
77     state_type& s_save_;
78     aspect_type a_save_;
79 };
80 
81 class ios_width_saver {
82 public:
83     typedef std::ios_base state_type;
84     typedef std::streamsize aspect_type;
85 
ios_width_saver(state_type & s)86     explicit ios_width_saver(state_type& s)
87         : s_save_(s)
88         , a_save_(s.width()) { }
89 
ios_width_saver(state_type & s,aspect_type a)90     ios_width_saver(state_type& s, aspect_type a)
91         : s_save_(s)
92         , a_save_(s.width(a)) { }
93 
~ios_width_saver()94     ~ios_width_saver() {
95         this->restore();
96     }
97 
restore()98     void restore() {
99         s_save_.width(a_save_);
100     }
101 
102 private:
103     ios_width_saver(const ios_width_saver&);
104     ios_width_saver& operator=(const ios_width_saver&);
105 
106     state_type& s_save_;
107     aspect_type a_save_;
108 };
109 
110 template<class Ch, class Tr>
111 class basic_ios_iostate_saver {
112 public:
113     typedef std::basic_ios<Ch, Tr> state_type;
114     typedef std::ios_base::iostate aspect_type;
115 
basic_ios_iostate_saver(state_type & s)116     explicit basic_ios_iostate_saver(state_type& s)
117         : s_save_(s)
118         , a_save_(s.rdstate()) { }
119 
basic_ios_iostate_saver(state_type & s,aspect_type a)120     basic_ios_iostate_saver(state_type& s, aspect_type a)
121         : s_save_(s)
122         , a_save_(s.rdstate()) {
123             s.clear(a);
124         }
125 
~basic_ios_iostate_saver()126     ~basic_ios_iostate_saver() {
127         this->restore();
128     }
129 
restore()130     void restore() {
131         s_save_.clear(a_save_);
132     }
133 
134 private:
135     basic_ios_iostate_saver(const basic_ios_iostate_saver&);
136     basic_ios_iostate_saver& operator=(const basic_ios_iostate_saver&);
137 
138     state_type& s_save_;
139     aspect_type a_save_;
140 };
141 
142 template<class Ch, class Tr>
143 class basic_ios_exception_saver {
144 public:
145     typedef std::basic_ios<Ch, Tr> state_type;
146     typedef std::ios_base::iostate aspect_type;
147 
basic_ios_exception_saver(state_type & s)148     explicit basic_ios_exception_saver(state_type& s)
149         : s_save_(s)
150         , a_save_(s.exceptions()) { }
151 
basic_ios_exception_saver(state_type & s,aspect_type a)152     basic_ios_exception_saver(state_type& s, aspect_type a)
153         : s_save_(s)
154         , a_save_(s.exceptions()) {
155         s.exceptions(a);
156     }
157 
~basic_ios_exception_saver()158     ~basic_ios_exception_saver() {
159         this->restore();
160     }
161 
restore()162     void restore() {
163         s_save_.exceptions(a_save_);
164     }
165 
166 private:
167     basic_ios_exception_saver(const basic_ios_exception_saver&);
168     basic_ios_exception_saver& operator=(const basic_ios_exception_saver&);
169 
170     state_type& s_save_;
171     aspect_type a_save_;
172 };
173 
174 template<class Ch, class Tr>
175 class basic_ios_tie_saver {
176 public:
177     typedef std::basic_ios<Ch, Tr> state_type;
178     typedef std::basic_ostream<Ch, Tr>* aspect_type;
179 
basic_ios_tie_saver(state_type & s)180     explicit basic_ios_tie_saver(state_type& s)
181         : s_save_(s)
182         , a_save_(s.tie()) { }
183 
basic_ios_tie_saver(state_type & s,aspect_type a)184     basic_ios_tie_saver(state_type& s, aspect_type a)
185         : s_save_(s)
186         , a_save_(s.tie(a)) { }
187 
~basic_ios_tie_saver()188     ~basic_ios_tie_saver() {
189         this->restore();
190     }
191 
restore()192     void restore() {
193         s_save_.tie(a_save_);
194     }
195 
196 private:
197     basic_ios_tie_saver(const basic_ios_tie_saver&);
198     basic_ios_tie_saver& operator=(const basic_ios_tie_saver&);
199 
200     state_type& s_save_;
201     aspect_type a_save_;
202 };
203 
204 template<class Ch, class Tr>
205 class basic_ios_rdbuf_saver {
206 public:
207     typedef std::basic_ios<Ch, Tr> state_type;
208     typedef std::basic_streambuf<Ch, Tr>* aspect_type;
209 
basic_ios_rdbuf_saver(state_type & s)210     explicit basic_ios_rdbuf_saver(state_type& s)
211         : s_save_(s)
212         , a_save_(s.rdbuf()) { }
213 
basic_ios_rdbuf_saver(state_type & s,aspect_type a)214     basic_ios_rdbuf_saver(state_type& s, aspect_type a)
215         : s_save_(s)
216         , a_save_(s.rdbuf(a)) { }
217 
~basic_ios_rdbuf_saver()218     ~basic_ios_rdbuf_saver() {
219         this->restore();
220     }
221 
restore()222     void restore() {
223         s_save_.rdbuf(a_save_);
224     }
225 
226 private:
227     basic_ios_rdbuf_saver(const basic_ios_rdbuf_saver&);
228     basic_ios_rdbuf_saver& operator=(const basic_ios_rdbuf_saver&);
229 
230     state_type& s_save_;
231     aspect_type a_save_;
232 };
233 
234 template<class Ch, class Tr>
235 class basic_ios_fill_saver {
236 public:
237     typedef std::basic_ios<Ch, Tr> state_type;
238     typedef typename state_type::char_type aspect_type;
239 
basic_ios_fill_saver(state_type & s)240     explicit basic_ios_fill_saver(state_type& s)
241         : s_save_(s)
242         , a_save_(s.fill()) { }
243 
basic_ios_fill_saver(state_type & s,aspect_type a)244     basic_ios_fill_saver(state_type& s, aspect_type a)
245         : s_save_(s)
246         , a_save_(s.fill(a)) { }
247 
~basic_ios_fill_saver()248     ~basic_ios_fill_saver() {
249         this->restore();
250     }
251 
restore()252     void restore() {
253         s_save_.fill(a_save_);
254     }
255 
256 private:
257     basic_ios_fill_saver(const basic_ios_fill_saver&);
258     basic_ios_fill_saver& operator=(const basic_ios_fill_saver&);
259 
260     state_type& s_save_;
261     aspect_type a_save_;
262 };
263 
264 #ifndef BOOST_NO_STD_LOCALE
265 template<class Ch, class Tr>
266 class basic_ios_locale_saver {
267 public:
268     typedef std::basic_ios<Ch, Tr> state_type;
269     typedef std::locale aspect_type;
270 
basic_ios_locale_saver(state_type & s)271     explicit basic_ios_locale_saver(state_type& s)
272         : s_save_(s)
273         , a_save_(s.getloc()) { }
274 
basic_ios_locale_saver(state_type & s,const aspect_type & a)275     basic_ios_locale_saver(state_type& s, const aspect_type& a)
276         : s_save_(s)
277         , a_save_(s.imbue(a)) { }
278 
~basic_ios_locale_saver()279     ~basic_ios_locale_saver() {
280         this->restore();
281     }
282 
restore()283     void restore() {
284         s_save_.imbue(a_save_);
285     }
286 
287 private:
288     basic_ios_locale_saver(const basic_ios_locale_saver&);
289     basic_ios_locale_saver& operator=(const basic_ios_locale_saver&);
290 
291     state_type& s_save_;
292     aspect_type a_save_;
293 };
294 #endif
295 
296 class ios_iword_saver {
297 public:
298     typedef std::ios_base state_type;
299     typedef int index_type;
300     typedef long aspect_type;
301 
ios_iword_saver(state_type & s,index_type i)302     explicit ios_iword_saver(state_type& s, index_type i)
303         : s_save_(s)
304         , a_save_(s.iword(i))
305         , i_save_(i) { }
306 
ios_iword_saver(state_type & s,index_type i,aspect_type a)307     ios_iword_saver(state_type& s, index_type i, aspect_type a)
308         : s_save_(s)
309         , a_save_(s.iword(i))
310         , i_save_(i) {
311         s.iword(i) = a;
312     }
313 
~ios_iword_saver()314     ~ios_iword_saver() {
315         this->restore();
316     }
317 
restore()318     void restore() {
319         s_save_.iword(i_save_) = a_save_;
320     }
321 
322 private:
323     ios_iword_saver(const ios_iword_saver&);
324     ios_iword_saver& operator=(const ios_iword_saver&);
325 
326     state_type& s_save_;
327     aspect_type a_save_;
328     index_type i_save_;
329 };
330 
331 class ios_pword_saver {
332 public:
333     typedef std::ios_base state_type;
334     typedef int index_type;
335     typedef void* aspect_type;
336 
ios_pword_saver(state_type & s,index_type i)337     explicit ios_pword_saver(state_type& s, index_type i)
338         : s_save_(s)
339         , a_save_(s.pword(i))
340         , i_save_(i) { }
341 
ios_pword_saver(state_type & s,index_type i,aspect_type a)342     ios_pword_saver(state_type& s, index_type i, aspect_type a)
343         : s_save_(s)
344         , a_save_(s.pword(i))
345         , i_save_(i) {
346         s.pword(i) = a;
347     }
348 
~ios_pword_saver()349     ~ios_pword_saver() {
350         this->restore();
351     }
352 
restore()353     void restore() {
354         s_save_.pword(i_save_) = a_save_;
355     }
356 
357 private:
358     ios_pword_saver(const ios_pword_saver&);
359     ios_pword_saver operator=(const ios_pword_saver&);
360 
361     state_type& s_save_;
362     aspect_type a_save_;
363     index_type i_save_;
364 };
365 
366 class ios_base_all_saver {
367 public:
368     typedef std::ios_base state_type;
369 
ios_base_all_saver(state_type & s)370     explicit ios_base_all_saver(state_type& s)
371         : s_save_(s)
372         , a1_save_(s.flags())
373         , a2_save_(s.precision())
374         , a3_save_(s.width()) { }
375 
~ios_base_all_saver()376     ~ios_base_all_saver() {
377         this->restore();
378     }
379 
restore()380     void restore() {
381         s_save_.width(a3_save_);
382         s_save_.precision(a2_save_);
383         s_save_.flags(a1_save_);
384     }
385 
386 private:
387     ios_base_all_saver(const ios_base_all_saver&);
388     ios_base_all_saver& operator=(const ios_base_all_saver&);
389 
390     state_type& s_save_;
391     state_type::fmtflags a1_save_;
392     std::streamsize a2_save_;
393     std::streamsize a3_save_;
394 };
395 
396 template<class Ch, class Tr>
397 class basic_ios_all_saver {
398 public:
399     typedef std::basic_ios<Ch, Tr> state_type;
400 
basic_ios_all_saver(state_type & s)401     explicit basic_ios_all_saver(state_type& s)
402         : s_save_(s)
403         , a1_save_(s.flags())
404         , a2_save_(s.precision())
405         , a3_save_(s.width())
406         , a4_save_(s.rdstate())
407         , a5_save_(s.exceptions())
408         , a6_save_(s.tie())
409         , a7_save_(s.rdbuf())
410         , a8_save_(s.fill())
411 #ifndef BOOST_NO_STD_LOCALE
412         , a9_save_(s.getloc())
413 #endif
414         { }
415 
~basic_ios_all_saver()416     ~basic_ios_all_saver() {
417         this->restore();
418     }
419 
restore()420     void restore() {
421 #ifndef BOOST_NO_STD_LOCALE
422         s_save_.imbue(a9_save_);
423 #endif
424         s_save_.fill(a8_save_);
425         s_save_.rdbuf(a7_save_);
426         s_save_.tie(a6_save_);
427         s_save_.exceptions(a5_save_);
428         s_save_.clear(a4_save_);
429         s_save_.width(a3_save_);
430         s_save_.precision(a2_save_);
431         s_save_.flags(a1_save_);
432     }
433 
434 private:
435     basic_ios_all_saver(const basic_ios_all_saver&);
436     basic_ios_all_saver& operator=(const basic_ios_all_saver&);
437 
438     state_type& s_save_;
439     typename state_type::fmtflags a1_save_;
440     std::streamsize a2_save_;
441     std::streamsize a3_save_;
442     typename state_type::iostate a4_save_;
443     typename state_type::iostate a5_save_;
444     std::basic_ostream<Ch, Tr>* a6_save_;
445     std::basic_streambuf<Ch, Tr>* a7_save_;
446     typename state_type::char_type a8_save_;
447 #ifndef BOOST_NO_STD_LOCALE
448     std::locale a9_save_;
449 #endif
450 };
451 
452 class ios_all_word_saver {
453 public:
454     typedef std::ios_base state_type;
455     typedef int index_type;
456 
ios_all_word_saver(state_type & s,index_type i)457     ios_all_word_saver(state_type& s, index_type i)
458         : s_save_(s)
459         , i_save_(i)
460         , a1_save_(s.iword(i))
461         , a2_save_(s.pword(i)) { }
462 
~ios_all_word_saver()463     ~ios_all_word_saver() {
464         this->restore();
465     }
466 
restore()467     void restore() {
468         s_save_.pword(i_save_) = a2_save_;
469         s_save_.iword(i_save_) = a1_save_;
470     }
471 
472 private:
473     ios_all_word_saver(const ios_all_word_saver&);
474     ios_all_word_saver& operator=(const ios_all_word_saver&);
475 
476     state_type& s_save_;
477     index_type i_save_;
478     long a1_save_;
479     void* a2_save_;
480 };
481 
482 } /* io */
483 } /* boost */
484 
485 #endif
486