Index: format_implementation.hpp =================================================================== --- format_implementation.hpp (revision 65446) +++ format_implementation.hpp (working copy) @@ -235,6 +235,9 @@ if( static_cast(item.fmtstate_.width_) > res.size() ) res.append( static_cast(item.fmtstate_.width_) - res.size(), item.fmtstate_.fill_ ); + }else if( item.argN_ == format_item_t::argN_repeat) { // added by Francis (Grizzly) Smit // + BOOST_ASSERT( item.pad_scheme_ & format_item_t::repeat); + res.append( static_cast(item.fmtstate_.width_), item.fmtstate_.fill_ ); } res += item.appendix_; } Index: feed_args.hpp =================================================================== --- feed_args.hpp (revision 65446) +++ feed_args.hpp (working copy) @@ -116,8 +116,76 @@ } #endif #endif // -msvc workaround + + // Added by Francis (Grizzly) Smit // + template< class T> + inline long long cast_to_long_long(T t) + { // should never be called // + return 0; + } + inline long long cast_to_long_long(char v) + { + return static_cast(v); + } + inline long long cast_to_long_long(signed char v) + { + return static_cast(v); + } + + inline long long cast_to_long_long(short v) + { + return static_cast(v); + } + + inline long long cast_to_long_long(int v) + { + return static_cast(v); + } + + inline long long cast_to_long_long(long v) + { + return static_cast(v); + } + + inline long long cast_to_long_long(long long v) + { + return static_cast(v); + } + + // Added by Francis (Grizzly) Smit // + template< class T> + inline unsigned long long cast_to_unsigned_long_long(T t) + { // should never be called // + return 0; + } + + inline unsigned long long cast_to_unsigned_long_long(unsigned char v) + { + return static_cast(v); + } + + inline unsigned long long cast_to_unsigned_long_long(unsigned short v) + { + return static_cast(v); + } + + inline unsigned long long cast_to_unsigned_long_long(unsigned int v) + { + return static_cast(v); + } + + inline unsigned long long cast_to_unsigned_long_long(unsigned long v) + { + return static_cast(v); + } + + inline unsigned long long cast_to_unsigned_long_long(unsigned long long v) + { + return static_cast(v); + } + template< class Ch, class Tr, class Alloc, class T> void put( T x, const format_item& specs, @@ -137,10 +205,66 @@ typedef typename basic_format::string_type string_type; typedef typename basic_format::format_item_t format_item_t; + typedef typename basic_format::format_item_t::base_args base_args_t; typedef typename string_type::size_type size_type; basic_oaltstringstream oss( &buf); specs.fmtstate_.apply_on(oss, loc_p); + + //* + unsigned char base = static_cast(specs.base); + if(base) + { + bool uppercase = (specs.fmtstate_.flags_ & std::ios_base::uppercase); + if((2 <= base) && (base <= 36)) + { + if((typeid(T) == typeid(char)) || (typeid(T) == typeid(short)) || + (typeid(T) == typeid(int)) || (typeid(T) == typeid(long)) || + (typeid(T) == typeid(long long)) || (typeid(T) == typeid(signed char))) + { + string_type buffer; + long long l = cast_to_long_long(x); + int sign = (l < 0)?-1:1; + char digit; + if(sign == -1) + { + l = -l; + } + for(; l > 0; l /= base) + { + digit = l % base; + digit += (digit < 10)?('0'):((uppercase)?('A' - 10):('a' - 10)); + buffer = digit + buffer; + } + if(sign == -1) + { + buffer = '-' + buffer; + } + format_item specs1 = specs; + specs1.base = static_cast(0); + put(buffer, specs1, res, buf, loc_p); + return; + }else if((typeid(T) == typeid(unsigned char)) || + (typeid(T) == typeid(unsigned short)) || (typeid(T) == typeid(unsigned int)) || + (typeid(T) == typeid(unsigned long)) || (typeid(T) == typeid(unsigned long long))) + { + string_type buffer; + unsigned long long l = cast_to_unsigned_long_long(x); + char digit; + for(; l > 0; l /= base) + { + digit = l % base; + digit += (digit < 10)?('0'):((uppercase)?('A' - 10):('a' - 10)); + buffer += digit + buffer; + } + format_item specs1 = specs; + specs1.base = static_cast(0); + put(buffer, specs1, res, buf, loc_p); + return; + } + } + } + //*/ // the stream format state can be modified by manipulators in the argument : put_head( oss, x ); Index: internals.hpp =================================================================== --- internals.hpp (revision 65446) +++ internals.hpp (working copy) @@ -63,19 +63,26 @@ template struct format_item { - enum pad_values { zeropad = 1, spacepad =2, centered=4, tabulation = 8 }; + enum pad_values { zeropad = 1, spacepad =2, centered=4, tabulation = 8, repeat = 16 }; // 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. + // repeat added by Francis (Grizzly) Smit // 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) + argN_ignored = -3, // ignored directive. (no argument read) + argN_repeat = -4 // repeat. (no argument read) // added by Francis (Grizzly) Smit // }; + // added by Francis (Grizzly) Smit // + enum base_args { base_io = 63, repeat_chars = 1 << 7 }; + // 2 ... 36 base number // + // 128 ... 255 xor'd with repeat_chars gives a value of from 0 ... 127 // typedef BOOST_IO_STD basic_ios basic_ios; typedef detail::stream_format_state stream_format_state; typedef ::std::basic_string string_type; - format_item(Ch fill) :argN_(argN_no_posit), fmtstate_(fill), + format_item(Ch fill) :argN_(argN_no_posit), fmtstate_(fill), base(static_cast(0)), + // base added by Francis (Grizzly) Smit // truncate_(max_streamsize()), pad_scheme_(0) {} void reset(Ch fill); void compute_states(); // sets states according to truncate and pad_scheme. @@ -92,8 +99,20 @@ stream_format_state fmtstate_;// set by parsing, is only affected by modify_item + base_args base; // added by Francis (Grizzly) Smit // + 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 + format_item& operator=(const format_item& fi) // added by Francis (Grizzly) Smit // + { + argN_ = fi.argN_; + res_ = fi.res_; + appendix_ = fi.appendix_; + fmtstate_ = fi.fmtstate_; + base = fi.base; + truncate_ = fi.truncate_; + pad_scheme_ = fi.pad_scheme_; + } }; Index: parsing.hpp =================================================================== --- parsing.hpp (revision 65446) +++ parsing.hpp (working copy) @@ -126,6 +126,7 @@ std::size_t offset, unsigned char exceptions) { typedef typename basic_format::format_item_t format_item_t; + typedef typename basic_format::format_item_t::base_args base_args; fpar->argN_ = format_item_t::argN_no_posit; // if no positional-directive bool precision_set = false; @@ -265,6 +266,50 @@ return true; } switch ( wrap_narrow(fac, *start, 0) ) { + case 'B': // added by Francis (Grizzly) Smit // + fpar->fmtstate_.flags_ |= std::ios_base::boolalpha; + break; + case 'b': // added by Francis (Grizzly) Smit // + if(wrap_narrow(fac, *(start + 1), 0) == '(') + { + start += 2; + if(wrap_narrow(fac, *start, 0) == '-') + { + fpar->fmtstate_.flags_ &= ~std::ios_base::uppercase; + ++start; + }else{ + if(wrap_narrow(fac, *start, 0) == '+') ++start; + fpar->fmtstate_.flags_ |= std::ios_base::uppercase; + } + unsigned char base; + start = str2int(start, last, base, fac); + if((2 <= base) && (base <= 36)) + { + fpar->base = static_cast(base); + }else{ + maybe_throw_exception(exceptions, start-start0+offset, fstring_size); + } + if(wrap_narrow(fac, *start, 0) != ')') + maybe_throw_exception(exceptions, start-start0+offset, fstring_size); + }else{ + fpar->base = static_cast(2); + } + break; + case 'r': // added by Francis (Grizzly) Smit // + fpar->fmtstate_.fill_ = const_or_not(fac).widen( ' '); + fpar->pad_scheme_ |= format_item_t::repeat; + fpar->argN_ = format_item_t::argN_repeat; + break; + case 'R': // added by Francis (Grizzly) Smit // + ++start; + if( start >= last) + maybe_throw_exception(exceptions, start-start0+offset, fstring_size); + else + fpar->fmtstate_.fill_ = *start; + fpar->pad_scheme_ |= format_item_t::repeat; + fpar->argN_ = format_item_t::argN_repeat; + break; + case 'X': fpar->fmtstate_.flags_ |= std::ios_base::uppercase; case 'p': // pointer => set hex. @@ -460,6 +505,7 @@ if(argN ==format_item_t::argN_no_posit) ordered_args=false; else if(argN == format_item_t::argN_tabulation) special_things=true; + else if(argN == format_item_t::argN_repeat) special_things=true; // added by Francis (Grizzly) Smit // else if(argN > max_argN) max_argN = argN; ++num_items; ++cur_item;