File indexing completed on 2025-01-18 09:30:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef BOOST_FORMAT_INTERNALS_HPP
0015 #define BOOST_FORMAT_INTERNALS_HPP
0016
0017
0018 #include <string>
0019 #include <boost/assert.hpp>
0020 #include <boost/core/ignore_unused.hpp>
0021 #include <boost/optional.hpp>
0022 #include <boost/limits.hpp>
0023 #include <boost/format/detail/compat_workarounds.hpp>
0024 #include <boost/format/alt_sstream.hpp> // used as a dummy stream
0025
0026 namespace boost {
0027 namespace io {
0028 namespace detail {
0029
0030
0031
0032
0033
0034 template<class Ch, class Tr>
0035 struct stream_format_state
0036 {
0037 typedef BOOST_IO_STD basic_ios<Ch, Tr> basic_ios;
0038
0039 stream_format_state(Ch fill) { reset(fill); }
0040
0041
0042 void reset(Ch fill);
0043 void set_by_stream(const basic_ios& os);
0044 void apply_on(basic_ios & os,
0045 boost::io::detail::locale_t * loc_default = 0) const;
0046 template<class T>
0047 void apply_manip(T manipulator)
0048 { apply_manip_body<Ch, Tr, T>( *this, manipulator) ; }
0049
0050
0051 std::streamsize width_;
0052 std::streamsize precision_;
0053 Ch fill_;
0054 std::ios_base::fmtflags flags_;
0055 std::ios_base::iostate rdstate_;
0056 std::ios_base::iostate exceptions_;
0057 boost::optional<boost::io::detail::locale_t> loc_;
0058 };
0059
0060
0061
0062
0063
0064 template<class Ch, class Tr, class Alloc>
0065 struct format_item
0066 {
0067 enum pad_values { zeropad = 1, spacepad =2, centered=4, tabulation = 8 };
0068
0069
0070
0071 enum arg_values { argN_no_posit = -1,
0072 argN_tabulation = -2,
0073 argN_ignored = -3
0074 };
0075 typedef BOOST_IO_STD basic_ios<Ch, Tr> basic_ios;
0076 typedef detail::stream_format_state<Ch, Tr> stream_format_state;
0077 typedef ::std::basic_string<Ch, Tr, Alloc> string_type;
0078
0079 format_item(Ch fill) :argN_(argN_no_posit), fmtstate_(fill),
0080 truncate_(max_streamsize()), pad_scheme_(0) {}
0081 void reset(Ch fill);
0082 void compute_states();
0083
0084 static std::streamsize max_streamsize() {
0085 return (std::numeric_limits<std::streamsize>::max)();
0086 }
0087
0088
0089 int argN_;
0090
0091 string_type res_;
0092 string_type appendix_;
0093
0094 stream_format_state fmtstate_;
0095
0096 std::streamsize truncate_;
0097 unsigned int pad_scheme_;
0098 };
0099
0100
0101
0102
0103
0104
0105 template<class Ch, class Tr>
0106 void stream_format_state<Ch,Tr>:: apply_on (basic_ios & os,
0107 boost::io::detail::locale_t * loc_default) const {
0108
0109 #if !defined(BOOST_NO_STD_LOCALE)
0110 if(loc_)
0111 os.imbue(loc_.get());
0112 else if(loc_default)
0113 os.imbue(*loc_default);
0114 #else
0115 ignore_unused(loc_default);
0116 #endif
0117
0118 if(width_ != -1)
0119 os.width(width_);
0120 if(precision_ != -1)
0121 os.precision(precision_);
0122 if(fill_ != 0)
0123 os.fill(fill_);
0124 os.flags(flags_);
0125 os.clear(rdstate_);
0126 os.exceptions(exceptions_);
0127 }
0128
0129 template<class Ch, class Tr>
0130 void stream_format_state<Ch,Tr>:: set_by_stream(const basic_ios& os) {
0131
0132 flags_ = os.flags();
0133 width_ = os.width();
0134 precision_ = os.precision();
0135 fill_ = os.fill();
0136 rdstate_ = os.rdstate();
0137 exceptions_ = os.exceptions();
0138 }
0139
0140
0141 template<class Ch, class Tr, class T>
0142 void apply_manip_body( stream_format_state<Ch, Tr>& self,
0143 T manipulator) {
0144
0145 basic_oaltstringstream<Ch, Tr> ss;
0146 self.apply_on( ss );
0147 ss << manipulator;
0148 self.set_by_stream( ss );
0149 }
0150
0151 template<class Ch, class Tr> inline
0152 void stream_format_state<Ch,Tr>:: reset(Ch fill) {
0153
0154 width_=0; precision_=6;
0155 fill_=fill;
0156 flags_ = std::ios_base::dec | std::ios_base::skipws;
0157
0158 exceptions_ = std::ios_base::goodbit;
0159 rdstate_ = std::ios_base::goodbit;
0160 }
0161
0162
0163
0164
0165 template<class Ch, class Tr, class Alloc>
0166 void format_item<Ch, Tr, Alloc>::
0167 reset (Ch fill) {
0168 argN_=argN_no_posit; truncate_ = max_streamsize(); pad_scheme_ =0;
0169 res_.resize(0); appendix_.resize(0);
0170 fmtstate_.reset(fill);
0171 }
0172
0173 template<class Ch, class Tr, class Alloc>
0174 void format_item<Ch, Tr, Alloc>::
0175 compute_states() {
0176
0177
0178 if(pad_scheme_ & zeropad) {
0179
0180 if(fmtstate_.flags_ & std::ios_base::left) {
0181 BOOST_ASSERT(!(fmtstate_.flags_ &(std::ios_base::adjustfield ^std::ios_base::left)));
0182
0183 pad_scheme_ = pad_scheme_ & (~zeropad);
0184 }
0185 else {
0186 pad_scheme_ &= ~spacepad;
0187 fmtstate_.fill_='0';
0188 fmtstate_.flags_ = (fmtstate_.flags_ & ~std::ios_base::adjustfield)
0189 | std::ios_base::internal;
0190
0191 }
0192 }
0193 if(pad_scheme_ & spacepad) {
0194 if(fmtstate_.flags_ & std::ios_base::showpos)
0195 pad_scheme_ &= ~spacepad;
0196 }
0197 }
0198
0199
0200 } } }
0201
0202
0203 #endif