replace tabs

git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@439 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
syntheticpp 2006-01-06 09:36:12 +00:00
parent 81aa37aa37
commit e647b7ac3e

View file

@ -26,7 +26,7 @@
#include <locale> #include <locale>
// long is 32bit on 64bit Windows! // long is 32 bit on 64-bit Windows!
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
#define LOKI_SIGNED_LONG intptr_t #define LOKI_SIGNED_LONG intptr_t
@ -42,500 +42,500 @@
namespace Loki namespace Loki
{ {
// Crude writing method: writes straight to the file, unbuffered // Crude writing method: writes straight to the file, unbuffered
// Must be combined with a buffer to work properly (and efficiently) // Must be combined with a buffer to work properly (and efficiently)
void write(std::FILE* f, const char* from, const char* to) { void write(std::FILE* f, const char* from, const char* to) {
assert(from <= to); assert(from <= to);
fwrite(from, 1, to - from, f); fwrite(from, 1, to - from, f);
} }
// Write to a string // Write to a string
void write(std::string& s, const char* from, const char* to) { void write(std::string& s, const char* from, const char* to) {
assert(from <= to); assert(from <= to);
s.append(from, to); s.append(from, to);
} }
// Write to a fixed-size buffer // Write to a fixed-size buffer
template <class Char> template <class Char>
void write(std::pair<Char*, std::size_t>& s, const Char* from, const Char* to) { void write(std::pair<Char*, std::size_t>& s, const Char* from, const Char* to) {
assert(from <= to); assert(from <= to);
if (from + s.second > to) throw std::overflow_error(""); if (from + s.second > to) throw std::overflow_error("");
s.first = copy(from, to, s.first); s.first = copy(from, to, s.first);
s.second -= to - from; s.second -= to - from;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// PrintfState class template // PrintfState class template
// Holds the formatting state, and implements operator() to format stuff // Holds the formatting state, and implements operator() to format stuff
// Todo: make sure errors are handled properly // Todo: make sure errors are handled properly
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template <class Device, class Char> template <class Device, class Char>
struct PrintfState { struct PrintfState {
PrintfState(Device dev, const Char * format) PrintfState(Device dev, const Char * format)
: device_(dev) : device_(dev)
, format_(format) , format_(format)
, result_(0) { , result_(0) {
Advance(); Advance();
} }
~PrintfState() { ~PrintfState() {
} }
#define LOKI_PRINTF_STATE_FORWARD(type) \ #define LOKI_PRINTF_STATE_FORWARD(type) \
PrintfState& operator()(type par) {\ PrintfState& operator()(type par) {\
return (*this)(static_cast< LOKI_UNSIGNED_LONG >(par)); \ return (*this)(static_cast< LOKI_UNSIGNED_LONG >(par)); \
} }
LOKI_PRINTF_STATE_FORWARD(bool) LOKI_PRINTF_STATE_FORWARD(bool)
LOKI_PRINTF_STATE_FORWARD(char) LOKI_PRINTF_STATE_FORWARD(char)
LOKI_PRINTF_STATE_FORWARD(signed char) LOKI_PRINTF_STATE_FORWARD(signed char)
LOKI_PRINTF_STATE_FORWARD(unsigned char) LOKI_PRINTF_STATE_FORWARD(unsigned char)
LOKI_PRINTF_STATE_FORWARD(signed short) LOKI_PRINTF_STATE_FORWARD(signed short)
LOKI_PRINTF_STATE_FORWARD(unsigned short) LOKI_PRINTF_STATE_FORWARD(unsigned short)
LOKI_PRINTF_STATE_FORWARD(signed int) LOKI_PRINTF_STATE_FORWARD(signed int)
#if !(defined(_WIN32) || defined(_WIN64)) #if !(defined(_WIN32) || defined(_WIN64))
LOKI_PRINTF_STATE_FORWARD(unsigned int) LOKI_PRINTF_STATE_FORWARD(unsigned int)
#endif #endif
LOKI_PRINTF_STATE_FORWARD(signed long) LOKI_PRINTF_STATE_FORWARD(signed long)
// Print (or gobble in case of the "*" specifier) an int // Print (or gobble in case of the "*" specifier) an int
PrintfState& operator()(LOKI_UNSIGNED_LONG i) { PrintfState& operator()(LOKI_UNSIGNED_LONG i) {
if (result_ == -1) return *this; // don't even bother if (result_ == -1) return *this; // don't even bother
// % [flags] [width] [.prec] [modifier] type_char // % [flags] [width] [.prec] [modifier] type_char
// Fetch the flags // Fetch the flags
ReadFlags(); ReadFlags();
if (*format_ == '*') { if (*format_ == '*') {
// read the width and get out // read the width and get out
SetWidth(static_cast<size_t>(i)); SetWidth(static_cast<size_t>(i));
++format_; ++format_;
return *this; return *this;
} }
ReadWidth(); ReadWidth();
// precision // precision
if (*format_ == '.') { if (*format_ == '.') {
// deal with precision // deal with precision
if (format_[1] == '*') { if (format_[1] == '*') {
// read the precision and get out // read the precision and get out
SetPrec(static_cast<size_t>(i)); SetPrec(static_cast<size_t>(i));
format_ += 2; format_ += 2;
return *this; return *this;
} }
ReadPrecision(); ReadPrecision();
} }
ReadModifiers(); ReadModifiers();
// input size modifier // input size modifier
if (ForceShort()) { if (ForceShort()) {
// short int // short int
const Char c = *format_; const Char c = *format_;
if (c == 'x' || c == 'X' || c == 'u' || c == 'o') { if (c == 'x' || c == 'X' || c == 'u' || c == 'o') {
i = static_cast<LOKI_UNSIGNED_LONG>(static_cast<unsigned short>(i)); i = static_cast<LOKI_UNSIGNED_LONG>(static_cast<unsigned short>(i));
} }
} }
FormatWithCurrentFlags(i); FormatWithCurrentFlags(i);
return *this; return *this;
} }
PrintfState& operator()(double n) { PrintfState& operator()(double n) {
if (result_ == -1) return *this; // don't even bother if (result_ == -1) return *this; // don't even bother
PrintFloatingPoint(n); PrintFloatingPoint(n);
return *this; return *this;
} }
PrintfState& operator()(long double n) { PrintfState& operator()(long double n) {
if (result_ == -1) return *this; // don't even bother if (result_ == -1) return *this; // don't even bother
PrintFloatingPoint(n); PrintFloatingPoint(n);
return *this; return *this;
} }
// Store the number of characters printed so far // Store the number of characters printed so far
PrintfState& operator()(int * pi) { PrintfState& operator()(int * pi) {
return StoreCountHelper(pi); return StoreCountHelper(pi);
} }
// Store the number of characters printed so far // Store the number of characters printed so far
PrintfState& operator()(short * pi) { PrintfState& operator()(short * pi) {
return StoreCountHelper(pi); return StoreCountHelper(pi);
} }
// Store the number of characters printed so far // Store the number of characters printed so far
PrintfState& operator()(long * pi) { PrintfState& operator()(long * pi) {
return StoreCountHelper(pi); return StoreCountHelper(pi);
} }
PrintfState& operator()(const char *const s) { PrintfState& operator()(const char *const s) {
if (result_ == -1) return *this; if (result_ == -1) return *this;
ReadLeaders(); ReadLeaders();
const char fmt = *format_; const char fmt = *format_;
if (fmt == 'p') { if (fmt == 'p') {
FormatWithCurrentFlags(reinterpret_cast<LOKI_UNSIGNED_LONG>(s)); FormatWithCurrentFlags(reinterpret_cast<LOKI_UNSIGNED_LONG>(s));
return *this; return *this;
} }
if (fmt != 's') { if (fmt != 's') {
result_ = -1; result_ = -1;
return *this; return *this;
} }
const size_t len = std::min(strlen(s), prec_); const size_t len = std::min(strlen(s), prec_);
if (width_ > len) { if (width_ > len) {
if (LeftJustify()) { if (LeftJustify()) {
Write(s, s + len); Write(s, s + len);
Fill(' ', width_ - len); Fill(' ', width_ - len);
} else { } else {
Fill(' ', width_ - len); Fill(' ', width_ - len);
Write(s, s + len); Write(s, s + len);
} }
} else { } else {
Write(s, s + len); Write(s, s + len);
} }
Next(); Next();
return *this; return *this;
} }
PrintfState& operator()(const void *const p) { PrintfState& operator()(const void *const p) {
return (*this)(reinterpret_cast<LOKI_UNSIGNED_LONG>(p)); return (*this)(reinterpret_cast<LOKI_UNSIGNED_LONG>(p));
} }
// read the result // read the result
operator int() const { operator int() const {
return result_; return result_;
} }
private: private:
PrintfState& operator=(const PrintfState&); PrintfState& operator=(const PrintfState&);
template <typename T> template <typename T>
PrintfState& StoreCountHelper(T *const pi) { PrintfState& StoreCountHelper(T *const pi) {
if (result_ == -1) return *this; // don't even bother if (result_ == -1) return *this; // don't even bother
ReadLeaders(); ReadLeaders();
const char fmt = *format_; const char fmt = *format_;
if (fmt == 'p') { // pointer if (fmt == 'p') { // pointer
FormatWithCurrentFlags(reinterpret_cast<LOKI_UNSIGNED_LONG>(pi)); FormatWithCurrentFlags(reinterpret_cast<LOKI_UNSIGNED_LONG>(pi));
return *this; return *this;
} }
if (fmt != 'n') { if (fmt != 'n') {
result_ = -1; result_ = -1;
return *this; return *this;
} }
assert(pi != 0); assert(pi != 0);
*pi = result_; *pi = result_;
Next(); Next();
return *this; return *this;
} }
void FormatWithCurrentFlags(const LOKI_UNSIGNED_LONG i) { void FormatWithCurrentFlags(const LOKI_UNSIGNED_LONG i) {
// look at the format character // look at the format character
Char formatChar = *format_; Char formatChar = *format_;
bool isSigned = formatChar == 'd' || formatChar == 'i'; bool isSigned = formatChar == 'd' || formatChar == 'i';
if (formatChar == 'p') { if (formatChar == 'p') {
formatChar = 'x'; // pointers go to hex formatChar = 'x'; // pointers go to hex
SetAlternateForm(); // printed with '0x' in front SetAlternateForm(); // printed with '0x' in front
isSigned = true; // that's what gcc does isSigned = true; // that's what gcc does
} }
if (!strchr("cdiuoxX", formatChar)) { if (!strchr("cdiuoxX", formatChar)) {
result_ = -1; result_ = -1;
return; return;
} }
Char buf[ Char buf[
sizeof(LOKI_UNSIGNED_LONG) * 3 // digits sizeof(LOKI_UNSIGNED_LONG) * 3 // digits
+ 1 // sign or ' ' + 1 // sign or ' '
+ 2 // 0x or 0X + 2 // 0x or 0X
+ 1]; // terminating zero + 1]; // terminating zero
const Char *const bufEnd = buf + (sizeof(buf) / sizeof(Char)); const Char *const bufEnd = buf + (sizeof(buf) / sizeof(Char));
Char * bufLast = buf + (sizeof(buf) / sizeof(Char) - 1); Char * bufLast = buf + (sizeof(buf) / sizeof(Char) - 1);
Char signChar = 0; Char signChar = 0;
unsigned int base = 10; unsigned int base = 10;
if (formatChar == 'c') { if (formatChar == 'c') {
// Format only one character // Format only one character
// The 'fill with zeros' flag is ignored // The 'fill with zeros' flag is ignored
ResetFillZeros(); ResetFillZeros();
*bufLast = static_cast<char>(i); *bufLast = static_cast<char>(i);
} else { } else {
// TODO: inefficient code, refactor // TODO: inefficient code, refactor
const bool negative = isSigned && static_cast<LOKI_SIGNED_LONG>(i) < 0; const bool negative = isSigned && static_cast<LOKI_SIGNED_LONG>(i) < 0;
if (formatChar == 'o') base = 8; if (formatChar == 'o') base = 8;
else if (formatChar == 'x' || formatChar == 'X') base = 16; else if (formatChar == 'x' || formatChar == 'X') base = 16;
bufLast = isSigned bufLast = isSigned
? RenderWithoutSign(static_cast<LOKI_SIGNED_LONG>(i), bufLast, base, ? RenderWithoutSign(static_cast<LOKI_SIGNED_LONG>(i), bufLast, base,
formatChar == 'X') formatChar == 'X')
: RenderWithoutSign(i, bufLast, base, : RenderWithoutSign(i, bufLast, base,
formatChar == 'X'); formatChar == 'X');
// Add the sign // Add the sign
if (isSigned) { if (isSigned) {
negative ? signChar = '-' negative ? signChar = '-'
: ShowSignAlways() ? signChar = '+' : ShowSignAlways() ? signChar = '+'
: Blank() ? signChar = ' ' : Blank() ? signChar = ' '
: 0; : 0;
} }
} }
// precision // precision
size_t size_t
countDigits = bufEnd - bufLast, countDigits = bufEnd - bufLast,
countZeros = prec_ != size_t(-1) && countDigits < prec_ && countZeros = prec_ != size_t(-1) && countDigits < prec_ &&
formatChar != 'c' formatChar != 'c'
? prec_ - countDigits ? prec_ - countDigits
: 0, : 0,
countBase = base != 10 && AlternateForm() && i != 0 countBase = base != 10 && AlternateForm() && i != 0
? (base == 16 ? 2 : countZeros > 0 ? 0 : 1) ? (base == 16 ? 2 : countZeros > 0 ? 0 : 1)
: 0, : 0,
countSign = (signChar != 0), countSign = (signChar != 0),
totalPrintable = countDigits + countZeros + countBase + countSign; totalPrintable = countDigits + countZeros + countBase + countSign;
size_t countPadLeft = 0, countPadRight = 0; size_t countPadLeft = 0, countPadRight = 0;
if (width_ > totalPrintable) { if (width_ > totalPrintable) {
if (LeftJustify()) { if (LeftJustify()) {
countPadRight = width_ - totalPrintable; countPadRight = width_ - totalPrintable;
countPadLeft = 0; countPadLeft = 0;
} else { } else {
countPadLeft = width_ - totalPrintable; countPadLeft = width_ - totalPrintable;
countPadRight = 0; countPadRight = 0;
} }
} }
if (FillZeros() && prec_ == size_t(-1)) { if (FillZeros() && prec_ == size_t(-1)) {
// pad with zeros and no precision - transfer padding to precision // pad with zeros and no precision - transfer padding to precision
countZeros = countPadLeft; countZeros = countPadLeft;
countPadLeft = 0; countPadLeft = 0;
} }
// ok, all computed, ready to print to device // ok, all computed, ready to print to device
Fill(' ', countPadLeft); Fill(' ', countPadLeft);
if (signChar != 0) Write(&signChar, &signChar + 1); if (signChar != 0) Write(&signChar, &signChar + 1);
if (countBase > 0) Fill('0', 1); if (countBase > 0) Fill('0', 1);
if (countBase == 2) Fill(formatChar, 1); if (countBase == 2) Fill(formatChar, 1);
Fill('0', countZeros); Fill('0', countZeros);
Write(bufLast, bufEnd); Write(bufLast, bufEnd);
Fill(' ', countPadRight); Fill(' ', countPadRight);
// done, advance // done, advance
Next(); Next();
} }
void Write(const Char* b, const Char* e) { void Write(const Char* b, const Char* e) {
if (result_ < 0) return; if (result_ < 0) return;
const LOKI_SIGNED_LONG x = e - b; const LOKI_SIGNED_LONG x = e - b;
write(device_, b, e); write(device_, b, e);
result_ += x; result_ += x;
} }
template <class Double> template <class Double>
void PrintFloatingPoint(Double n) { void PrintFloatingPoint(Double n) {
const Char *const fmt = format_ - 1; const Char *const fmt = format_ - 1;
assert(*fmt == '%'); assert(*fmt == '%');
// enforce format string validity // enforce format string validity
ReadLeaders(); ReadLeaders();
// enforce format spec // enforce format spec
if (!strchr("eEfgG", *format_)) { if (!strchr("eEfgG", *format_)) {
result_ = -1; result_ = -1;
return; return;
} }
// format char validated, copy it to a temp and use legacy sprintf // format char validated, copy it to a temp and use legacy sprintf
++format_; ++format_;
Char fmtBuf[128], resultBuf[1024]; Char fmtBuf[128], resultBuf[1024];
if (format_ >= fmt + sizeof(fmtBuf) / sizeof(Char)) { if (format_ >= fmt + sizeof(fmtBuf) / sizeof(Char)) {
result_ = -1; result_ = -1;
return; return;
} }
memcpy(fmtBuf, fmt, (format_ - fmt) * sizeof(Char)); memcpy(fmtBuf, fmt, (format_ - fmt) * sizeof(Char));
fmtBuf[format_ - fmt] = 0; fmtBuf[format_ - fmt] = 0;
#ifdef _MSC_VER #ifdef _MSC_VER
const int stored = _snprintf(resultBuf, const int stored = _snprintf(resultBuf,
#else #else
const int stored = snprintf(resultBuf, const int stored = snprintf(resultBuf,
#endif #endif
sizeof(resultBuf) / sizeof(Char), fmtBuf, n); sizeof(resultBuf) / sizeof(Char), fmtBuf, n);
if (stored < 0) { if (stored < 0) {
result_ = -1; result_ = -1;
return; return;
} }
Write(resultBuf, resultBuf + strlen(resultBuf)); Write(resultBuf, resultBuf + strlen(resultBuf));
Advance(); // output stuff to the next format directive Advance(); // output stuff to the next format directive
} }
void Fill(const Char c, size_t n) { void Fill(const Char c, size_t n) {
for (; n > 0; --n) { for (; n > 0; --n) {
Write(&c, &c + 1); Write(&c, &c + 1);
} }
} }
Char* RenderWithoutSign(LOKI_UNSIGNED_LONG n, char* bufLast, Char* RenderWithoutSign(LOKI_UNSIGNED_LONG n, char* bufLast,
unsigned int base, bool uppercase) { unsigned int base, bool uppercase) {
const Char hex1st = uppercase ? 'A' : 'a'; const Char hex1st = uppercase ? 'A' : 'a';
for (;;) { for (;;) {
const LOKI_UNSIGNED_LONG next = n / base; const LOKI_UNSIGNED_LONG next = n / base;
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(push) #pragma warning(push)
#pragma warning(disable: 4244) #pragma warning(disable: 4244)
#endif #endif
Char c = n - next * base; Char c = n - next * base;
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
#endif #endif
c += (c <= 9) ? '0' : hex1st - 10; c += (c <= 9) ? '0' : hex1st - 10;
*bufLast = c; *bufLast = c;
n = next; n = next;
if (n == 0) break; if (n == 0) break;
--bufLast; --bufLast;
} }
return bufLast; return bufLast;
} }
char* RenderWithoutSign(LOKI_SIGNED_LONG n, char* bufLast, unsigned int base, char* RenderWithoutSign(LOKI_SIGNED_LONG n, char* bufLast, unsigned int base,
bool uppercase) { bool uppercase) {
if (n != LONG_MIN) { if (n != LONG_MIN) {
return RenderWithoutSign(static_cast<LOKI_UNSIGNED_LONG>(n < 0 ? -n : n), return RenderWithoutSign(static_cast<LOKI_UNSIGNED_LONG>(n < 0 ? -n : n),
bufLast, base, uppercase); bufLast, base, uppercase);
} }
// annoying corner case // annoying corner case
char* save = bufLast; char* save = bufLast;
++n; ++n;
bufLast = RenderWithoutSign(static_cast<LOKI_UNSIGNED_LONG>(n), bufLast = RenderWithoutSign(static_cast<LOKI_UNSIGNED_LONG>(n),
bufLast, base, uppercase); bufLast, base, uppercase);
--(*save); --(*save);
return bufLast; return bufLast;
} }
void Next() { void Next() {
++format_; ++format_;
Advance(); Advance();
} }
void Advance() { void Advance() {
ResetAll(); ResetAll();
const Char* begin = format_; const Char* begin = format_;
for (;;) { for (;;) {
if (*format_ == '%') { if (*format_ == '%') {
if (format_[1] != '%') { // It's a format specifier if (format_[1] != '%') { // It's a format specifier
Write(begin, format_); Write(begin, format_);
++format_; ++format_;
break; break;
} }
// It's a "%%" // It's a "%%"
Write(begin, ++format_); Write(begin, ++format_);
begin = ++format_; begin = ++format_;
continue; continue;
} }
if (*format_ == 0) { if (*format_ == 0) {
Write(begin, format_); Write(begin, format_);
break; break;
} }
++format_; ++format_;
} }
} }
void ReadFlags() { void ReadFlags() {
for (;; ++format_) { for (;; ++format_) {
switch (*format_) { switch (*format_) {
case '-': SetLeftJustify(); break; case '-': SetLeftJustify(); break;
case '+': SetShowSignAlways(); break; case '+': SetShowSignAlways(); break;
case ' ': SetBlank(); break; case ' ': SetBlank(); break;
case '#': SetAlternateForm(); break; case '#': SetAlternateForm(); break;
case '0': SetFillZeros(); break; case '0': SetFillZeros(); break;
default: return; default: return;
} }
} }
} }
void ParseDecimalSizeT(size_t& dest) { void ParseDecimalSizeT(size_t& dest) {
if (!std::isdigit(*format_, std::locale())) return; if (!std::isdigit(*format_, std::locale())) return;
size_t r = 0; size_t r = 0;
do { do {
// TODO: inefficient - rewrite // TODO: inefficient - rewrite
r *= 10; r *= 10;
r += *format_ - '0'; r += *format_ - '0';
++format_; ++format_;
} while (std::isdigit(*format_, std::locale())); } while (std::isdigit(*format_, std::locale()));
dest = r; dest = r;
} }
void ReadWidth() { void ReadWidth() {
ParseDecimalSizeT(width_); ParseDecimalSizeT(width_);
} }
void ReadPrecision() { void ReadPrecision() {
assert(*format_ == '.'); assert(*format_ == '.');
++format_; ++format_;
ParseDecimalSizeT(prec_); ParseDecimalSizeT(prec_);
} }
void ReadModifiers() { void ReadModifiers() {
switch (*format_) { switch (*format_) {
case 'h': SetForceShort(); ++format_; break; case 'h': SetForceShort(); ++format_; break;
case 'l': ++format_; break; case 'l': ++format_; break;
// more (C99 and platform-specific modifiers) to come // more (C99 and platform-specific modifiers) to come
} }
} }
void ReadLeaders() { void ReadLeaders() {
ReadFlags(); ReadFlags();
ReadWidth(); ReadWidth();
if (*format_ == '.') ReadPrecision(); if (*format_ == '.') ReadPrecision();
ReadModifiers(); ReadModifiers();
} }
enum { enum {
leftJustify = 1, leftJustify = 1,
showSignAlways = 2, showSignAlways = 2,
blank = 4, blank = 4,
alternateForm = 8, alternateForm = 8,
fillZeros = 16, fillZeros = 16,
forceShort = 32 forceShort = 32
}; };
bool LeftJustify() const { return (flags_ & leftJustify) != 0; } bool LeftJustify() const { return (flags_ & leftJustify) != 0; }
bool ShowSignAlways() const { return (flags_ & showSignAlways) != 0; } bool ShowSignAlways() const { return (flags_ & showSignAlways) != 0; }
void SetWidth(size_t w) { width_ = w; } void SetWidth(size_t w) { width_ = w; }
void SetLeftJustify() { flags_ |= leftJustify; } void SetLeftJustify() { flags_ |= leftJustify; }
void SetShowSignAlways() { flags_ |= showSignAlways; } void SetShowSignAlways() { flags_ |= showSignAlways; }
bool Blank() const { return (flags_ & blank) != 0; } bool Blank() const { return (flags_ & blank) != 0; }
bool AlternateForm() const { return (flags_ & alternateForm) != 0; } bool AlternateForm() const { return (flags_ & alternateForm) != 0; }
bool FillZeros() const { return (flags_ & fillZeros) != 0; } bool FillZeros() const { return (flags_ & fillZeros) != 0; }
bool ForceShort() const { return (flags_ & forceShort) != 0; } bool ForceShort() const { return (flags_ & forceShort) != 0; }
void SetPrec(size_t p) { prec_ = p; } void SetPrec(size_t p) { prec_ = p; }
void SetBlank() { flags_ |= blank; } void SetBlank() { flags_ |= blank; }
void SetAlternateForm() { flags_ |= alternateForm; } void SetAlternateForm() { flags_ |= alternateForm; }
void SetFillZeros() { flags_ |= fillZeros; } void SetFillZeros() { flags_ |= fillZeros; }
void ResetFillZeros() { flags_ &= ~fillZeros; } void ResetFillZeros() { flags_ &= ~fillZeros; }
void SetForceShort() { flags_ |= forceShort; } void SetForceShort() { flags_ |= forceShort; }
void ResetAll() { void ResetAll() {
assert(result_ != EOF); assert(result_ != EOF);
width_ = 0; width_ = 0;
prec_ = size_t(-1); prec_ = size_t(-1);
flags_ = 0; flags_ = 0;
} }
// state // state
Device device_; Device device_;
const Char* format_; const Char* format_;
size_t width_; size_t width_;
size_t prec_; size_t prec_;
unsigned int flags_; unsigned int flags_;
LOKI_SIGNED_LONG result_; LOKI_SIGNED_LONG result_;
}; };
PrintfState<std::FILE*, char> Printf(const char* format) { PrintfState<std::FILE*, char> Printf(const char* format) {
return PrintfState<std::FILE*, char>(stdout, format); return PrintfState<std::FILE*, char>(stdout, format);
} }
PrintfState<std::FILE*, char> FPrintf(FILE* f, const char* format) { PrintfState<std::FILE*, char> FPrintf(FILE* f, const char* format) {
return PrintfState<std::FILE*, char>(f, format); return PrintfState<std::FILE*, char>(f, format);
} }
PrintfState<std::string&, char> SPrintf(std::string& s, const char* format) { PrintfState<std::string&, char> SPrintf(std::string& s, const char* format) {
return PrintfState<std::string&, char>(s, format); return PrintfState<std::string&, char>(s, format);
} }
template <class T, class Char> template <class T, class Char>
PrintfState<T&, Char> XPrintf(T& device, const Char* format) { PrintfState<T&, Char> XPrintf(T& device, const Char* format) {
return PrintfState<T&, Char>(device, format); return PrintfState<T&, Char>(device, format);
} }
template <class Char, std::size_t N> template <class Char, std::size_t N>
PrintfState<std::pair<Char*, std::size_t>, Char> PrintfState<std::pair<Char*, std::size_t>, Char>
BufPrintf(Char (&buf)[N], const Char* format) { BufPrintf(Char (&buf)[N], const Char* format) {
std::pair<Char*, std::size_t> temp(buf, N); std::pair<Char*, std::size_t> temp(buf, N);
return PrintfState<std::pair<Char*, std::size_t>, Char>(temp, format); return PrintfState<std::pair<Char*, std::size_t>, Char>(temp, format);
} }
}// namespace Loki }// namespace Loki