Blame view

3rdparty/boost_1_81_0/boost/format/internals.hpp 7.97 KB
63e88f80   Hu Chunming   提交三方库
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
  // ----------------------------------------------------------------------------
  // internals.hpp :  internal structs : stream_format_state, format_item. 
  //                  included by format.hpp
  // ----------------------------------------------------------------------------
  
  //  Copyright Samuel Krempp 2003. Use, modification, and distribution are
  //  subject to the Boost Software License, Version 1.0. (See accompanying
  //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  
  //  See http://www.boost.org/libs/format for library home page
  
  // ----------------------------------------------------------------------------
  
  #ifndef BOOST_FORMAT_INTERNALS_HPP
  #define BOOST_FORMAT_INTERNALS_HPP
  
  
  #include <string>
  #include <boost/assert.hpp>
  #include <boost/core/ignore_unused.hpp>
  #include <boost/optional.hpp>
  #include <boost/limits.hpp>
  #include <boost/format/detail/compat_workarounds.hpp>
  #include <boost/format/alt_sstream.hpp> // used as a dummy stream
  
  namespace boost {
  namespace io {
  namespace detail {
  
  
  //---- stream_format_state --------------------------------------------------//
  
  //   set of params that define the format state of a stream
      template<class Ch, class Tr> 
      struct stream_format_state 
      {
          typedef BOOST_IO_STD basic_ios<Ch, Tr>   basic_ios;
  
          stream_format_state(Ch fill)                 { reset(fill); }
  //        stream_format_state(const basic_ios& os)     { set_by_stream(os); }
  
          void reset(Ch fill);                     //- sets to default state.
          void set_by_stream(const basic_ios& os); //- sets to os's state.
          void apply_on(basic_ios & os,            //- applies format_state to the stream
                        boost::io::detail::locale_t * loc_default = 0) const;
          template<class T> 
          void apply_manip(T manipulator)          //- modifies state by applying manipulator
              { apply_manip_body<Ch, Tr, T>( *this, manipulator) ; }
  
          // --- data ---
          std::streamsize width_;
          std::streamsize precision_;
          Ch fill_; 
          std::ios_base::fmtflags flags_;
          std::ios_base::iostate  rdstate_;
          std::ios_base::iostate  exceptions_;
          boost::optional<boost::io::detail::locale_t>  loc_;
      };  
  
  
  //---- format_item  ---------------------------------------------------------//
  
  //   stores all parameters that can be specified in format strings
      template<class Ch, class Tr, class Alloc>  
      struct format_item 
      {     
          enum pad_values { zeropad = 1, spacepad =2, centered=4, tabulation = 8 };
                           // 1. if zeropad is set, all other bits are not, 
                           // 2. if tabulation is set, all others are not.
                           // centered and spacepad can be mixed freely.
          enum arg_values { argN_no_posit   = -1, // non-positional directive. will set argN later
                            argN_tabulation = -2, // tabulation directive. (no argument read) 
                            argN_ignored    = -3  // ignored directive. (no argument read)
          };
          typedef BOOST_IO_STD basic_ios<Ch, Tr>                    basic_ios;
          typedef detail::stream_format_state<Ch, Tr>               stream_format_state;
          typedef ::std::basic_string<Ch, Tr, Alloc>                string_type;
  
          format_item(Ch fill) :argN_(argN_no_posit), fmtstate_(fill), 
                                truncate_(max_streamsize()), pad_scheme_(0)  {}
          void reset(Ch fill);
          void compute_states(); // sets states  according to truncate and pad_scheme.
  
          static std::streamsize max_streamsize() { 
              return (std::numeric_limits<std::streamsize>::max)();
          }
  
          // --- data ---
          int         argN_;  //- argument number (starts at 0,  eg : %1 => argN=0)
                              //  negative values for items that don't process an argument
          string_type  res_;      //- result of the formatting of this item
          string_type  appendix_; //- piece of string between this item and the next
  
          stream_format_state fmtstate_;// set by parsing, is only affected by modify_item
  
          std::streamsize truncate_;//- is set for directives like %.5s that ask truncation
          unsigned int pad_scheme_;//- several possible padding schemes can mix. see pad_values
      }; 
  
  
  
  //--- Definitions  ------------------------------------------------------------
  
  // -   stream_format_state:: -------------------------------------------------
      template<class Ch, class Tr>
      void stream_format_state<Ch,Tr>:: apply_on (basic_ios & os,
                        boost::io::detail::locale_t * loc_default) const {
      // If a locale is available, set it first. "os.fill(fill_);" may chrash otherwise. 
  #if !defined(BOOST_NO_STD_LOCALE)
          if(loc_)
              os.imbue(loc_.get());
          else if(loc_default)
              os.imbue(*loc_default);
  #else
          ignore_unused(loc_default);
  #endif        
          // set the state of this stream according to our params
          if(width_ != -1)
              os.width(width_);
          if(precision_ != -1)
              os.precision(precision_);
          if(fill_ != 0)
              os.fill(fill_);
          os.flags(flags_);
          os.clear(rdstate_);
          os.exceptions(exceptions_);
      }
  
      template<class Ch, class Tr>
      void stream_format_state<Ch,Tr>:: set_by_stream(const basic_ios& os) {
          // set our params according to the state of this stream
          flags_ = os.flags();
          width_ = os.width();
          precision_ = os.precision();
          fill_ = os.fill();
          rdstate_ = os.rdstate();
          exceptions_ = os.exceptions();
      }
  
  
      template<class Ch, class Tr, class T>
      void apply_manip_body( stream_format_state<Ch, Tr>& self,
                             T manipulator) {
          // modify our params according to the manipulator
          basic_oaltstringstream<Ch, Tr>  ss;
          self.apply_on( ss );
          ss << manipulator;
          self.set_by_stream( ss );
      }
  
      template<class Ch, class Tr> inline
      void stream_format_state<Ch,Tr>:: reset(Ch fill) {
          // set our params to standard's default state.   cf 27.4.4.1 of the C++ norm
          width_=0; precision_=6; 
          fill_=fill; // default is widen(' '), but we cant compute it without the locale
          flags_ = std::ios_base::dec | std::ios_base::skipws; 
          // the adjust_field part is left equal to 0, which means right.
          exceptions_ = std::ios_base::goodbit;
          rdstate_ = std::ios_base::goodbit;
      }
  
  
  // ---   format_item:: --------------------------------------------------------
  
      template<class Ch, class Tr, class Alloc> 
      void format_item<Ch, Tr, Alloc>:: 
      reset (Ch fill) { 
          argN_=argN_no_posit; truncate_ = max_streamsize(); pad_scheme_ =0; 
          res_.resize(0); appendix_.resize(0);
          fmtstate_.reset(fill);
      }
  
      template<class Ch, class Tr, class Alloc> 
      void format_item<Ch, Tr, Alloc>:: 
      compute_states() {
          // reflect pad_scheme_   on  fmt_state_
          //   because some pad_schemes has complex consequences on several state params.
          if(pad_scheme_ & zeropad) {
              // ignore zeropad in left alignment :
              if(fmtstate_.flags_ & std::ios_base::left) {
                BOOST_ASSERT(!(fmtstate_.flags_ &(std::ios_base::adjustfield ^std::ios_base::left)));
                // only left bit might be set. (not right, nor internal)
                pad_scheme_ = pad_scheme_ & (~zeropad); 
              }
              else { 
                  pad_scheme_ &= ~spacepad; // printf ignores spacepad when zeropadding
                  fmtstate_.fill_='0'; 
                  fmtstate_.flags_ = (fmtstate_.flags_ & ~std::ios_base::adjustfield) 
                      | std::ios_base::internal;
                  // removes all adjustfield bits, and adds internal.
              }
          }
          if(pad_scheme_ & spacepad) {
              if(fmtstate_.flags_ & std::ios_base::showpos)
                  pad_scheme_ &= ~spacepad;
          }
      }
  
  
  } } } // namespaces boost :: io :: detail
  
  
  #endif // BOOST_FORMAT_INTERNALS_HPP