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. 14 inline 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 // 23 enum 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 // 38 class TInfoSinkBase { 39 public: 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 p); 100 void location(int file, int line); 101 void location(const TSourceLoc& loc); 102 void message(TPrefixType p, const TSourceLoc& loc, const char* m); 103 104 private: 105 TPersistString sink; 106 }; 107 108 class TInfoSink { 109 public: 110 TInfoSinkBase info; 111 TInfoSinkBase debug; 112 TInfoSinkBase obj; 113 }; 114 115 #endif // _INFOSINK_INCLUDED_ 116