BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslim_formatguard.h
Go to the documentation of this file.
1/// @file bslim_formatguard.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslim_formatguard.h -*-C++-*-
8#ifndef INCLUDED_BSLIM_FORMATGUARD
9#define INCLUDED_BSLIM_FORMATGUARD
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslim_formatguard bslim_formatguard
15/// @brief Provide a guard for saving the state of a stream object.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslim
19/// @{
20/// @addtogroup bslim_formatguard
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslim_formatguard-purpose"> Purpose</a>
25/// * <a href="#bslim_formatguard-classes"> Classes </a>
26/// * <a href="#bslim_formatguard-description"> Description </a>
27/// * <a href="#bslim_formatguard-usage"> Usage </a>
28/// * <a href="#bslim_formatguard-example-1-saving-stream-state-to-be-restored-later"> Example 1: Saving Stream State to be Restored Later: </a>
29///
30/// # Purpose {#bslim_formatguard-purpose}
31/// Provide a guard for saving the state of a stream object.
32///
33/// # Classes {#bslim_formatguard-classes}
34///
35/// - bslim::FormatGuard: format guard for stream types.
36///
37/// # Description {#bslim_formatguard-description}
38/// The `bslim::FormatGuard` type saves the configuration of a
39/// @ref basic_ostream type, when the guard is created. When the guard is
40/// destroyed, the stream is restored to the state it was in when the guard was
41/// created.
42///
43/// The state that is saved is
44/// * The `fmtflags` state
45/// * The floating-point precision
46/// * The fill char
47///
48/// Note that the `width` field is not saved, because it does not normally
49/// persist among multiple items output, but automatically resets to 0 after a
50/// single item is ouput.
51///
52/// ## Usage {#bslim_formatguard-usage}
53///
54///
55/// In the following example we illustrate the usage of `FormatGuard`.
56///
57/// ### Example 1: Saving Stream State to be Restored Later: {#bslim_formatguard-example-1-saving-stream-state-to-be-restored-later}
58///
59///
60/// Suppose we want to do some output to a stream for which we must change the
61/// state of the stream.
62///
63/// First, we declare our stream:
64/// @code
65/// bsl::ostringstream oss;
66/// @endcode
67/// Then, we use a `FormatGuard` to save the state of `oss` before we
68/// reconfigure it, so that when the `FormatGuard` is destroyed it will resotre
69/// `oss` to its original state.
70/// @code
71/// {
72/// bslim::FormatGuard guard(&oss);
73/// @endcode
74/// Then, we reconfigure out stream and do some output:
75/// @code
76/// oss << "First line in hex: " << bsl::showbase << bsl::hex << 80 <<
77/// endl;
78/// @endcode
79/// Next, we leave the block and the destructor of `guard` will restore `oss`
80/// to its original configuration:
81/// @code
82/// }
83/// @endcode
84/// Now, we do another line of output:
85/// @code
86/// oss << "Second line in decimal: " << 123 << endl;
87/// @endcode
88/// Finally, we observe that our guarded output was in hex, as desired, and the
89/// output afterward was in decimal, as desired:
90/// @code
91/// assert(oss.str() == "First line in hex: 0x50\n"
92/// "Second line in decimal: 123\n");
93/// @endcode
94/// @}
95/** @} */
96/** @} */
97
98/** @addtogroup bsl
99 * @{
100 */
101/** @addtogroup bslim
102 * @{
103 */
104/** @addtogroup bslim_formatguard
105 * @{
106 */
107
108#include <bslscm_version.h>
109
110#include <bslmf_assert.h>
111#include <bslmf_isintegral.h>
112#include <bsls_keyword.h>
113#include <bsls_types.h>
114
115#include <bsl_ios.h>
116#include <bsl_ostream.h>
117
118
119
120namespace bslim {
121
122 // =================
123 // class FormatGuard
124 // =================
125
126/// This class implements a guard that saves the state of a @ref basic_ostream
127/// and restores that state upon destruction of the guard.
128///
129/// See @ref bslim_formatguard
131
132 // PRIVATE TYPES
133 typedef void (FormatGuard::*DestructorImpl_p)();
134
135 // DATA
136 bsl::ios_base * const d_iosBase_p; // base class of stream
137
138 const bsl::ios_base::fmtflags d_flags; // stream format flags
139
140 const bsl::streamsize d_precision; // precision of ostream
141
142 const bsls::Types::Int64 d_fillChar; // fill char of ostream
143
144 const DestructorImpl_p d_destructorImpl_p; // method pointer to
145 // implementation of
146 // destructor
147
148 private:
149 // NOT IMPLEMENTED
152
153 private:
154 // PRIVATE MANIPULATORS
155
156 /// Restore the format flags, precision, and fill character to the
157 /// stream that was passed to the constructor.
158 template <class CHAR_TYPE, class CHAR_TRAITS>
159 void ostreamDestructorImpl();
160
161 public:
162 // CREATORS
163
164 /// Create a `FormatGuard` object saving the state of the specified
165 /// `stream`.
166 template <class CHAR_TYPE, class CHAR_TRAITS>
167 explicit
168 FormatGuard(bsl::basic_ostream<CHAR_TYPE, CHAR_TRAITS> *stream);
169
170 /// Restore all the saved state to the stream that was passed to the
171 /// constructor.
172 ~FormatGuard();
173};
174
175 // -----------------
176 // class FormatGuard
177 // -----------------
178
179// PRIVATE MANIPULATORS
180template <class CHAR_TYPE, class CHAR_TRAITS>
181void FormatGuard::ostreamDestructorImpl()
182{
183 // Note that @ref basic_ostream inherits from 'basic_ios' through virtual
184 // inheritance, so we cannot cast from an 'ios_base *' to a
185 // 'basic_ostream *'. However, we can restore 100% of the state that we
186 // intend to using a 'basic_ios *', which inherits non-virtually from
187 // 'ios_base *'.
188
189 typedef bsl::basic_ios<CHAR_TYPE, CHAR_TRAITS> BasicIos;
190
191 BasicIos *basicIos_p = static_cast<BasicIos *>(d_iosBase_p);
192
193 basicIos_p->flags(d_flags);
194 basicIos_p->precision(d_precision);
195 basicIos_p->fill(static_cast<CHAR_TYPE>(d_fillChar));
196}
197
198// CREATORS
199template <class CHAR_TYPE, class CHAR_TRAITS>
200inline
201FormatGuard::FormatGuard(bsl::basic_ostream<CHAR_TYPE, CHAR_TRAITS> *stream)
202: d_iosBase_p(stream)
203, d_flags(stream->flags())
204, d_precision(stream->precision())
205, d_fillChar(stream->fill())
206, d_destructorImpl_p(
207 &FormatGuard::ostreamDestructorImpl<CHAR_TYPE, CHAR_TRAITS>)
208{
210 BSLMF_ASSERT(sizeof(CHAR_TYPE) <=
211 sizeof(bsls::Types::Int64)); // 'd_fillChar'
212}
213
214inline
216{
217 (this->*d_destructorImpl_p)();
218}
219
220} // close package namespace
221
222
223#endif
224
225// ----------------------------------------------------------------------------
226// Copyright 2021 Bloomberg Finance L.P.
227//
228// Licensed under the Apache License, Version 2.0 (the "License");
229// you may not use this file except in compliance with the License.
230// You may obtain a copy of the License at
231//
232// http://www.apache.org/licenses/LICENSE-2.0
233//
234// Unless required by applicable law or agreed to in writing, software
235// distributed under the License is distributed on an "AS IS" BASIS,
236// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
237// See the License for the specific language governing permissions and
238// limitations under the License.
239// ----------------------------- END-OF-FILE ----------------------------------
240
241/** @} */
242/** @} */
243/** @} */
Definition bslim_formatguard.h:130
~FormatGuard()
Definition bslim_formatguard.h:215
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:229
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_DELETED
Definition bsls_keyword.h:609
Definition bslim_formatguard.h:120
Definition bslmf_isintegral.h:130
long long Int64
Definition bsls_types.h:132