1// 2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 3// Use of this source code is governed by a BSD-style license that can be 4// found in the LICENSE file. 5// 6 7#ifndef _INFOSINK_INCLUDED_ 8#define _INFOSINK_INCLUDED_ 9 10#include <math.h> 11#include "compiler/Common.h" 12 13// Returns the fractional part of the given floating-point number. 14inline float fractionalPart(float f) { 15 float intPart = 0.0f; 16 return modff(f, &intPart); 17} 18 19// 20// TPrefixType is used to centralize how info log messages start. 21// See below. 22// 23enum TPrefixType { 24 EPrefixNone, 25 EPrefixWarning, 26 EPrefixError, 27 EPrefixInternalError, 28 EPrefixUnimplemented, 29 EPrefixNote 30}; 31 32// 33// Encapsulate info logs for all objects that have them. 34// 35// The methods are a general set of tools for getting a variety of 36// messages and types inserted into the log. 37// 38class TInfoSinkBase { 39public: 40 TInfoSinkBase() {} 41 42 template <typename T> 43 TInfoSinkBase& operator<<(const T& t) { 44 TPersistStringStream stream; 45 stream << t; 46 sink.append(stream.str()); 47 return *this; 48 } 49 // Override << operator for specific types. It is faster to append strings 50 // and characters directly to the sink. 51 TInfoSinkBase& operator<<(char c) { 52 sink.append(1, c); 53 return *this; 54 } 55 TInfoSinkBase& operator<<(const char* str) { 56 sink.append(str); 57 return *this; 58 } 59 TInfoSinkBase& operator<<(const TPersistString& str) { 60 sink.append(str); 61 return *this; 62 } 63 TInfoSinkBase& operator<<(const TString& str) { 64 sink.append(str.c_str()); 65 return *this; 66 } 67 // Make sure floats are written with correct precision. 68 TInfoSinkBase& operator<<(float f) { 69 // Make sure that at least one decimal point is written. If a number 70 // does not have a fractional part, the default precision format does 71 // not write the decimal portion which gets interpreted as integer by 72 // the compiler. 73 TPersistStringStream stream; 74 if (fractionalPart(f) == 0.0f) { 75 stream.precision(1); 76 stream << std::showpoint << std::fixed << f; 77 } else { 78 stream.unsetf(std::ios::fixed); 79 stream.unsetf(std::ios::scientific); 80 stream.precision(8); 81 stream << f; 82 } 83 sink.append(stream.str()); 84 return *this; 85 } 86 // Write boolean values as their names instead of integral value. 87 TInfoSinkBase& operator<<(bool b) { 88 const char* str = b ? "true" : "false"; 89 sink.append(str); 90 return *this; 91 } 92 93 void erase() { sink.clear(); } 94 int size() { return static_cast<int>(sink.size()); } 95 96 const TPersistString& str() const { return sink; } 97 const char* c_str() const { return sink.c_str(); } 98 99 void prefix(TPrefixType message); 100 void location(TSourceLoc loc); 101 void message(TPrefixType message, const char* s); 102 void message(TPrefixType message, const char* s, TSourceLoc loc); 103 104private: 105 TPersistString sink; 106}; 107 108class TInfoSink { 109public: 110 TInfoSinkBase info; 111 TInfoSinkBase debug; 112 TInfoSinkBase obj; 113}; 114 115#endif // _INFOSINK_INCLUDED_ 116