cprintf_formats.hh revision 2621
111723Sar4jc@virginia.edu/* 211723Sar4jc@virginia.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan 311723Sar4jc@virginia.edu * All rights reserved. 411723Sar4jc@virginia.edu * 511723Sar4jc@virginia.edu * Redistribution and use in source and binary forms, with or without 611723Sar4jc@virginia.edu * modification, are permitted provided that the following conditions are 711723Sar4jc@virginia.edu * met: redistributions of source code must retain the above copyright 811723Sar4jc@virginia.edu * notice, this list of conditions and the following disclaimer; 911723Sar4jc@virginia.edu * redistributions in binary form must reproduce the above copyright 1011723Sar4jc@virginia.edu * notice, this list of conditions and the following disclaimer in the 1111723Sar4jc@virginia.edu * documentation and/or other materials provided with the distribution; 1211723Sar4jc@virginia.edu * neither the name of the copyright holders nor the names of its 1311723Sar4jc@virginia.edu * contributors may be used to endorse or promote products derived from 1411723Sar4jc@virginia.edu * this software without specific prior written permission. 1511723Sar4jc@virginia.edu * 1611723Sar4jc@virginia.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711723Sar4jc@virginia.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811723Sar4jc@virginia.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911723Sar4jc@virginia.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011723Sar4jc@virginia.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111723Sar4jc@virginia.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211723Sar4jc@virginia.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311723Sar4jc@virginia.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411723Sar4jc@virginia.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511723Sar4jc@virginia.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611723Sar4jc@virginia.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711723Sar4jc@virginia.edu */ 2811723Sar4jc@virginia.edu 2911723Sar4jc@virginia.edu#ifndef __CPRINTF_FORMATS_HH__ 3011723Sar4jc@virginia.edu#define __CPRINTF_FORMATS_HH__ 3111723Sar4jc@virginia.edu 3211723Sar4jc@virginia.edu#include <sstream> 3311723Sar4jc@virginia.edu#include <ostream> 3411723Sar4jc@virginia.edu 3511963Sar4jc@virginia.edunamespace cp { 3611723Sar4jc@virginia.edu 3711723Sar4jc@virginia.edustruct Format 3811723Sar4jc@virginia.edu{ 3911723Sar4jc@virginia.edu bool alternate_form; 4011723Sar4jc@virginia.edu bool flush_left; 4111723Sar4jc@virginia.edu bool print_sign; 4211723Sar4jc@virginia.edu bool blank_space; 4311723Sar4jc@virginia.edu bool fill_zero; 4411723Sar4jc@virginia.edu bool uppercase; 4511723Sar4jc@virginia.edu enum { dec, hex, oct } base; 4611723Sar4jc@virginia.edu enum { none, string, integer, character, floating } format; 4711723Sar4jc@virginia.edu enum { best, fixed, scientific } float_format; 4811723Sar4jc@virginia.edu int precision; 4911723Sar4jc@virginia.edu int width; 5011723Sar4jc@virginia.edu 5111723Sar4jc@virginia.edu Format() { clear(); } 5211723Sar4jc@virginia.edu 5311723Sar4jc@virginia.edu void clear() 5411723Sar4jc@virginia.edu { 5511723Sar4jc@virginia.edu alternate_form = false; 5611723Sar4jc@virginia.edu flush_left = false; 5711723Sar4jc@virginia.edu print_sign = false; 5811723Sar4jc@virginia.edu blank_space = false; 5911723Sar4jc@virginia.edu fill_zero = false; 6011723Sar4jc@virginia.edu uppercase = false; 6111723Sar4jc@virginia.edu base = dec; 6211723Sar4jc@virginia.edu format = none; 6311963Sar4jc@virginia.edu precision = -1; 6412695Sar4jc@virginia.edu width = 0; 6512695Sar4jc@virginia.edu } 6612695Sar4jc@virginia.edu}; 6712695Sar4jc@virginia.edu 6812695Sar4jc@virginia.edutemplate <typename T> 6912695Sar4jc@virginia.eduinline void 7012695Sar4jc@virginia.edu_format_char(std::ostream &out, const T &data, Format &fmt) 7112695Sar4jc@virginia.edu{ 7212695Sar4jc@virginia.edu using namespace std; 7311723Sar4jc@virginia.edu 7411723Sar4jc@virginia.edu out << data; 7512695Sar4jc@virginia.edu} 7612695Sar4jc@virginia.edu 7712695Sar4jc@virginia.edutemplate <typename T> 7812695Sar4jc@virginia.eduinline void 7912695Sar4jc@virginia.edu_format_integer(std::ostream &out, const T &data, Format &fmt) 8012695Sar4jc@virginia.edu{ 8112695Sar4jc@virginia.edu using namespace std; 8212695Sar4jc@virginia.edu 8312695Sar4jc@virginia.edu switch (fmt.base) { 8412695Sar4jc@virginia.edu case Format::hex: 8512695Sar4jc@virginia.edu out.setf(ios::hex, ios::basefield); 8612695Sar4jc@virginia.edu break; 8712695Sar4jc@virginia.edu 8812695Sar4jc@virginia.edu case Format::oct: 8912695Sar4jc@virginia.edu out.setf(ios::oct, ios::basefield); 9012695Sar4jc@virginia.edu break; 9112695Sar4jc@virginia.edu 9212695Sar4jc@virginia.edu case Format::dec: 9312695Sar4jc@virginia.edu out.setf(ios::dec, ios::basefield); 9412695Sar4jc@virginia.edu break; 9512695Sar4jc@virginia.edu } 9612695Sar4jc@virginia.edu 9711723Sar4jc@virginia.edu if (fmt.alternate_form) { 9813612Sgabeblack@google.com if (!fmt.fill_zero) 9911723Sar4jc@virginia.edu out.setf(ios::showbase); 10011723Sar4jc@virginia.edu else { 10112695Sar4jc@virginia.edu switch (fmt.base) { 10212695Sar4jc@virginia.edu case Format::hex: 10312695Sar4jc@virginia.edu out << "0x"; 10412695Sar4jc@virginia.edu fmt.width -= 2; 10511723Sar4jc@virginia.edu break; 10612695Sar4jc@virginia.edu case Format::oct: 10712695Sar4jc@virginia.edu out << "0"; 10812695Sar4jc@virginia.edu fmt.width -= 1; 10911723Sar4jc@virginia.edu break; 11011723Sar4jc@virginia.edu case Format::dec: 11113612Sgabeblack@google.com break; 11211723Sar4jc@virginia.edu } 11311723Sar4jc@virginia.edu } 11411723Sar4jc@virginia.edu } 11512695Sar4jc@virginia.edu 11612695Sar4jc@virginia.edu if (fmt.fill_zero) 11712695Sar4jc@virginia.edu out.fill('0'); 11812695Sar4jc@virginia.edu 11912695Sar4jc@virginia.edu if (fmt.width > 0) 12012695Sar4jc@virginia.edu out.width(fmt.width); 12112695Sar4jc@virginia.edu 12212695Sar4jc@virginia.edu if (fmt.flush_left && !fmt.fill_zero) 12312695Sar4jc@virginia.edu out.setf(ios::left); 12412695Sar4jc@virginia.edu 12512695Sar4jc@virginia.edu if (fmt.print_sign) 12612695Sar4jc@virginia.edu out.setf(ios::showpos); 12712695Sar4jc@virginia.edu 12812695Sar4jc@virginia.edu if (fmt.uppercase) 12912695Sar4jc@virginia.edu out.setf(ios::uppercase); 13012695Sar4jc@virginia.edu 13112695Sar4jc@virginia.edu out << data; 13212695Sar4jc@virginia.edu} 13311723Sar4jc@virginia.edu 13412695Sar4jc@virginia.edutemplate <typename T> 13512695Sar4jc@virginia.eduinline void 13612695Sar4jc@virginia.edu_format_float(std::ostream &out, const T &data, Format &fmt) 13712695Sar4jc@virginia.edu{ 13812695Sar4jc@virginia.edu using namespace std; 13912695Sar4jc@virginia.edu 14012695Sar4jc@virginia.edu switch (fmt.float_format) { 14112695Sar4jc@virginia.edu case Format::scientific: 14213548Salec.roelke@gmail.com if (fmt.precision != -1) { 14313548Salec.roelke@gmail.com if (fmt.width > 0) 14413548Salec.roelke@gmail.com out.width(fmt.width); 14513548Salec.roelke@gmail.com 14613548Salec.roelke@gmail.com if (fmt.precision == 0) 14713548Salec.roelke@gmail.com fmt.precision = 1; 14811723Sar4jc@virginia.edu else 14912695Sar4jc@virginia.edu out.setf(ios::scientific); 15012695Sar4jc@virginia.edu 15112695Sar4jc@virginia.edu out.precision(fmt.precision); 15212695Sar4jc@virginia.edu } else 15312695Sar4jc@virginia.edu if (fmt.width > 0) 15412695Sar4jc@virginia.edu out.width(fmt.width); 15512695Sar4jc@virginia.edu 15612695Sar4jc@virginia.edu if (fmt.uppercase) 15712695Sar4jc@virginia.edu out.setf(ios::uppercase); 15812695Sar4jc@virginia.edu break; 15912695Sar4jc@virginia.edu 16012695Sar4jc@virginia.edu case Format::fixed: 16112695Sar4jc@virginia.edu if (fmt.precision != -1) { 16211723Sar4jc@virginia.edu if (fmt.width > 0) 16311723Sar4jc@virginia.edu out.width(fmt.width); 16411723Sar4jc@virginia.edu 16511723Sar4jc@virginia.edu out.setf(ios::fixed); 16611723Sar4jc@virginia.edu out.precision(fmt.precision); 16713612Sgabeblack@google.com } else 16811723Sar4jc@virginia.edu if (fmt.width > 0) 16912695Sar4jc@virginia.edu out.width(fmt.width); 17012695Sar4jc@virginia.edu 17112695Sar4jc@virginia.edu break; 17211723Sar4jc@virginia.edu 17312695Sar4jc@virginia.edu default: 17412695Sar4jc@virginia.edu if (fmt.precision != -1) 17511723Sar4jc@virginia.edu out.precision(fmt.precision); 17611723Sar4jc@virginia.edu 17711723Sar4jc@virginia.edu if (fmt.width > 0) 17813612Sgabeblack@google.com out.width(fmt.width); 17911723Sar4jc@virginia.edu 18012695Sar4jc@virginia.edu break; 18112695Sar4jc@virginia.edu } 18212695Sar4jc@virginia.edu 18312695Sar4jc@virginia.edu out << data; 18413548Salec.roelke@gmail.com} 18513548Salec.roelke@gmail.com 18613548Salec.roelke@gmail.comtemplate <typename T> 18713548Salec.roelke@gmail.cominline void 18813548Salec.roelke@gmail.com_format_string(std::ostream &out, const T &data, Format &fmt) 18913548Salec.roelke@gmail.com{ 19013548Salec.roelke@gmail.com using namespace std; 19113548Salec.roelke@gmail.com 19213548Salec.roelke@gmail.com#if defined(__GNUC__) && (__GNUC__ < 3) || 1 19313548Salec.roelke@gmail.com if (fmt.width > 0) { 19411723Sar4jc@virginia.edu std::stringstream foo; 19511723Sar4jc@virginia.edu foo << data; 19611723Sar4jc@virginia.edu int flen = foo.str().size(); 19711723Sar4jc@virginia.edu 19811723Sar4jc@virginia.edu if (fmt.width > flen) { 19911723Sar4jc@virginia.edu char *spaces = new char[fmt.width - flen + 1]; 20011723Sar4jc@virginia.edu memset(spaces, ' ', fmt.width - flen); 20111723Sar4jc@virginia.edu spaces[fmt.width - flen] = 0; 20211723Sar4jc@virginia.edu 20313582Sgabeblack@google.com if (fmt.flush_left) 204 out << foo.str() << spaces; 205 else 206 out << spaces << foo.str(); 207 208 delete [] spaces; 209 } else 210 out << data; 211 } else 212 out << data; 213#else 214 if (fmt.width > 0) 215 out.width(fmt.width); 216 if (fmt.flush_left) 217 out.setf(ios::left); 218 219 out << data; 220#endif 221} 222 223///////////////////////////////////////////////////////////////////////////// 224// 225// The code below controls the actual usage of formats for various types 226// 227 228// 229// character formats 230// 231template <typename T> 232inline void 233format_char(std::ostream &out, const T &data, Format &fmt) 234{ out << "<bad arg type for char format>"; } 235 236inline void 237format_char(std::ostream &out, char data, Format &fmt) 238{ _format_char(out, data, fmt); } 239 240inline void 241format_char(std::ostream &out, unsigned char data, Format &fmt) 242{ _format_char(out, data, fmt); } 243 244inline void 245format_char(std::ostream &out, signed char data, Format &fmt) 246{ _format_char(out, data, fmt); } 247 248inline void 249format_char(std::ostream &out, short data, Format &fmt) 250{ _format_char(out, (char)data, fmt); } 251 252inline void 253format_char(std::ostream &out, unsigned short data, Format &fmt) 254{ _format_char(out, (char)data, fmt); } 255 256inline void 257format_char(std::ostream &out, int data, Format &fmt) 258{ _format_char(out, (char)data, fmt); } 259 260inline void 261format_char(std::ostream &out, unsigned int data, Format &fmt) 262{ _format_char(out, (char)data, fmt); } 263 264inline void 265format_char(std::ostream &out, long data, Format &fmt) 266{ _format_char(out, (char)data, fmt); } 267 268inline void 269format_char(std::ostream &out, unsigned long data, Format &fmt) 270{ _format_char(out, (char)data, fmt); } 271 272inline void 273format_char(std::ostream &out, long long data, Format &fmt) 274{ _format_char(out, (char)data, fmt); } 275 276inline void 277format_char(std::ostream &out, unsigned long long data, Format &fmt) 278{ _format_char(out, (char)data, fmt); } 279 280// 281// integer formats 282// 283template <typename T> 284inline void 285format_integer(std::ostream &out, const T &data, Format &fmt) 286{ _format_integer(out, data, fmt); } 287inline void 288format_integer(std::ostream &out, char data, Format &fmt) 289{ _format_integer(out, data, fmt); } 290inline void 291format_integer(std::ostream &out, unsigned char data, Format &fmt) 292{ _format_integer(out, data, fmt); } 293inline void 294format_integer(std::ostream &out, signed char data, Format &fmt) 295{ _format_integer(out, data, fmt); } 296#if 0 297inline void 298format_integer(std::ostream &out, short data, Format &fmt) 299{ _format_integer(out, data, fmt); } 300inline void 301format_integer(std::ostream &out, unsigned short data, Format &fmt) 302{ _format_integer(out, data, fmt); } 303inline void 304format_integer(std::ostream &out, int data, Format &fmt) 305{ _format_integer(out, data, fmt); } 306inline void 307format_integer(std::ostream &out, unsigned int data, Format &fmt) 308{ _format_integer(out, data, fmt); } 309inline void 310format_integer(std::ostream &out, long data, Format &fmt) 311{ _format_integer(out, data, fmt); } 312inline void 313format_integer(std::ostream &out, unsigned long data, Format &fmt) 314{ _format_integer(out, data, fmt); } 315inline void 316format_integer(std::ostream &out, long long data, Format &fmt) 317{ _format_integer(out, data, fmt); } 318inline void 319format_integer(std::ostream &out, unsigned long long data, Format &fmt) 320{ _format_integer(out, data, fmt); } 321#endif 322 323// 324// floating point formats 325// 326template <typename T> 327inline void 328format_float(std::ostream &out, const T &data, Format &fmt) 329{ out << "<bad arg type for float format>"; } 330 331inline void 332format_float(std::ostream &out, float data, Format &fmt) 333{ _format_float(out, data, fmt); } 334 335inline void 336format_float(std::ostream &out, double data, Format &fmt) 337{ _format_float(out, data, fmt); } 338 339// 340// string formats 341// 342template <typename T> 343inline void 344format_string(std::ostream &out, const T &data, Format &fmt) 345{ _format_string(out, data, fmt); } 346 347inline void 348format_string(std::ostream &out, const std::stringstream &data, Format &fmt) 349{ _format_string(out, data.str(), fmt); } 350 351} // namespace cp 352 353#endif // __CPRINTF_FORMATS_HH__ 354