LCOV - code coverage report
Current view: top level - usr/include/boost/format - format_implementation.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 62 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // ----------------------------------------------------------------------------
       2             : // format_implementation.hpp  Implementation of the basic_format class
       3             : // ----------------------------------------------------------------------------
       4             : 
       5             : //  Copyright Samuel Krempp 2003. Use, modification, and distribution are
       6             : //  subject to the Boost Software License, Version 1.0. (See accompanying
       7             : //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       8             : 
       9             : //  See http://www.boost.org/libs/format for library home page
      10             : 
      11             : 
      12             : // ----------------------------------------------------------------------------
      13             : 
      14             : #ifndef BOOST_FORMAT_IMPLEMENTATION_HPP
      15             : #define BOOST_FORMAT_IMPLEMENTATION_HPP
      16             : 
      17             : #include <boost/config.hpp>
      18             : #include <boost/throw_exception.hpp>
      19             : #include <boost/assert.hpp>
      20             : #include <boost/format/format_class.hpp>
      21             : #include <algorithm> // std::swap
      22             : 
      23             : namespace boost {
      24             : 
      25             : // ---  basic_format implementation -----------------------------------------//
      26             : 
      27             :     template< class Ch, class Tr, class Alloc>
      28           0 :     basic_format<Ch, Tr, Alloc>:: basic_format(const Ch* s)
      29             :         : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
      30           0 :           exceptions_(io::all_error_bits)
      31             :     {
      32           0 :         if( s)
      33           0 :             parse( s );
      34           0 :     }
      35             : 
      36             : #if !defined(BOOST_NO_STD_LOCALE)
      37             :     template< class Ch, class Tr, class Alloc>
      38             :     basic_format<Ch, Tr, Alloc>:: basic_format(const Ch* s, const std::locale & loc)
      39             :         : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
      40             :           exceptions_(io::all_error_bits), loc_(loc)
      41             :     {
      42             :         if(s) parse( s );
      43             :     }
      44             : 
      45             :     template< class Ch, class Tr, class Alloc>
      46             :     basic_format<Ch, Tr, Alloc>:: basic_format(const string_type& s, const std::locale & loc)
      47             :         : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
      48             :           exceptions_(io::all_error_bits), loc_(loc)
      49             :     {
      50             :         parse(s);  
      51             :     }
      52             : #endif // ! BOOST_NO_STD_LOCALE
      53             :     template< class Ch, class Tr, class Alloc>
      54           0 :     io::detail::locale_t basic_format<Ch, Tr, Alloc>:: 
      55             :     getloc() const {
      56           0 :         return loc_ ? loc_.get() : io::detail::locale_t(); 
      57             :     }
      58             : 
      59             :     template< class Ch, class Tr, class Alloc>
      60           0 :     basic_format<Ch, Tr, Alloc>:: basic_format(const string_type& s)
      61             :         : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
      62           0 :           exceptions_(io::all_error_bits)
      63             :     {
      64           0 :         parse(s);  
      65           0 :     }
      66             : 
      67             :     template< class Ch, class Tr, class Alloc> // just don't copy the buf_ member
      68             :     basic_format<Ch, Tr, Alloc>:: basic_format(const basic_format& x)
      69             :         : items_(x.items_), bound_(x.bound_), style_(x.style_),
      70             :           cur_arg_(x.cur_arg_), num_args_(x.num_args_), dumped_(x.dumped_),
      71             :           prefix_(x.prefix_), exceptions_(x.exceptions_), loc_(x.loc_)
      72             :     {
      73             :     }
      74             : 
      75             :     template< class Ch, class Tr, class Alloc>  // just don't copy the buf_ member
      76             :     basic_format<Ch, Tr, Alloc>& basic_format<Ch, Tr, Alloc>:: 
      77             :     operator= (const basic_format& x) {
      78             :         if(this == &x)
      79             :             return *this;
      80             :         (basic_format<Ch, Tr, Alloc>(x)).swap(*this);
      81             :         return *this;
      82             :     }
      83             :     template< class Ch, class Tr, class Alloc>
      84             :     void  basic_format<Ch, Tr, Alloc>:: 
      85             :     swap (basic_format & x) {
      86             :         std::swap(exceptions_, x.exceptions_);
      87             :         std::swap(style_, x.style_); 
      88             :         std::swap(cur_arg_, x.cur_arg_); 
      89             :         std::swap(num_args_, x.num_args_);
      90             :         std::swap(dumped_, x.dumped_);
      91             : 
      92             :         items_.swap(x.items_);
      93             :         prefix_.swap(x.prefix_);
      94             :         bound_.swap(x.bound_);
      95             :     }
      96             : 
      97             :     template< class Ch, class Tr, class Alloc>
      98           0 :     unsigned char basic_format<Ch,Tr, Alloc>:: exceptions() const {
      99             :         return exceptions_; 
     100             :     }
     101             : 
     102             :     template< class Ch, class Tr, class Alloc>
     103             :     unsigned char basic_format<Ch,Tr, Alloc>:: exceptions(unsigned char newexcept) { 
     104             :         unsigned char swp = exceptions_; 
     105             :         exceptions_ = newexcept; 
     106             :         return swp; 
     107             :     }
     108             : 
     109             :     template<class Ch, class Tr, class Alloc>
     110           0 :     void basic_format<Ch, Tr, Alloc>:: 
     111             :     make_or_reuse_data (std::size_t nbitems) {
     112             : #if !defined(BOOST_NO_STD_LOCALE)
     113           0 :         Ch fill = ( BOOST_USE_FACET(std::ctype<Ch>, getloc()) ). widen(' ');
     114             : #else
     115             :         Ch fill = ' ';
     116             : #endif
     117           0 :         if(items_.size() == 0)
     118           0 :             items_.assign( nbitems, format_item_t(fill) );
     119             :         else {
     120           0 :             if(nbitems>items_.size())
     121           0 :                 items_.resize(nbitems, format_item_t(fill));
     122           0 :             bound_.resize(0);
     123           0 :             for(std::size_t i=0; i < nbitems; ++i)
     124           0 :                 items_[i].reset(fill); //  strings are resized, instead of reallocated
     125             :         }
     126           0 :         prefix_.resize(0);
     127           0 :     }
     128             : 
     129             :     template< class Ch, class Tr, class Alloc>
     130           0 :     basic_format<Ch,Tr, Alloc>& basic_format<Ch,Tr, Alloc>:: 
     131             :     clear () {
     132             :         // empty the string buffers (except bound arguments)
     133             :         // and make the format object ready for formatting a new set of arguments
     134             : 
     135           0 :         BOOST_ASSERT( bound_.size()==0 || num_args_ == static_cast<int>(bound_.size()) );
     136             : 
     137           0 :         for(unsigned long i=0; i<items_.size(); ++i) {
     138             :             // clear converted strings only if the corresponding argument is not  bound :
     139           0 :             if( bound_.size()==0 || items_[i].argN_<0 || !bound_[ items_[i].argN_ ] )
     140           0 :                 items_[i].res_.resize(0);
     141             :         }
     142           0 :         cur_arg_=0; dumped_=false;
     143             :         // maybe first arg is bound:
     144           0 :         if(bound_.size() != 0) {
     145           0 :             for(; cur_arg_ < num_args_ && bound_[cur_arg_]; ++cur_arg_)
     146             :                 {}
     147             :         }
     148           0 :         return *this;
     149             :     }
     150             : 
     151             :     template< class Ch, class Tr, class Alloc>
     152             :     basic_format<Ch,Tr, Alloc>& basic_format<Ch,Tr, Alloc>:: 
     153             :     clear_binds () {
     154             :         // remove all binds, then clear()
     155             :         bound_.resize(0);
     156             :         clear();
     157             :         return *this;
     158             :     }
     159             : 
     160             :     template< class Ch, class Tr, class Alloc>
     161             :     basic_format<Ch,Tr, Alloc>& basic_format<Ch,Tr, Alloc>:: 
     162             :     clear_bind (int argN) {
     163             :         // remove the bind of ONE argument then clear()
     164             :         if(argN<1 || argN > num_args_ || bound_.size()==0 || !bound_[argN-1] ) {
     165             :             if( exceptions() & io::out_of_range_bit)
     166             :                 boost::throw_exception(io::out_of_range(argN, 1, num_args_+1 ) ); 
     167             :             else return *this;
     168             :         }
     169             :         bound_[argN-1]=false;
     170             :         clear();
     171             :         return *this;
     172             :     }
     173             : 
     174             :     template< class Ch, class Tr, class Alloc>
     175             :     int basic_format<Ch,Tr, Alloc>::
     176             :     bound_args() const {
     177             :         if(bound_.size()==0)
     178             :             return 0;
     179             :         int n=0;
     180             :         for(int i=0; i<num_args_ ; ++i)
     181             :             if(bound_[i])
     182             :                 ++n;
     183             :         return n;
     184             :     }
     185             : 
     186             :     template< class Ch, class Tr, class Alloc>
     187             :     int basic_format<Ch,Tr, Alloc>::
     188             :     fed_args() const {
     189             :         if(bound_.size()==0)
     190             :             return cur_arg_;
     191             :         int n=0;
     192             :         for(int i=0; i<cur_arg_ ; ++i)
     193             :             if(!bound_[i])
     194             :                 ++n;
     195             :         return n;
     196             :     }
     197             : 
     198             :     template< class Ch, class Tr, class Alloc>
     199             :     int basic_format<Ch,Tr, Alloc>::
     200             :     cur_arg() const {
     201             :       return cur_arg_+1; }
     202             : 
     203             :     template< class Ch, class Tr, class Alloc>
     204             :     int basic_format<Ch,Tr, Alloc>::
     205             :     remaining_args() const {
     206             :         if(bound_.size()==0)
     207             :             return num_args_-cur_arg_;
     208             :         int n=0;
     209             :         for(int i=cur_arg_; i<num_args_ ; ++i)
     210             :             if(!bound_[i])
     211             :                 ++n;
     212             :         return n;
     213             :     }
     214             : 
     215             :     template< class Ch, class Tr, class Alloc>
     216             :     typename basic_format<Ch, Tr, Alloc>::string_type 
     217           0 :     basic_format<Ch,Tr, Alloc>:: 
     218             :     str () const {
     219           0 :         if(items_.size()==0)
     220           0 :             return prefix_;
     221           0 :         if( cur_arg_ < num_args_)
     222           0 :             if( exceptions() & io::too_few_args_bit )
     223             :                 // not enough variables supplied
     224           0 :                 boost::throw_exception(io::too_few_args(cur_arg_, num_args_)); 
     225             : 
     226             :         unsigned long i;
     227           0 :         string_type res;
     228           0 :         res.reserve(size());
     229           0 :         res += prefix_;
     230           0 :         for(i=0; i < items_.size(); ++i) {
     231           0 :             const format_item_t& item = items_[i];
     232           0 :             res += item.res_;
     233           0 :             if( item.argN_ == format_item_t::argN_tabulation) { 
     234           0 :                 BOOST_ASSERT( item.pad_scheme_ & format_item_t::tabulation);
     235           0 :                 if( static_cast<size_type>(item.fmtstate_.width_) > res.size() )
     236           0 :                     res.append( static_cast<size_type>(item.fmtstate_.width_) - res.size(),
     237           0 :                                         item.fmtstate_.fill_ );
     238             :             }
     239           0 :             res += item.appendix_;
     240             :         }
     241           0 :         dumped_=true;
     242           0 :         return res;
     243             :     }
     244             :     template< class Ch, class Tr, class Alloc>
     245           0 :     typename std::basic_string<Ch, Tr, Alloc>::size_type  basic_format<Ch,Tr, Alloc>:: 
     246             :     size () const {
     247             : #ifdef BOOST_MSVC
     248             :        // If std::min<unsigned> or std::max<unsigned> are already instantiated
     249             :        // at this point then we get a blizzard of warning messages when we call
     250             :        // those templates with std::size_t as arguments.  Weird and very annoyning...
     251             : #pragma warning(push)
     252             : #pragma warning(disable:4267)
     253             : #endif
     254             :         BOOST_USING_STD_MAX();
     255           0 :         size_type sz = prefix_.size();
     256             :         unsigned long i;
     257           0 :         for(i=0; i < items_.size(); ++i) {
     258           0 :             const format_item_t& item = items_[i];
     259           0 :             sz += item.res_.size();
     260           0 :             if( item.argN_ == format_item_t::argN_tabulation)
     261           0 :                 sz = max BOOST_PREVENT_MACRO_SUBSTITUTION (sz,
     262           0 :                                         static_cast<size_type>(item.fmtstate_.width_) );
     263           0 :             sz += item.appendix_.size();
     264             :         }
     265           0 :         return sz;
     266             : #ifdef BOOST_MSVC
     267             : #pragma warning(pop)
     268             : #endif
     269             :     }
     270             : 
     271             : namespace io {
     272             : namespace detail {
     273             : 
     274             :     template<class Ch, class Tr, class Alloc, class T> 
     275             :     basic_format<Ch, Tr, Alloc>&  
     276             :     bind_arg_body (basic_format<Ch, Tr, Alloc>& self, int argN, const T& val) {
     277             :         // bind one argument to a fixed value
     278             :         // this is persistent over clear() calls, thus also over str() and <<
     279             :         if(self.dumped_) 
     280             :             self.clear(); // needed because we will modify cur_arg_
     281             :         if(argN<1 || argN > self.num_args_) {
     282             :             if( self.exceptions() & io::out_of_range_bit )
     283             :                 boost::throw_exception(io::out_of_range(argN, 1, self.num_args_+1 ) );
     284             :             else return self;
     285             :         }
     286             :         if(self.bound_.size()==0) 
     287             :             self.bound_.assign(self.num_args_,false);
     288             :         else 
     289             :             BOOST_ASSERT( self.num_args_ == static_cast<signed int>(self.bound_.size()) );
     290             :         int o_cur_arg = self.cur_arg_;
     291             :         self.cur_arg_ = argN-1; // arrays begin at 0
     292             : 
     293             :         self.bound_[self.cur_arg_]=false; // if already set, we unset and re-sets..
     294             :         self.operator%(val); // put val at the right place, because cur_arg is set
     295             :     
     296             : 
     297             :         // Now re-position cur_arg before leaving :
     298             :         self.cur_arg_ = o_cur_arg; 
     299             :         self.bound_[argN-1]=true;
     300             :         if(self.cur_arg_ == argN-1 ) {
     301             :             // hum, now this arg is bound, so move to next free arg
     302             :             while(self.cur_arg_ < self.num_args_ && self.bound_[self.cur_arg_])   
     303             :                 ++self.cur_arg_;
     304             :         }
     305             :         // In any case, we either have all args, or are on an unbound arg :
     306             :         BOOST_ASSERT( self.cur_arg_ >= self.num_args_ || ! self.bound_[self.cur_arg_]);
     307             :         return self;
     308             :     }
     309             : 
     310             :     template<class Ch, class Tr, class Alloc, class T> basic_format<Ch, Tr, Alloc>&
     311             :     modify_item_body (basic_format<Ch, Tr, Alloc>& self, int itemN, T manipulator) {
     312             :         // applies a manipulator to the format_item describing a given directive.
     313             :         // this is a permanent change, clear or reset won't cancel that.
     314             :         if(itemN<1 || itemN > static_cast<signed int>(self.items_.size() )) {
     315             :             if( self.exceptions() & io::out_of_range_bit ) 
     316             :                 boost::throw_exception(io::out_of_range(itemN, 1, static_cast<int>(self.items_.size()) ));
     317             :             else return self;
     318             :         }
     319             :         self.items_[itemN-1].fmtstate_. template apply_manip<T> ( manipulator );
     320             :         return self;
     321             :     }
     322             : 
     323             : } // namespace detail
     324             : } // namespace io
     325             : } // namespace boost
     326             : 
     327             : 
     328             : 
     329             : #endif  // BOOST_FORMAT_IMPLEMENTATION_HPP

Generated by: LCOV version 1.14