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_IMPLEMENTATION_HPP
0015 #define BOOST_FORMAT_IMPLEMENTATION_HPP
0016
0017 #include <boost/config.hpp>
0018 #include <boost/throw_exception.hpp>
0019 #include <boost/assert.hpp>
0020 #include <boost/format/format_class.hpp>
0021 #include <algorithm> // std::swap
0022
0023 namespace boost {
0024
0025
0026
0027 template< class Ch, class Tr, class Alloc>
0028 basic_format<Ch, Tr, Alloc>:: basic_format(const Ch* s)
0029 : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
0030 exceptions_(io::all_error_bits)
0031 {
0032 if( s)
0033 parse( s );
0034 }
0035
0036 #if !defined(BOOST_NO_STD_LOCALE)
0037 template< class Ch, class Tr, class Alloc>
0038 basic_format<Ch, Tr, Alloc>:: basic_format(const Ch* s, const std::locale & loc)
0039 : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
0040 exceptions_(io::all_error_bits), loc_(loc)
0041 {
0042 if(s) parse( s );
0043 }
0044
0045 template< class Ch, class Tr, class Alloc>
0046 basic_format<Ch, Tr, Alloc>:: basic_format(const string_type& s, const std::locale & loc)
0047 : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
0048 exceptions_(io::all_error_bits), loc_(loc)
0049 {
0050 parse(s);
0051 }
0052 #endif
0053 template< class Ch, class Tr, class Alloc>
0054 io::detail::locale_t basic_format<Ch, Tr, Alloc>::
0055 getloc() const {
0056 return loc_ ? loc_.get() : io::detail::locale_t();
0057 }
0058
0059 template< class Ch, class Tr, class Alloc>
0060 basic_format<Ch, Tr, Alloc>:: basic_format(const string_type& s)
0061 : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
0062 exceptions_(io::all_error_bits)
0063 {
0064 parse(s);
0065 }
0066
0067 template< class Ch, class Tr, class Alloc>
0068 basic_format<Ch, Tr, Alloc>:: basic_format(const basic_format& x)
0069 : items_(x.items_), bound_(x.bound_), style_(x.style_),
0070 cur_arg_(x.cur_arg_), num_args_(x.num_args_), dumped_(x.dumped_),
0071 prefix_(x.prefix_), exceptions_(x.exceptions_), loc_(x.loc_)
0072 {
0073 }
0074
0075 template< class Ch, class Tr, class Alloc>
0076 basic_format<Ch, Tr, Alloc>& basic_format<Ch, Tr, Alloc>::
0077 operator= (const basic_format& x) {
0078 if(this == &x)
0079 return *this;
0080 (basic_format<Ch, Tr, Alloc>(x)).swap(*this);
0081 return *this;
0082 }
0083 template< class Ch, class Tr, class Alloc>
0084 void basic_format<Ch, Tr, Alloc>::
0085 swap (basic_format & x) {
0086 std::swap(exceptions_, x.exceptions_);
0087 std::swap(style_, x.style_);
0088 std::swap(cur_arg_, x.cur_arg_);
0089 std::swap(num_args_, x.num_args_);
0090 std::swap(dumped_, x.dumped_);
0091
0092 items_.swap(x.items_);
0093 prefix_.swap(x.prefix_);
0094 bound_.swap(x.bound_);
0095 }
0096
0097 template< class Ch, class Tr, class Alloc>
0098 unsigned char basic_format<Ch,Tr, Alloc>:: exceptions() const {
0099 return exceptions_;
0100 }
0101
0102 template< class Ch, class Tr, class Alloc>
0103 unsigned char basic_format<Ch,Tr, Alloc>:: exceptions(unsigned char newexcept) {
0104 unsigned char swp = exceptions_;
0105 exceptions_ = newexcept;
0106 return swp;
0107 }
0108
0109 template<class Ch, class Tr, class Alloc>
0110 void basic_format<Ch, Tr, Alloc>::
0111 make_or_reuse_data (std::size_t nbitems) {
0112 #if !defined(BOOST_NO_STD_LOCALE)
0113 Ch fill = ( BOOST_USE_FACET(std::ctype<Ch>, getloc()) ). widen(' ');
0114 #else
0115 Ch fill = ' ';
0116 #endif
0117 if(items_.size() == 0)
0118 items_.assign( nbitems, format_item_t(fill) );
0119 else {
0120 if(nbitems>items_.size())
0121 items_.resize(nbitems, format_item_t(fill));
0122 bound_.resize(0);
0123 for(std::size_t i=0; i < nbitems; ++i)
0124 items_[i].reset(fill);
0125 }
0126 prefix_.resize(0);
0127 }
0128
0129 template< class Ch, class Tr, class Alloc>
0130 basic_format<Ch,Tr, Alloc>& basic_format<Ch,Tr, Alloc>::
0131 clear () {
0132
0133
0134
0135 BOOST_ASSERT( bound_.size()==0 || num_args_ == static_cast<int>(bound_.size()) );
0136
0137 for(unsigned long i=0; i<items_.size(); ++i) {
0138
0139 if( bound_.size()==0 || items_[i].argN_<0 || !bound_[ items_[i].argN_ ] )
0140 items_[i].res_.resize(0);
0141 }
0142 cur_arg_=0; dumped_=false;
0143
0144 if(bound_.size() != 0) {
0145 for(; cur_arg_ < num_args_ && bound_[cur_arg_]; ++cur_arg_)
0146 {}
0147 }
0148 return *this;
0149 }
0150
0151 template< class Ch, class Tr, class Alloc>
0152 basic_format<Ch,Tr, Alloc>& basic_format<Ch,Tr, Alloc>::
0153 clear_binds () {
0154
0155 bound_.resize(0);
0156 clear();
0157 return *this;
0158 }
0159
0160 template< class Ch, class Tr, class Alloc>
0161 basic_format<Ch,Tr, Alloc>& basic_format<Ch,Tr, Alloc>::
0162 clear_bind (int argN) {
0163
0164 if(argN<1 || argN > num_args_ || bound_.size()==0 || !bound_[argN-1] ) {
0165 if( exceptions() & io::out_of_range_bit)
0166 boost::throw_exception(io::out_of_range(argN, 1, num_args_+1 ) );
0167 else return *this;
0168 }
0169 bound_[argN-1]=false;
0170 clear();
0171 return *this;
0172 }
0173
0174 template< class Ch, class Tr, class Alloc>
0175 int basic_format<Ch,Tr, Alloc>::
0176 bound_args() const {
0177 if(bound_.size()==0)
0178 return 0;
0179 int n=0;
0180 for(int i=0; i<num_args_ ; ++i)
0181 if(bound_[i])
0182 ++n;
0183 return n;
0184 }
0185
0186 template< class Ch, class Tr, class Alloc>
0187 int basic_format<Ch,Tr, Alloc>::
0188 fed_args() const {
0189 if(bound_.size()==0)
0190 return cur_arg_;
0191 int n=0;
0192 for(int i=0; i<cur_arg_ ; ++i)
0193 if(!bound_[i])
0194 ++n;
0195 return n;
0196 }
0197
0198 template< class Ch, class Tr, class Alloc>
0199 int basic_format<Ch,Tr, Alloc>::
0200 cur_arg() const {
0201 return cur_arg_+1; }
0202
0203 template< class Ch, class Tr, class Alloc>
0204 int basic_format<Ch,Tr, Alloc>::
0205 remaining_args() const {
0206 if(bound_.size()==0)
0207 return num_args_-cur_arg_;
0208 int n=0;
0209 for(int i=cur_arg_; i<num_args_ ; ++i)
0210 if(!bound_[i])
0211 ++n;
0212 return n;
0213 }
0214
0215 template< class Ch, class Tr, class Alloc>
0216 typename basic_format<Ch, Tr, Alloc>::string_type
0217 basic_format<Ch,Tr, Alloc>::
0218 str () const {
0219 if(items_.size()==0)
0220 return prefix_;
0221 if( cur_arg_ < num_args_)
0222 if( exceptions() & io::too_few_args_bit )
0223
0224 boost::throw_exception(io::too_few_args(cur_arg_, num_args_));
0225
0226 unsigned long i;
0227 string_type res;
0228 res.reserve(size());
0229 res += prefix_;
0230 for(i=0; i < items_.size(); ++i) {
0231 const format_item_t& item = items_[i];
0232 res += item.res_;
0233 if( item.argN_ == format_item_t::argN_tabulation) {
0234 BOOST_ASSERT( item.pad_scheme_ & format_item_t::tabulation);
0235 if( static_cast<size_type>(item.fmtstate_.width_) > res.size() )
0236 res.append( static_cast<size_type>(item.fmtstate_.width_) - res.size(),
0237 item.fmtstate_.fill_ );
0238 }
0239 res += item.appendix_;
0240 }
0241 dumped_=true;
0242 return res;
0243 }
0244 template< class Ch, class Tr, class Alloc>
0245 typename std::basic_string<Ch, Tr, Alloc>::size_type basic_format<Ch,Tr, Alloc>::
0246 size () const {
0247 #ifdef BOOST_MSVC
0248
0249
0250
0251 #pragma warning(push)
0252 #pragma warning(disable:4267)
0253 #endif
0254 BOOST_USING_STD_MAX();
0255 size_type sz = prefix_.size();
0256 unsigned long i;
0257 for(i=0; i < items_.size(); ++i) {
0258 const format_item_t& item = items_[i];
0259 sz += item.res_.size();
0260 if( item.argN_ == format_item_t::argN_tabulation)
0261 sz = max BOOST_PREVENT_MACRO_SUBSTITUTION (sz,
0262 static_cast<size_type>(item.fmtstate_.width_) );
0263 sz += item.appendix_.size();
0264 }
0265 return sz;
0266 #ifdef BOOST_MSVC
0267 #pragma warning(pop)
0268 #endif
0269 }
0270
0271 namespace io {
0272 namespace detail {
0273
0274 template<class Ch, class Tr, class Alloc, class T>
0275 basic_format<Ch, Tr, Alloc>&
0276 bind_arg_body (basic_format<Ch, Tr, Alloc>& self, int argN, const T& val) {
0277
0278
0279 if(self.dumped_)
0280 self.clear();
0281 if(argN<1 || argN > self.num_args_) {
0282 if( self.exceptions() & io::out_of_range_bit )
0283 boost::throw_exception(io::out_of_range(argN, 1, self.num_args_+1 ) );
0284 else return self;
0285 }
0286 if(self.bound_.size()==0)
0287 self.bound_.assign(self.num_args_,false);
0288 else
0289 BOOST_ASSERT( self.num_args_ == static_cast<signed int>(self.bound_.size()) );
0290 int o_cur_arg = self.cur_arg_;
0291 self.cur_arg_ = argN-1;
0292
0293 self.bound_[self.cur_arg_]=false;
0294 self.operator%(val);
0295
0296
0297
0298 self.cur_arg_ = o_cur_arg;
0299 self.bound_[argN-1]=true;
0300 if(self.cur_arg_ == argN-1 ) {
0301
0302 while(self.cur_arg_ < self.num_args_ && self.bound_[self.cur_arg_])
0303 ++self.cur_arg_;
0304 }
0305
0306 BOOST_ASSERT( self.cur_arg_ >= self.num_args_ || ! self.bound_[self.cur_arg_]);
0307 return self;
0308 }
0309
0310 template<class Ch, class Tr, class Alloc, class T> basic_format<Ch, Tr, Alloc>&
0311 modify_item_body (basic_format<Ch, Tr, Alloc>& self, int itemN, T manipulator) {
0312
0313
0314 if(itemN<1 || itemN > static_cast<signed int>(self.items_.size() )) {
0315 if( self.exceptions() & io::out_of_range_bit )
0316 boost::throw_exception(io::out_of_range(itemN, 1, static_cast<int>(self.items_.size()) ));
0317 else return self;
0318 }
0319 self.items_[itemN-1].fmtstate_. template apply_manip<T> ( manipulator );
0320 return self;
0321 }
0322
0323 }
0324 }
0325 }
0326
0327
0328
0329 #endif